Skip to content

Conversation

gtungatkar
Copy link

Go implementation of JSONPB does not support well-known proto type FieldMask, which has special JSON encoding.
The spec is defined as:
mask { paths: "user.display_name" paths: "photo" }
JSON:
{ mask: "user.displayName,photo" }
What jsonpb actually serializes it as:
mask: {paths: ["user.displayName","photo"]}

While this has been fixed in v2 as described in this issue golang/protobuf#745 , v1 is still widely in use and v2 does not have published timelines.

What does this pull request do
This PR adds support for correctly serializing FieldMask. But since this is a breaking change, this fix is gated by an env variable.
Protobuf implementations in other languages like python/cpp already support FieldMask. This allows gogo JSONPB generated JSON to be compatible.

@gtungatkar
Copy link
Author

@donaldgraham @jmarais please let me know if I can do anything to get this reviewed and hopefully merged.

@peats-bond
Copy link

peats-bond commented Jul 23, 2019

Ping on this PR! We'd like to get this reviewed when you get a chance :)

Copy link

@peats-bond peats-bond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall 👍

Copy link

@peats-bond peats-bond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link

@mh-park mh-park left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic looks good; some concerns with error handling and some nits!

Copy link

@mh-park mh-park left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@jmarais
Copy link
Contributor

jmarais commented Jul 30, 2019

Hi. Thanks for contribution.
You mentioned:

But since this is a breaking change, this fix is gated by an env variable.

Why did you remove it in a recent commit? Since this is a breaking change I do not just want to merge it without any guard in place.

jsonpb/jsonpb.go Outdated

// To correctly support marshaling field masks, the following is largely copied from the `golang/protobuf` v2 implementation
// https://github.com/golang/protobuf/blob/a3369c5dc28ac197f8ec8de40a7291be4dea85b5/encoding/protojson/well_known_types.go#L884
if proto.MessageName(v) == "google.protobuf.FieldMask" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can generate a XXX_WellKnownType() method for the FieldMask message here:
https://github.com/gogo/protobuf/blob/master/protoc-gen-gogo/generator/generator.go#L2032
and then you can add the "FieldMask" case here:
https://github.com/gogo/protobuf/blob/master/jsonpb/jsonpb.go#L816

And same with the unmarshal

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@gtungatkar
Copy link
Author

Hi. Thanks for contribution.
You mentioned:

But since this is a breaking change, this fix is gated by an env variable.

Why did you remove it in a recent commit? Since this is a breaking change I do not just want to merge it without any guard in place.

Hi, yes i removed it since we were just going to apply the patch internally if we could not get it accepted. I can add it back if you think that you will be able to accept/merge the pull request. I will address other comments.

Apply suggestions from code review

Co-Authored-By: Alex Peats-Bond <[email protected]>
@gtungatkar gtungatkar force-pushed the add-jsonpb-field-mask-support branch from ae35ac2 to 4ea7d02 Compare July 31, 2019 20:13
@jmarais
Copy link
Contributor

jmarais commented Aug 1, 2019

I think this change is fine. As you pointed out, the current marshaled format is not inline with the proto spec.
However, think a better approach would be to add it as an option on the marshaler/unmarshaler struct first, with the default off. This will prevent us from break backward compatibility.

@gtungatkar
Copy link
Author

I think this change is fine. As you pointed out, the current marshaled format is not inline with the proto spec.
However, think a better approach would be to add it as an option on the marshaler/unmarshaler struct first, with the default off. This will prevent us from break backward compatibility.

Added option on the marshaler/unmarshaler struct

@gpopovic
Copy link

Any news about this one? :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants