Skip to content

protojson: Add MarshalOption to write int64 as a number and not as a string #1414

@corgrath

Description

@corgrath

Is your feature request related to a problem? Please describe.
When using the protonjson library int64 numbers are outputted as strings in the JSON due to this code:

https://github.com/protocolbuffers/protobuf-go/blob/b92717ecb630d4a4824b372bf98c729d87311a4d/encoding/protojson/encode.go#L275-L278

From what I understand, it is written as a string since JavaScript cannot handle that precision.

However, from a JSON stand point (not JavaScript), it should handle any integers (JSON should not care about precision, just as XML shouldn't care about precision).

We are only interested in marshaling a message to a JSON, not to JavaScript, so would like the protonjson to write int64 as an integer/number and not as a string.

Describe the solution you'd like
Add a new to option to MarshalOptions :

https://github.com/protocolbuffers/protobuf-go/blob/b92717ecb630d4a4824b372bf98c729d87311a4d/encoding/protojson/encode.go#L43

Something like:

	// Write64KindsAsInteger will write any 64 bit kinds as integers instead of a string.
	Write64KindsAsInteger

And then in marshalSingular use this option:

	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		if e.opts.Write64KindsAsInteger {
			e.WriteInt64(val.Int())
		} else {
			// 64-bit integers are written out as JSON string.
			e.WriteString(val.String())
		}

	case pref.Uint64Kind, pref.Fixed64Kind:
		if e.opts.Write64KindsAsInteger {
			e.WriteUInt64(val.Int())
		} else {
			// 64-bit integers are written out as JSON string.
			e.WriteString(val.String())
		}

Describe alternatives you've considered
AFAK, there are no other feasible solutions to write int64s as integers in the JSON output.

Additional context
If you use the default JSON marshaller (encoding/json), int64 is written as a number.

However, since we need to output default values, we are forced to use this library due to the EmitUnpopulated option.

So right now our organization is between a hard rock and a stone; Either omit default values (such as 0 and false) or write int64 as strings (and breaking other tools that reads in JSON data).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions