Repository navigation
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
Only oneof members and extensions special-cased NullValue. Every other
field shape went through the generic open-enum helpers, so optional,
required, repeated and map NullValue fields serialized as "NULL_VALUE"
in both owned and view JSON, and opt_enum read `{"f": null}` as an
unset field, which then dropped out of the binary encoding. ProtoJSON
(and buffa's own DynamicMessage) writes every NullValue as null and
reads null as a present NULL_VALUE.
Codegen now routes NullValue fields to dedicated json_helpers modules:
null_value, opt_null_value, repeated_null_value, map_null_value and
bytes_key_null_value_map for the bytes keys that strict_utf8_mapping
produces. They write null and read null, "NULL_VALUE" or a number, and
keep the ignore_unknown_enum_values filtering of the enum helpers. The
generated view Serialize writes null for the same shapes. They do not
share code with repeated_enum or map_enum, so a change to how those
treat null elements does not reach NullValue.
v0ropaev
force-pushed
the
fix/json-null-value-fields
branch
from
October 28, 2026 12:24
c4e63f9 to
dc7f6a6
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Generated JSON only treats
google.protobuf.NullValuespecially for oneof members and extensions. Every other field shape goes through the generic open-enum helpers, so an optional, required, repeated or map NullValue field serializes as the string"NULL_VALUE", in owned and view serialization alike. On the way in,opt_enumreads{"opt": null}as an unset field, so the value is dropped and also disappears from the binary encoding.struct.proto says the JSON representation of NullValue is JSON null, and protobuf-go and the C++ parser read null as a present
NULL_VALUE. buffa's ownDynamicMessagealready does both, so right now generated types andDynamicMessageproduce different JSON for the same bytes.and
serde_json::from_str::<M>(r#"{"opt":null}"#)?.optwasNone, now it'sSome(NULL_VALUE).Codegen now sends NullValue fields to dedicated
json_helpersmodules (null_value,opt_null_value,repeated_null_value,map_null_value, andbytes_key_null_value_mapfor the bytes keys thatstrict_utf8_mappingproduces). They write null, accept null,"NULL_VALUE"or a number, and keep theignore_unknown_enum_valuesfiltering the enum helpers have. An unknown number in a NullValue field is also written as null, the same as protobuf-go, C++ andDynamicMessage. The generated viewSerializewrites null for the same shapes.The new modules deliberately don't share code with
repeated_enumormap_enum, so #766, which starts rejecting null elements in those, won't affect NullValue lists and maps. I checked that the two apply together and both sets of tests pass.The tests build proto3, edition 2023 and proto2 fixtures with views and JSON. They check owned and view output for the implicit, optional, required, repeated and map shapes (string, integer, bool and bytes keys), and parsing for the explicit-presence and container shapes. Generated code from this version needs the matching buffa, since it names the new helper modules.