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

Missing fields from JSON serialization #606

Closed
plamenterziev opened this issue Jun 20, 2017 · 6 comments
Closed

Missing fields from JSON serialization #606

plamenterziev opened this issue Jun 20, 2017 · 6 comments

Comments

@plamenterziev
Copy link

If enum is set to its default value it seems that the field is missing from the JSON.

For example:

syntax = "proto3";

message MyMessage {
	
	enum MyEnum {
		FIRST_VALUE = 0;
		SECOND_VALUE = 1;
	}

	MyEnum e = 1;
}

If the code is:

let c = MyMessage.with {
    $0.e = .firstValue
}
        
print(try! c.jsonString())

then the output is wrong and the field is missing:

{}

However if change the value of e to $0.e = .secondValue then the output is correct: {"e":"SECOND_VALUE"}

@tbkka
Copy link
Contributor

tbkka commented Jun 20, 2017

This is standard protobuf behavior. Proto3 compresses the output by omitting any field that has a default value. This applies to both the binary protobuf encoding and to JSON encoding.

From https://developers.google.com/protocol-buffers/docs/proto3#json

If a value is missing in the JSON-encoded data or if its value is null, it will be interpreted as the appropriate default value when parsed into a protocol buffer. If a field has the default value in the protocol buffer, it will be omitted in the JSON-encoded data by default to save space.

@plamenterziev
Copy link
Author

@tbkka - does it mean that if change the default value later and the deserialization of an old serialized data will produce wrong results?

@thomasvl
Copy link
Collaborator

In proto3 syntax, the only possible default values are the zero values, so they can't really be changed.

In proto2 syntax, you can state explicit default values (non zero). But since any value that is explicitly set is sent over the wire (JSON, binary, etc.), the conditions are a little different. The proto2 guide talks about changing defaults in the section on updating a proto definition.

@plamenterziev
Copy link
Author

ok, thank you for the clarification

@sboddeus
Copy link

sboddeus commented Nov 24, 2023

@thomasvl
Sorry to comment on an old issue.

The specification seems to mention that implementations can allow default values to be encoded in the JSON as an option.
The last sentence of:
"When generating JSON-encoded output from a protocol buffer, if a protobuf field has the default value and if the field doesn’t support field presence, it will be omitted from the output by default. An implementation may provide options to include fields with default values in the output."
From here: https://protobuf.dev/programming-guides/proto3/#json

Would it be possible to have it added as an option to this function call:

  public func jsonString(
    options: JSONEncodingOptions = JSONEncodingOptions()
  ) throws -> String 

Or specifically a property here:

/// Options for JSONEncoding.
public struct JSONEncodingOptions {

  /// Always print enums as ints. By default they are printed as strings.
  public var alwaysPrintEnumsAsInts: Bool = false

  /// Whether to preserve proto field names.
  /// By default they are converted to JSON(lowerCamelCase) names.
  public var preserveProtoFieldNames: Bool = false

  public init() {}
}

If the answer is yes but limited resources, I'd be happy to try make a PR.

@thomasvl
Copy link
Collaborator

See #861

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

No branches or pull requests

4 participants