@@ -6,7 +6,7 @@ description = "Explains the various presence-tracking disciplines for protobuf f
6
6
type = " docs"
7
7
+++
8
8
9
- ## Background
9
+ ## Background {#background}
10
10
11
11
* Field presence* is the notion of whether a protobuf field has a value. There
12
12
are two different manifestations of presence for protobufs: * implicit presence* ,
@@ -18,15 +18,15 @@ recommend always adding the `optional` label for proto3 basic types. This
18
18
provides a smoother path to editions, which uses explicit presence by
19
19
default.{{% /alert %}}
20
20
21
- ### Presence Disciplines
21
+ ### Presence Disciplines {#disciplines}
22
22
23
23
* Presence disciplines* define the semantics for translating between the * API
24
24
representation* and the * serialized representation* . The * implicit presence*
25
25
discipline relies upon the field value itself to make decisions at
26
26
(de)serialization time, while the * explicit presence* discipline relies upon the
27
27
explicit tracking state instead.
28
28
29
- ### Presence in * Tag-value stream* (Wire Format) Serialization
29
+ ### Presence in * Tag-value stream* (Wire Format) Serialization {#presence-tag-value}
30
30
31
31
The wire format is a stream of tagged, * self-delimiting* values. By definition,
32
32
the wire format represents a sequence of * present* values. In other words, every
@@ -66,7 +66,7 @@ deserializing wire-formatted messages:
66
66
APIs. However, out-of-range values may be stored as * unknown fields* in the
67
67
API, even though the wire-format tag was recognized.
68
68
69
- ### Presence in * Named-field Mapping* Formats
69
+ ### Presence in * Named-field Mapping* Formats {#presence-named-field}
70
70
71
71
Protobufs can be represented in human-readable, textual forms. Two notable
72
72
formats are TextFormat (the output format produced by generated message
@@ -104,7 +104,7 @@ practice, however, presence correctness can vary depending upon implementation
104
104
choices, especially if JSON was chosen as a means to interoperate with clients
105
105
not using protobufs.
106
106
107
- ### Presence in Proto2 APIs
107
+ ### Presence in Proto2 APIs {#presence-proto2}
108
108
109
109
This table outlines whether presence is tracked for fields in proto2 APIs (both
110
110
for generated APIs and using dynamic reflection):
@@ -147,7 +147,7 @@ several methods:
147
147
Repeated fields and maps do not track presence: there is no distinction between
148
148
an * empty* and a * not-present* repeated field.
149
149
150
- ### Presence in Proto3 APIs
150
+ ### Presence in Proto3 APIs {#presence-proto3}
151
151
152
152
This table outlines whether presence is tracked for fields in proto3 APIs (both
153
153
for generated APIs and using dynamic reflection):
@@ -187,7 +187,7 @@ required to have an enumerator value which maps to 0. By convention, this is an
187
187
the domain of valid values for the application, this behavior can be thought of
188
188
as tantamount to * explicit presence* .
189
189
190
- ### Presence in Editions APIs
190
+ ### Presence in Editions APIs {#presence-editions}
191
191
192
192
This table outlines whether presence is tracked for fields in editions APIs
193
193
(both for generated APIs and using dynamic reflection):
@@ -239,7 +239,7 @@ For a singular field with numeric, enum, or string type:
239
239
exception to this behavior is Dart, which generates ` has_ ` methods with proto3
240
240
proto schema files.{{% /alert %}}
241
241
242
- ### Considerations for Merging
242
+ ### Considerations for Merging {#merging}
243
243
244
244
Under the * implicit presence* rules, it is effectively impossible for a target
245
245
field to merge-from its default value (using the protobuf's API merging
@@ -256,7 +256,7 @@ Updating to set a default value in this case requires some external mechanism,
256
256
such as ` FieldMask ` . However, if presence * is* tracked, then all explicitly-set
257
257
values -- even default values -- will be merged into the target.
258
258
259
- ### Considerations for change-compatibility
259
+ ### Considerations for change-compatibility {#change-compatibility}
260
260
261
261
Changing a field between * explicit presence* and * implicit presence* is a
262
262
binary-compatible change for serialized values in wire format. However, the
@@ -334,7 +334,7 @@ this is not a safe change: client A requires (by `assert`) that the field is
334
334
present; even without any modifications through the API, that requirement fails
335
335
in a value- and peer-dependent case.
336
336
337
- ## How to Enable * Explicit Presence* in Proto3
337
+ ## How to Enable * Explicit Presence* in Proto3 {#enable-explicit-proto3}
338
338
339
339
These are the general steps to use field tracking support for proto3:
340
340
@@ -344,7 +344,7 @@ These are the general steps to use field tracking support for proto3:
344
344
1 . Use the generated "hazzer" methods and "clear" methods in application code,
345
345
instead of comparing or setting default values.
346
346
347
- ### ` .proto ` File Changes
347
+ ### ` .proto ` File Changes {#proto-file-changes}
348
348
349
349
This is an example of a proto3 message with fields which follow both * no
350
350
presence* and * explicit presence* semantics:
@@ -362,7 +362,7 @@ message MyMessage {
362
362
}
363
363
```
364
364
365
- ### ` protoc ` Invocation
365
+ ### ` protoc ` Invocation {#protoc-invocation}
366
366
367
367
Presence tracking for proto3 messages is enabled by default
368
368
[ since v3.15.0] ( https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0 )
@@ -399,7 +399,7 @@ message Msg {
399
399
In the examples, a function ` GetProto ` constructs and returns a message of type
400
400
` Msg ` with unspecified contents.
401
401
402
- #### C++ Example
402
+ #### C++ Example {#cpp-example}
403
403
404
404
Implicit presence:
405
405
@@ -427,7 +427,7 @@ if (m.has_foo()) {
427
427
}
428
428
```
429
429
430
- #### C# Example
430
+ #### C# Example {#csharp-example}
431
431
432
432
Implicit presence:
433
433
@@ -455,7 +455,7 @@ if (m.HasFoo) {
455
455
}
456
456
```
457
457
458
- #### Go Example
458
+ #### Go Example {#go-example}
459
459
460
460
Implicit presence:
461
461
@@ -483,7 +483,7 @@ if m.Foo != nil {
483
483
}
484
484
```
485
485
486
- #### Java Example
486
+ #### Java Example {#java-example}
487
487
488
488
These examples use a ` Builder ` to demonstrate clearing. Simply checking presence
489
489
and getting values from a ` Builder ` follows the same API as the message type.
@@ -514,7 +514,7 @@ if (m.hasFoo()) {
514
514
}
515
515
```
516
516
517
- #### Python Example
517
+ #### Python Example {#python-example}
518
518
519
519
Implicit presence:
520
520
@@ -540,7 +540,7 @@ else:
540
540
m.foo = 1
541
541
```
542
542
543
- #### Ruby Example
543
+ #### Ruby Example {#ruby-example}
544
544
545
545
Implicit presence:
546
546
568
568
end
569
569
```
570
570
571
- #### Javascript Example
571
+ #### Javascript Example {#js-example}
572
572
573
573
Implicit presence:
574
574
@@ -596,7 +596,7 @@ if (m.hasFoo()) {
596
596
}
597
597
```
598
598
599
- #### Objective-C Example
599
+ #### Objective-C Example {#objc-example}
600
600
601
601
Implicit presence:
602
602
0 commit comments