-
Notifications
You must be signed in to change notification settings - Fork 37
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
Unexpected 0-th value enum JSON serialization #235
Comments
The proto2 behavior definitely seems like a bug. As you mentioned, proto2 doesn't officially have a JSON spec defined and so pbandk doesn't officially support JSON with proto2. But we do try to match the behavior of the official protobuf libraries where possible. We would gladly accept a PR with a fix. The proto3 behavior I would argue is compliant with the spec. According to https://developers.google.com/protocol-buffers/docs/proto3#json:
pbandk does have the |
Thank you for the quick turnaround time :) Happy to hear that we can move forward with the fix for If you agree, please review #234 which only adds unit tests that show the current behavior. This will make our follow-up fix PR clearer. -- I looked into implementing the fix for A simpler approach is to say that Digging deeper, I came across Application note: Field presence which suggests that our fix here might not be enum-specific. From that doc:
This suggests that we should serialize default values of all optional fields (not only enums). -- Having all of the above, we can apply the fix with 3 scopes:
My hunch would be to move forward with 3) since it makes the code cleaner and is more aligned with other implementations. I can provide more details here if needed :) Looking forward to your input! |
I agree that this would be the preferred route. In general, it's better to avoid writing code that makes decisions based on proto2 vs proto3 (when possible) and instead write code that makes decisions based on the field's presence discipline (as described in the doc you linked to).
Yes agreed. Just keep in mind the distinction between "no presence" (the default behavior for non-repeated proto3 fields) and "explicit presence" (used in proto2 and proto3 for fields that include the |
Yep, I'll review them. I should have time later today to take a look at the PRs. |
Thank you for the review on the unit test PR. The fix PR is here: #238 |
# Motivation See #235 (comment). This PR only adds the unit tests that document the current behavior. We will implement the fix as discussed in #235 in the follow-up PR, after this one is merged. # Changes * Added a unit test to document the behavior that will be fixed in a follow-up PR. * After changing the `test_proto2.proto` I executed `./gradlew generateProtos` to generate the `TestProto.java` and `test_proto2.kt` # Tested Executed unit tests locally and they pass.
…#238) # Motivation Fixes #235 # Changes * Change the behavior for JSON serialization for fields with explicit presence. * If unset -> don't emit on the wire. * If set -> emit on the wire, even if the value is default (regardless of the `jsonConfig.outputDefaultValues`) This is consistent with the following: https://github.com/protocolbuffers/protobuf/blob/main/docs/field_presence.md#semantic-differences This PR also changes behavior of `outputDefaultValues` for unset nested message fields. Before we were outputting `null` and now we don't output any value. This is consistent with c++, python and java, as explained here: noom/protobuf#5 # Tested Run all unit tests in `runtime`
@antongrbin Thank you for the thorough fix and tests! |
@garyp is there anything blocking the 0.14.2 release? Milestone looks all closed: https://github.com/streem/pbandk/milestone/12 Thank you for your time :) |
@antongrbin It's released now! |
See #235 (comment). This PR only adds the unit tests that document the current behavior. We will implement the fix as discussed in #235 in the follow-up PR, after this one is merged. * Added a unit test to document the behavior that will be fixed in a follow-up PR. * After changing the `test_proto2.proto` I executed `./gradlew generateProtos` to generate the `TestProto.java` and `test_proto2.kt` Executed unit tests locally and they pass.
…#238) Fixes #235 * Change the behavior for JSON serialization for fields with explicit presence. * If unset -> don't emit on the wire. * If set -> emit on the wire, even if the value is default (regardless of the `jsonConfig.outputDefaultValues`) This is consistent with the following: https://github.com/protocolbuffers/protobuf/blob/main/docs/field_presence.md#semantic-differences This PR also changes behavior of `outputDefaultValues` for unset nested message fields. Before we were outputting `null` and now we don't output any value. This is consistent with c++, python and java, as explained here: noom/protobuf#5 Run all unit tests in `runtime`
The testing message is defined as follows:
We observe the following serialization with pbandk:
MessageWithEnum()
{"value":null}
{}
MessageWithEnum(value=FOO)
{}
{"value":"FOO"}
MessageWithEnum(value=BAR)
{"value":"BAR"}
The bug is reproduced in a unit test here:
#234
I know that proto2 doesn't really have a JSON spec defined, but other protobuf implementations (java, python, swift) would all behave as expected in this example.
In proto3, we observed the following serialization behavior:
TestAllTypesProto3()
{}
TestAllTypesProto3(optionalNestedEnum = FOO)
{}
{"value":"FOO"}
TestAllTypesProto3(optionalNestedEnum = BAR)
{"value":"BAR"}
Thank you for your time :)
The text was updated successfully, but these errors were encountered: