Skip to content

Commit 1a7567c

Browse files
Clarity adjustments to JSON documentation
- Split WKT repr into a separate table. - Push field names discussion into a paragraph instead of trying to cram it into the table. - Correct table header to use <thead> semantic tag type (the cells were already <th> so this is only a nitpick) PiperOrigin-RevId: 861738414
1 parent c6c8ba5 commit 1a7567c

1 file changed

Lines changed: 73 additions & 25 deletions

File tree

content/programming-guides/json.md

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,28 @@ See [JSON Wire Safety](#json-wire-safety) below for more details.
5353
The following table shows how data is represented in JSON files.
5454

5555
<table>
56-
<tbody>
56+
<thead>
5757
<tr>
58-
<th>Protobuf</th>
58+
<th>Protobuf type</th>
5959
<th>JSON</th>
6060
<th>JSON example</th>
6161
<th>Notes</th>
6262
</tr>
63+
</thead>
64+
<tbody>
6365
<tr>
6466
<td>message</td>
6567
<td>object</td>
6668
<td><code>{"fooBar": v, "g": null, ...}</code></td>
67-
<td>Generates JSON objects. Message field names are mapped to
68-
lowerCamelCase and become JSON object keys. If the
69-
<code>json_name</code> field option is specified, the specified value
70-
will be used as the key instead. Parsers accept both the lowerCamelCase
71-
name (or the one specified by the <code>json_name</code> option) and the
72-
original proto field name. <code>null</code> is an accepted value for
73-
all field types and leaves the field unset. <code>\0 (nul)</code> cannot
74-
be used within a <code>json_name</code> value. For more on why, see
75-
<a href="/news/2023-04-28#json-name">Stricter validation for json_name</a>.
69+
<td>Generates JSON objects.
70+
<p>
71+
Keys are serialized as lowerCamelCase of field name. See
72+
<a href="#field-names">Field Names</a> for more special cases regarding mapping of field names
73+
to object keys.
74+
<p>
75+
Well-known types have special representations, as described in the <a href="#wkt">Well-known types table</a>.
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.
7678
</td>
7779
</tr>
7880
<tr>
@@ -87,13 +89,13 @@ The following table shows how data is represented in JSON files.
8789
<td>map&lt;K,V&gt;</td>
8890
<td>object</td>
8991
<td><code>{"k": v, ...}</code></td>
90-
<td>All keys are converted to strings (keys in JSON spec can only be strings).</td>
92+
<td>All keys are converted to strings (object keys in JSON can only be strings).</td>
9193
</tr>
9294
<tr>
9395
<td>repeated V</td>
9496
<td>array</td>
9597
<td><code>[v, ...]</code></td>
96-
<td><code>null</code> is accepted as the empty list <code>[]</code>.</td>
98+
<td></td>
9799
</tr>
98100
<tr>
99101
<td>bool</td>
@@ -121,7 +123,7 @@ The following table shows how data is represented in JSON files.
121123
<td>number</td>
122124
<td><code>1, -10, 0</code></td>
123125
<td>JSON value will be a decimal number. Either numbers or strings are
124-
accepted. Empty strings are invalid. Exponent notation (such as `1e2`) is
126+
accepted. Empty strings are invalid. Exponent notation (such as <code>1e2</code>) is
125127
accepted in both quoted and unquoted forms.
126128
</td>
127129
</tr>
@@ -130,7 +132,7 @@ The following table shows how data is represented in JSON files.
130132
<td>string</td>
131133
<td><code>"1", "-10"</code></td>
132134
<td>JSON value will be a decimal string. Either numbers or strings are
133-
accepted. Empty strings are invalid. Exponent notation (such as `1e2`) is
135+
accepted. Empty strings are invalid. Exponent notation (such as <code>1e2</code>) is
134136
accepted in both quoted and unquoted forms.
135137
</td>
136138
</tr>
@@ -143,19 +145,41 @@ The following table shows how data is represented in JSON files.
143145
Empty strings are invalid. Exponent notation is also accepted.
144146
</td>
145147
</tr>
148+
</tbody>
149+
<table>
150+
151+
<!-- This section html instead of markdown as workaround to bug that escapes all html between the first and last table -->
152+
<h3 id="wkt">Well-Known Types</h3>
153+
154+
<p>Some messages in the <code>google.protobuf</code> package have a special representation
155+
when represented in JSON.
156+
157+
<p>No message type outside of the <code>google.protobuf</code> package has a special ProtoJSON
158+
handling; for example, types in <code>google.types</code> package are represented with the
159+
neutral representation.
160+
161+
<table>
162+
<thead>
163+
<tr>
164+
<th>Message type</th>
165+
<th>JSON</th>
166+
<th>JSON example</th>
167+
<th>Notes</th>
168+
</tr>
169+
</thead>
170+
<tbody>
146171
<tr>
147172
<td>Any</td>
148173
<td><code>object</code></td>
149174
<td><code>{"@type": "url", "f": v, ... }</code></td>
150-
<td>See <a href="#any">Any</a>
151-
</td>
175+
<td>See <a href="#any">Any</a></td>
152176
</tr>
153177
<tr>
154178
<td>Timestamp</td>
155179
<td>string</td>
156180
<td><code>"1972-01-01T10:00:20.021Z"</code></td>
157-
<td>Uses RFC 3339 (see <a href="#rfc3339-timestamp">clarification</a>), where generated output will always be Z-normalized
158-
and uses 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are
181+
<td>Uses RFC 3339 (see <a href="#rfc3339-timestamp">clarification</a>). Generated output will always be Z-normalized
182+
with 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are
159183
also accepted.
160184
</td>
161185
</tr>
@@ -166,7 +190,7 @@ The following table shows how data is represented in JSON files.
166190
<td>Generated output always contains 0, 3, 6, or 9 fractional digits,
167191
depending on required precision, followed by the suffix "s". Accepted
168192
are any fractional digits (also none) as long as they fit into
169-
nanoseconds precision and the suffix "s" is required. This is *not* RFC 3339
193+
nanoseconds precision and the suffix "s" is required. This is <b>not</b> RFC 3339
170194
'duration' format (see <a href="#rfc3339-duration">Durations</a> for clarification).
171195
</td>
172196
</tr>
@@ -215,17 +239,34 @@ The following table shows how data is represented in JSON files.
215239
<tr>
216240
<td>Empty</td>
217241
<td>object</td>
218-
<td><code>{} (not special cased)</code></td>
242+
<td><code>{}</code> <b>(not special cased)</b></td>
219243
<td>An empty JSON object</td>
220244
</tr>
221245
</tbody>
222246
</table>
223247

248+
## Field names as JSON keys {#field-names}
249+
250+
Message field names are mapped to lowerCamelCase to be used as JSON object keys.
251+
If the `json_name` field option is specified, the specified value will be used
252+
as the key instead.
253+
254+
Parsers accept both the lowerCamelCase name (or the one specified by the
255+
`json_name` option) and the original proto field name. This allows for a
256+
serializer option to choose to print using the original field name (see
257+
[JSON Options](#json-options)) and have the resulting output still be parsed
258+
back by all spec parsers.
259+
260+
`\0 (nul)` is not allowed within a `json_name` value. For more on why, see
261+
<a href="/news/2023-04-28#json-name">Stricter validation
262+
for json_name</a>. Note that `\0` is still considered a legal character within
263+
the value of a `string` field.
264+
224265
## Presence and default-values {#presence}
225266

226267
When generating JSON-encoded output from a protocol buffer, if a field supports
227268
presence, serializers must emit the field value if and only if the corresponding
228-
hasser would return true.
269+
hazzer would return true.
229270

230271
If the field doesn't support field presence and has the default value (for
231272
example any empty repeated field) serializers should omit it from the output. An
@@ -236,11 +277,18 @@ output.
236277

237278
Serializers should not emit `null` values.
238279

239-
Parsers should accept `null` as a legal value for any field, with the behavior:
280+
Parsers accept `null` as a legal value for any field, with the following
281+
behavior:
240282

241-
* Any key validity checking should still occur (disallowing unknown fields)
283+
* Any key validity checking should still occur (disallowing unknown fields).
242284
* The field should remain unset, as though it was not present in the input at
243-
all (hassers should still return false where applicable).
285+
all (hazzers should still return false where applicable).
286+
287+
The implication of this is that a `null` value for an implicit presence field
288+
will behave the identically to the behavior to the default value of that field,
289+
since there are no hazzers for those fields. For example, a value of `null` or
290+
`[]` for a repeated field will cause key-validation checks, but both will
291+
otherwise behave the same as if the field was not present in the JSON at all.
244292

245293
`null` values are not allowed within repeated fields.
246294

0 commit comments

Comments
 (0)