Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update JSON unknown field support #771

Merged
merged 7 commits into from Jul 24, 2018

Conversation

thomasvl
Copy link
Collaborator

Fixes #769

These were actually unknown field name getting skipped and not
real test of setting the field to null.
According to the spec:
  https://developers.google.com/protocol-buffers/docs/proto3#json_options
Unknown field name encountered while parsing JSON should cause
errors, but language can provide a option to allow those fields
to be skipped instead. We had it backwards, and always skipped
them with no way to get an error.

- Add an option to ignore unknown fields during JSON decode.
- Add a JSON Decoding Error to indicated when an unknown
  field was encountered.
- Wire up the option and new error.
- Update the existing tests get the behaviour they arelady
  required around unknown fields in JSON.
- Ensure the unknown field stop parsing (so any other errors don't show.)
- Ensure ensure the unknown field name is reported.
@thomasvl thomasvl requested review from allevato and tbkka July 17, 2018 14:22
@thomasvl
Copy link
Collaborator Author

Given we had the behavior wrong compared to the spec, should we move to 1.1.x to help call out the behavior change?

@thomasvl
Copy link
Collaborator Author

The first commit in there is a bug fix in the existing tests. They thought they were doing one thing, but the actually were dependent on ignoring unknown fields. Sadly we have a few too many failure tests that just see if things fail, but don't really check what error they fail with to confirm they are testing what we think they are.

@thomasvl
Copy link
Collaborator Author

Given we had the behavior wrong compared to the spec, should we move to 1.1.x to help call out the behavior change?

My vote is to do this just incase someone is/was dependent on it.

@@ -55,4 +55,8 @@ public enum JSONDecodingError: Error {
case conflictingOneOf
/// Reached the nesting limit for messages within messages while decoding.
case messageDepthLimit
/// Encountered a unknown field with the given name. When parsing JSON, you
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/Encountered a/Encountered an/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@@ -55,4 +55,8 @@ public enum JSONDecodingError: Error {
case conflictingOneOf
/// Reached the nesting limit for messages within messages while decoding.
case messageDepthLimit
/// Encountered a unknown field with the given name. When parsing JSON, you
/// can instead instructe the library to ignore this via
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/instructe/instruct/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@@ -21,5 +21,9 @@ public struct JSONDecodingOptions {
/// while parsing.
public var messageDepthLimit: Int = 100

/// If unknown fields in the JSON should be ignored. If they aren't
/// ignored, and error will be raised if one is encountered.
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/and error/an error/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@allevato
Copy link
Collaborator

Regarding version number, I agree, let's bump it.

Since we are adding a minor behavior change around unknown field names
in JSON parsing, bump the minor version to help call out this subtle
change in behavior.
@thomasvl
Copy link
Collaborator Author

Add a commit to pump the version also.

@@ -21,5 +21,9 @@ public struct JSONDecodingOptions {
/// while parsing.
public var messageDepthLimit: Int = 100

/// If unknown fields in the JSON should be ignored. If they aren't
/// ignored, an error will be raised if one is encountered.
public var ignoreUnknownFields: Bool = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Just out of curiosity, why is the default value for this option false?

I ask because it seems more natural to set this to true, to me, as someone who uses protobuf to help manage version compatibility across various components.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I also had the pointer in the second commit on the PR, but it is in the spec –

Spec: https://developers.google.com/protocol-buffers/docs/proto3#json_options

Ignore unknown fields: Proto3 JSON parser should reject unknown fields by default but may provide an option to ignore unknown fields in parsing.

With the binary format, the unknown fields can be parsed and preserved to be reflected back out. But for the JSON format, there is no way to know if something was an int32, int64, uint32, etc., so while it could be reflected back out in JSON, you can't convert it or even expose it via a reflection (if you language has proto reflection).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also, since the "ignore" is destructive, it really shouldn't be the default since it means by default we lose things we can't deal with. If we tried to capture the text and reflect it out for JSON, maybe it would make sense, but the fact that a binary conversion would loose things is also bad.

There is a similar issue with enums, if you get a value string you don't know, there is no way to keep it. They also offer up that folks could provide an encoding option to use number, but we haven't added that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, that makes a lot of sense. I am not accustomed to using JSON with proto aside from debugging.

@thomasvl thomasvl merged commit 3dec79b into apple:master Jul 24, 2018
@thomasvl thomasvl deleted the json_parse_unknowns branch July 24, 2018 17:19
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.

None yet

3 participants