You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/programming-guides/json.md
+37-4Lines changed: 37 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,7 +74,7 @@ The following table shows how data is represented in JSON files.
74
74
<p>
75
75
Well-known types have special representations, as described in the <a href="#wkt">Well-known types table</a>.
76
76
<p>
77
-
<code>null</code> is valid for any field and leaves the field unset. See <a href="null-values">Null Values</a> for clarification about the semantic behavior of null values.
77
+
<code>null</code> is valid for any field and leaves the field unset. See <a href="#null-values">Null Values</a> for clarification about the semantic behavior of null values.
78
78
</td>
79
79
</tr>
80
80
<tr>
@@ -122,7 +122,7 @@ The following table shows how data is represented in JSON files.
122
122
<td>int32, fixed32, uint32</td>
123
123
<td>number</td>
124
124
<td><code>1, -10, 0</code></td>
125
-
<td>JSON value will be a decimal number. Either numbers or strings are
125
+
<td>JSON value will be a number. Either numbers or strings are
126
126
accepted. Empty strings are invalid. Exponent notation (such as <code>1e2</code>) is
127
127
accepted in both quoted and unquoted forms.
128
128
</td>
@@ -133,7 +133,8 @@ The following table shows how data is represented in JSON files.
133
133
<td><code>"1", "-10"</code></td>
134
134
<td>JSON value will be a decimal string. Either numbers or strings are
135
135
accepted. Empty strings are invalid. Exponent notation (such as <code>1e2</code>) is
136
-
accepted in both quoted and unquoted forms.
136
+
accepted in both quoted and unquoted forms. See <a href="#int64-strings">Strings for int64s</a>
137
+
for the explanation why strings are used for int64s.
137
138
</td>
138
139
</tr>
139
140
<tr>
@@ -314,7 +315,7 @@ may be impractical or infeasible, so it is strongly recommended that systems
314
315
avoid relying on specific behavior for duplicate fields in ProtoJSON where
315
316
possible.
316
317
317
-
### Out of range numeric values
318
+
### Out of range numeric values {#out-of-range-values}
318
319
319
320
When parsing a numeric value, if the number that is is parsed from the wire
320
321
doesn't fit in the corresponding type, the parser should fail to parse.
@@ -326,6 +327,38 @@ Values with nonzero fractional portions are not allowed for integer-typed
326
327
fields. Zero fractional portions are accepted. For example `1.0` is valid for an
327
328
int32 field, but `1.5` is not.
328
329
330
+
### Strings for int64 {#int64-strings}
331
+
332
+
Unfortunately, the [json.org](https://json.org) spec does not speak to the
333
+
intended precision limits of numbers. Many implementations follow the original
334
+
JS behavior that JSON was derived from and interpret all numbers as binary64
335
+
(double precision) and are silently lossy if a number is an integer larger than
336
+
2**53. Other implementations may support unlimited precision bigints, int64s, or
337
+
even bigfloats with unlimited fractional precision.
338
+
339
+
This creates a situation where if the JSON contains a number that is not exactly
340
+
representable by double precision, different parsers will behave differently,
341
+
including silent precision loss in many languages.
342
+
343
+
To avoid these problems, ProtoJSON serializers emit int64s as strings to ensure
344
+
no precision loss will occur on large int64s by any implementation.
345
+
346
+
When parsing a bare number when expecting an int64, the implementation should
347
+
coerce that value to double-precision even if the corresponding language's
348
+
built-in JSON parser supports parsing of JSON numbers as bigints. This ensures a
349
+
consistent interpretation of the same data, regardless of language used.
350
+
351
+
This design follows established best practices in how to handle large numbers in
352
+
JSON when prioritizing interoperability, including:
353
+
354
+
*[RFC8259](https://datatracker.ietf.org/doc/html/rfc8259#section-6) includes
355
+
a note that software that intends good interoperability should only presume
0 commit comments