Skip to content

Commit 89a0c1c

Browse files
authored
Merge pull request #184 from Logofile/main
Documentation change
2 parents b5911c4 + b34117f commit 89a0c1c

File tree

3 files changed

+311
-179
lines changed

3 files changed

+311
-179
lines changed

content/editions/overview.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,32 @@ import "myproject/foo.proto";
307307
While the generated code changes when you move from proto2 or proto3 to
308308
editions, the wire format does not. You'll still be able to access proto2 and
309309
proto3 data files or file streams using your editions-syntax proto definitions.
310+
311+
### Grammar Changes {#syntax}
312+
313+
There are some grammar changes in editions compared to proto2 and proto3.
314+
315+
**Syntax description.** Instead of the `syntax` element, you use an `edition`
316+
element:
317+
318+
```proto
319+
syntax = "proto2";
320+
syntax = "proto3";
321+
edition = "2028";
322+
```
323+
324+
**Reserved names.** You no longer put field names and enum value names in
325+
quotation marks when reserving them:
326+
327+
```proto
328+
reserved foo, bar;
329+
```
330+
331+
**Group syntax.** Group syntax, available in proto2, is removed in editions. The
332+
special wire-format that groups used is still available by using `DELIMITED`
333+
message encoding.
334+
335+
**Required label.** The `required` label, available only in proto2, is
336+
unavailable in editions. The underlying functionality is still available (but
337+
[discouraged](/programming-guides/required-considered-harmful))
338+
by using `features.field_presence=LEGACY_REQUIRED`.

content/reference/kotlin/kotlin-generated.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,61 @@ extend Foo {
369369

370370
Java generates the \"extension identifier\" `bar`, which is used to \"key\"
371371
extension operations above.
372+
373+
## Why Doesn't Protobuf Support Nullable Setters/Getters? {#nullable-setters-getters}
374+
375+
We have heard feedback that some folks would like protobuf to support nullable
376+
getters/setters in their null-friendly language of choice (particularly Kotlin,
377+
C#, and Rust). While this does seem to be a helpful feature for folks using
378+
those languages, the design choice has tradeoffs which have led to the Protobuf
379+
team choosing not to implement them.
380+
381+
The biggest reason not to have nullable fields is the intended behavior of
382+
default values specified in a `.proto` file. By design, calling a getter on an
383+
unset field will return the default value of that field.
384+
385+
As an example, consider this `.proto` file:
386+
387+
```proto
388+
message Msg { optional Child child = 1; }
389+
message Child { optional Grandchild grandchild = 1; }
390+
message Grandchild { optional int32 foo = 1 [default = 72]; }
391+
```
392+
393+
and corresponding Kotlin getters:
394+
395+
```kotlin
396+
// With our API where getters are always non-nullable:
397+
msg.child.grandchild.foo == 72
398+
399+
// With nullable submessages the ?. operator fails to get the default value:
400+
msg?.child?.grandchild?.foo == null
401+
402+
// Or verbosely duplicating the default value at the usage site:
403+
(msg?.child?.grandchild?.foo ?: 72)
404+
```
405+
406+
If a nullable getter existed, it would necessarily ignore the user-specified
407+
defaults (to return null instead) which would lead to surprising and
408+
inconsistent behavior. If users of nullable getters want to access the default
409+
value of the field, they would have to write their own custom handling to use
410+
the default if null is returned, which removes the supposed benefit of
411+
cleaner/easier code with null getters.
412+
413+
Similarly, we do not provide nullable setters as the behavior would be
414+
unintuitive. Performing a set and then get would not always give the same value
415+
back, and calling a set would only sometimes affect the has-bit for the field.
416+
417+
Note that message-typed fields are always explicit presence fields (with
418+
hazzers). Proto3 defaults to scalar fields having implicit presence (without
419+
hazzers) unless they are explicitly marked `optional`, while Proto2 does not
420+
support implicit presence. With
421+
[Editions](/editions/features#field_presence), explicit
422+
presence is the default behavior unless an implicit presence feature is used.
423+
With the forward expectation that almost all fields will have explicit presence,
424+
the ergonomic concerns that come with nullable getters are expected to be more
425+
of a concern than they may have been for Proto3 users.
426+
427+
Due to these issues, nullable setters/getters would radically change the way
428+
default values can be used. While we understand the possible utility, we have
429+
decided it’s not worth the inconsistencies and difficulty it introduces.

0 commit comments

Comments
 (0)