I've recently encountered all sorts of wrappers in Google's protobuf
package. I'm struggling to imagine the use case. Can anyone shed the light: what problem were these intended to solve?
Here's one of the documentation links: https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/string-value (it says nothing about what can this be used for).
One thing that will be different in behavior between this, and simple string
type is that this field will be written less efficiently (a couple extra bytes, plus a redundant memory allocation). For other wrappers, the story is even worse, since the repeated
variants of those fields will be written inefficiently (official Google's Protobuf serializer doesn't support packed
encoding for non-numeric types).
Neither seems to be desirable. So, what's this all about?
There's a few reasons, mostly to do with where these are used - see struct.proto.
StringValue
can be null, string
often can't be in a language interfacing with protobufs. e.g. in Go strings are always set; the "zero value" for a string is "", the empty string, so it's impossible to distinguish between "this value is intentionally set to empty string" and "there was no value present". StringValue
can be null and so solves this problem. It's especially important when they're used in a StructValue
, which may represent arbitrary JSON: to do so it needs to distinguish between a JSON key which was set to empty string (StringValue
with an empty string) or a JSON key which wasn't set at all (null StringValue
).
Also if you look at struct.proto, you'll see that these aren't fully fledged message types in the proto - they're all generated from message Value
, which has a oneof kind { number_value, string_value, bool_value...
etc. By using a oneof
struct.proto can represent a variety of different values in one field. Again this makes sense considering what struct.proto is designed to handle - arbitrary JSON - you don't know what type of value a given JSON key has ahead of time.