Should repeated and map proto fields by writable by default?
negz opened this issue · comments
I'm new to Starlark1. I'm attempting to write a little Go function that essentially defers answering a gRPC request to a Starlark script. Like this:
v1beta1 = proto.file("v1beta1/run_function.proto)
def main(req):
# Do some stuff with req, which is a v1beta1.RunFunctionRequest message...
return v1beta1.RunFunctionResponse(
results=[v1beta1.Result(
severity=v1beta1.Severity.SEVERITY_NORMAL,
message="Hi from Starlark!"
)]
)
My first intuition was to try doing something like this2:
rsp = v1beta1.RunFunctionResponse()
rsp.results.append(v1beta1.Result(message="Hi!"))
However, I was surprised to be told that rsp.results
was a frozen repeated field. Looking at proto.go
I realized this was the default value, so I tried this:
rsp = v1beta1.RunFunctionResponse()
rsp.results = []
rsp.results.append(v1beta1.Result(message="Hi!"))
Unfortunately the field is still frozen. I'm guessing because the Has()
method of protoreflect.Message
only considers a message to have a repeated field (and thus I guess by extension map field) if it's non-empty.
With all that said, I'm curious:
- What's the reasoning behind default message field values being frozen?
- Would you be open to a PR that made them writable?
I'm not sure it's possible to make them writable/unfrozen by default but I wanted to ask before I dug in too deeply.
Footnotes
-
I guess technically I used it in a bunch of
BUILD
files a decade ago, but I've forgotten all about that. 🙂 ↩ -
I added the
append
method in https://github.com/google/starlark-go/pull/511. ↩
I think part of what I'm looking for, especially for maps (in the context of #511), is an API like this:
if msg.map_field == None:
msg.map_field = {}
msg.map_field["key"] = "value"
This is similar to what was mentioned in stripe/skycfg#23 (comment). I can use not proto.has
instead of == None
easily enough, but I'll still end up with a frozen field because the msg.map_field = {}
doesn't effectively replace the default value with a usable dict/MapField.