protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

json format: how should google.protobuf.Any with google.protobuf.Empty payload be rendered?

Open jhump opened this issue 6 years ago • 4 comments

The spec for Any messages states this:

If the embedded message type is well-known and has a custom JSON representation, that representation will be embedded adding a field value which holds the custom JSON in addition to the @type field.

What is not clear, however, is what does it mean to "have a custom JSON representation"?

I interpret this as having a custom format described in the main JSON format spec.

That is also how both Java and C/C++ runtimes are implemented for google.protobuf.Empty: they do not treat it as having a custom JSON representation and thus would emit the following if encountering an Any that has an Empty as its payload:

{
  "@type": "type.googleapis.com/google.protobuf.Empty"
}

However, the documentation for well-known types includes this regarding Empty messages:

The JSON representation for Empty is empty JSON object {}.

Does that mean this representation is considered "custom"? The Go runtime assumes yes, and thus renders the message in question as follows:

{
  "@type": "type.googleapis.com/google.protobuf.Empty",
  "value": {}
}

Admittedly, the value of putting an Empty into an Any is questionable, but it would be nice if the spec were more clear and if all runtimes behaved the same. As-is, this (admittedly contrived) case reveals an interop problem between runtimes: JSON emitted by one will not be accepted by another.

I originally filed this as a bug against the Go runtime (https://github.com/golang/protobuf/issues/759), but the response to my bug brought into question the spec itself and the behavior of the Java and C/C++ runtimes.

jhump avatar Nov 21 '18 20:11 jhump

I'm starting to look into Go's v2 implementation of jsonpb. It would be nice to get clarifications on this. Thanks!

cybrcodr avatar Feb 05 '19 02:02 cybrcodr

It seems like

{
  "@type": "type.googleapis.com/google.protobuf.Empty",
  "value": {}
}

should be the correct rendering. We don't do that correctly in all languages, which seem like a bug.

ghost avatar Mar 26 '19 00:03 ghost

Thanks for the clarification. Can someone update the doc in https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Empty to make it clearer? I'd suggest --

"The custom JSON representation for Empty is empty JSON object {}."

The word "custom" is used in describing the JSON representation for other well-known types because the description for Any states --

"If the embedded message type is well-known and has a custom JSON representation, that representation will be embedded adding a field value which holds the custom JSON..."

I confirmed that C++ v3.7.0 exhibits the behavior @jhump mentioned. Will this issue be marked closed and create another issue for C++ bug or reuse as a bug on C++?

cybrcodr avatar Mar 27 '19 22:03 cybrcodr