-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
When decoding protobuf messages from JSON, the decoder currently requires the generated code for all of the message types referenced from any field of type [repeated] google.protobuf.Any be linked into the binary.
We (Kythe) have tools that receive JSON-encoded protobuf messages as input, decode them, examine some of their fields, and then do other work based on what those fields contain. Schematically, we have a message like this:
message M {
Config info = 1;
repeated google.protobuf.Any details = 2;
}
This arrives as JSON, is decoded, and then passed along based on the contents of info.
The tool links M and Config already, since those are common to all uses. Unfortunately, if the provider of the message adds an unknown message to the details field whose decoder isn't linked, the decoding step currently fails. This makes it difficult to use Any messages forward-compatibly.
Ideally, we'd like the ability to treat Any messages similarly to how the encoding/json package handles json.RawMessage, viz., that they could be decoded to an intermediate type that preserves the encoded format until explicitly decoded.
One sensible implementation could be to add an option to jsonpb.Unmarshaler, that when set would make the decoding of google.protobuf.Any messages return an instance of a library type (perhaps: jsonpb.RawAny?) that
- implements
proto.Message, - encapsulates the un-decoded Any message (as JSON), and
- completes the decoding when explicitly unmarshalled (requiring the type to be linked)
There are probably other solutions, but this would I think solve our issues without requiring breaking changes to the API.
We could probably work around this by introducing our own work-alike equivalent of "Any". However, given that Any is designed as an extension point, it would be nice if the decoder could have control over this without changing the message structure explicitly.