Skip to content

Commit b68f344

Browse files
Protocol Buffer TeamLogofile
authored andcommitted
This documentation change includes the following:
* content/best-practices/dos-donts.md: Adds a note to clarify that "Common Types" (such as Date and Money) are not included with the standard compiler and require a dependency on the GoogleAPIs repository. * content/editions/features.md: Significantly expands the documentation for Protobuf editions features. * content/programming-guides/proto3.md: Adds content to the Proto3 programming guide about specifying paths for import files * content/reference/python/python-comparison.md: Adds a new documentation page that compares different Python implementations for Protocol Buffers. * content/programming-guides/proto-limits.md: Minor content updates. * content/includes/version-tables.css: Minor style adjustments. PiperOrigin-RevId: 799563507 Change-Id: I0624d9dc24207f1366e91b5b82b162da141bf52b
1 parent a97fcd8 commit b68f344

File tree

6 files changed

+214
-19
lines changed

6 files changed

+214
-19
lines changed

content/best-practices/dos-donts.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ when a perfectly suitable common type already exists!
168168
* [`color`](https://github.com/googleapis/googleapis/blob/master/google/type/color.proto)
169169
is a color in the RGBA color space.
170170

171+
**Note:** While the "Well-Known Types" (such as `Duration` and `Timestamp`) are
172+
included with the Protocol Buffers compiler, the "Common Types" (such as `Date`
173+
and `Money`) are not. To use the Common Types, you may need to add a dependency
174+
on the [googleapis repository](https://github.com/googleapis/googleapis).
175+
171176
<a id="do-define-widely-used-message-types-in-separate-files"></a>
172177

173178
## **Do** Define Message Types in Separate Files {#separate-files}

content/editions/features.md

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ message ImportedMessage {
157157
}
158158
```
159159

160-
### `features.enforce_naming_style` {#enforce-naming}
160+
### `features.enforce_naming_style` {#enforce_naming}
161161

162162
Introduced in Edition 2024, this feature enables strict naming style enforcement
163163
as defined in
@@ -199,7 +199,7 @@ message Foo {
199199
}
200200
```
201201

202-
Edition 2025 defaults to `STYLE2024`, so an override is needed to keep the
202+
Edition 2024 defaults to `STYLE2024`, so an override is needed to keep the
203203
non-conformant field name:
204204

205205
```proto
@@ -935,12 +935,89 @@ message MyMessage {
935935
}
936936
```
937937

938-
## Preserving proto2 or proto3 Behavior {#preserving}
938+
### `features.(pb.go).strip_enum_prefix` {#go-strip_enum_prefix}
939+
940+
**Languages:** Go
941+
942+
Enum values are not scoped by their containing enum name, so
943+
[prefixing every value with the enum name is recommended](/programming-guides/style#enums):
944+
945+
```proto
946+
edition = "2024";
947+
948+
enum Strip {
949+
STRIP_ZERO = 0;
950+
STRIP_ONE = 1;
951+
}
952+
```
953+
954+
However, the generated Go code will now contain two prefixes!
955+
956+
```go
957+
type Strip int32
958+
959+
const (
960+
Strip_STRIP_ZERO Strip = 0
961+
Strip_STRIP_ONE Strip = 1
962+
)
963+
```
964+
965+
The language-specific `strip_enum_prefix` feature determines whether the Go code
966+
generator strips the repetitive prefix or not.
967+
968+
**Values available:**
969+
970+
* `STRIP_ENUM_PREFIX_KEEP`: Keep the name as-is, even if repetitive.
971+
* `STRIP_ENUM_PREFIX_GENERATE_BOTH`: Generate both, a full name and a stripped
972+
name (to help with migrating your Go code).
973+
* `STRIP_ENUM_PREFIX_STRIP`: Strip the enum name prefix from enum value names.
974+
975+
**Applicable to the following scopes:** Enum, File
976+
977+
**Added in:** 2024
978+
979+
**Default behavior per syntax/edition:**
980+
981+
Syntax/edition | Default
982+
-------------- | ------------------------
983+
2024 | `STRIP_ENUM_PREFIX_KEEP`
984+
985+
**Note:** Feature settings on different schema elements
986+
[have different scopes](#cascading).
987+
988+
You can set the `strip_enum_prefix` feature in edition 2024 (or newer) .proto
989+
files:
990+
991+
```proto
992+
edition = "2024";
993+
994+
import "third_party/golang/protobuf/v2/src/google/protobuf/go_features.proto";
995+
996+
option features.(pb.go).strip_enum_prefix = STRIP_ENUM_PREFIX_STRIP;
997+
998+
enum Strip {
999+
STRIP_ZERO = 0;
1000+
STRIP_ONE = 1;
1001+
}
1002+
```
1003+
1004+
The generated Go code will now strip the `STRIP` prefix:
1005+
1006+
```go
1007+
type Strip int32
1008+
1009+
const (
1010+
Strip_ZERO Strip = 0
1011+
Strip_ONE Strip = 1
1012+
)
1013+
```
1014+
1015+
## Preserving proto2 or proto3 Behavior in Edition 2023 {#preserving}
9391016

9401017
You may want to move to the editions format but not deal with updates to the way
9411018
that generated code behaves yet. This section shows the changes that the
942-
Prototiller tool makes to your .proto files to make editions-based protos behave
943-
like a proto2 or proto3 file.
1019+
Prototiller tool makes to your .proto files to make edition-2023-based protos
1020+
behave like a proto2 or proto3 file.
9441021

9451022
After these changes are made at the file level, you get the proto2 or proto3
9461023
defaults. You can override at lower levels (message level, field level) to

content/includes/version-tables.css

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,36 +95,36 @@ table.version-chart td.active {
9595
/* latest release column */
9696
/*
9797
* How to advance the selection of the latest release:
98-
* Replace class 'y25q2' in the following selectors with 'y25q3' (the class
98+
* Replace class 'y25q3' in the following selectors with 'y25q4' (the class
9999
* referring to the quarter of the next release). Please also update this
100100
* instruction as a courtesy to the next maintainer.
101101
*/
102102

103103
/* visually replace 'yyQq' heading with string 'Latest' */
104-
table.version-chart th.y25q2 span {
104+
table.version-chart th.y25q3 span {
105105
display: none;
106106
}
107-
table.version-chart th.y25q2::after {
107+
table.version-chart th.y25q3::after {
108108
content: "Latest"
109109
}
110110

111111
/* draw a focus rectangle around the latest release column */
112-
table.version-chart th.y25q2 {
112+
table.version-chart th.y25q3 {
113113
border-top: 2px solid #e06666 !important;
114114
border-left: 2px solid #e06666 !important;
115115
border-right: 2px solid #e06666 !important;
116116
}
117-
table.version-chart td.y25q2 {
117+
table.version-chart td.y25q3 {
118118
font-weight: bold;
119119
border-left: 2px solid #e06666 !important;
120120
border-right: 2px solid #e06666 !important;
121121
}
122-
table.version-chart tr:last-child td.y25q2 {
122+
table.version-chart tr:last-child td.y25q3 {
123123
border-bottom: 2px solid #e06666 !important;
124124
}
125125

126126
/* future release columns */
127-
table.version-chart td:not(:has(~ .y25q2)):not(.y25q2) {
127+
table.version-chart td:not(:has(~ .y25q3)):not(.y25q3) {
128128
font-style: italic;
129129
}
130130

content/programming-guides/proto-limits.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ others.
1515

1616
## Number of Fields {#fields}
1717

18+
All messages are limited to 65,535 fields.
19+
1820
Message with only singular proto fields (such as Boolean):
1921

2022
* ~2100 fields (proto2)

content/programming-guides/proto3.md

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,34 @@ file:
879879
import "myproject/other_protos.proto";
880880
```
881881

882+
The protobuf compiler searches for imported files in a set of directories
883+
specified using the `-I`/`--proto_path` flag. The path given in an `import`
884+
statement is resolved relative to these directories. For more information on
885+
using the compiler, see [Generating Your Classes](#generating).
886+
887+
For example, consider the following directory structure:
888+
889+
```
890+
my_project/
891+
├── protos/
892+
│ ├── main.proto
893+
│ └── common/
894+
│ └── timestamp.proto
895+
```
896+
897+
To use definitions from `timestamp.proto` within `main.proto`, you would run the
898+
compiler from the `my_project` directory and set `--proto_path=protos`. The
899+
`import` statement in `main.proto` would then be:
900+
901+
```proto
902+
// Located in my_project/protos/main.proto
903+
import "common/timestamp.proto";
904+
```
905+
906+
In general you should set the `--proto_path` flag to the highest-level directory
907+
that contains protos. This is often the root of the project, but in this example
908+
it's in a separate `/protos` directory.
909+
882910
By default, you can use definitions only from directly imported `.proto` files.
883911
However, sometimes you may need to move a `.proto` file to a new location.
884912
Instead of moving the `.proto` file directly and updating all the call sites in
@@ -915,12 +943,6 @@ import "old.proto";
915943
// You use definitions from old.proto and new.proto, but not other.proto
916944
```
917945

918-
The protocol compiler searches for imported files in a set of directories
919-
specified on the protocol compiler command line using the `-I`/`--proto_path`
920-
flag. If no flag was given, it looks in the directory in which the compiler was
921-
invoked. In general you should set the `--proto_path` flag to the root of your
922-
project and use fully qualified names for all imports.
923-
924946
### Using proto2 Message Types {#proto2}
925947

926948
It's possible to import
@@ -1739,7 +1761,7 @@ generator plugin for the compiler; you can find this and installation
17391761
instructions in the [golang/protobuf](https://github.com/golang/protobuf/)
17401762
repository on GitHub.
17411763

1742-
The Protocol Compiler is invoked as follows:
1764+
The protobuf compiler is invoked as follows:
17431765

17441766
```sh
17451767
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
+++
2+
title = "Python Comparison"
3+
weight = 751
4+
linkTitle = "Python Comparison"
5+
description = "Describes how Python compares objects."
6+
type = "docs"
7+
+++
8+
9+
Because of how proto data is serialized, you cannot rely on the wire
10+
representation of a proto message instance to determine if its content is the
11+
same as another instance. A subset of the ways that a wire-format proto message
12+
instance can vary include the following:
13+
14+
* The protobuf schema changes in certain ways.
15+
* A map field stores its values in a different order.
16+
* The binary is built with different flags (such as opt vs. debug).
17+
* The protobuf library is updated.
18+
19+
Because of these ways that serialized data can vary, determining equality
20+
involves other methods.
21+
22+
## Comparison Methods {#methods}
23+
24+
You can compare protocol buffer messages for equality using the standard Python
25+
`==` operator. Comparing two objects using the `==` operator compares with
26+
`message.ListFields()`. When testing, you can use `self.assertEqual(msg1,
27+
msg2)`.
28+
29+
Two messages are considered equal if they have the same type and all of their
30+
corresponding fields are equal. The inequality operator `!=` is the exact
31+
inverse of `==`.
32+
33+
Message equality is recursive: for two messages to be equal, any nested messages
34+
must also be equal.
35+
36+
## Field Equality and Presence
37+
38+
The equality check for fields is value-based. For fields with
39+
[explicit presence](#singular-explicit), the presence of a field is also taken
40+
into account.
41+
42+
A field that is explicitly set to its default value is **not** considered equal
43+
to a field that is unset.
44+
45+
For example, consider the following message which has an explicit presence
46+
field:
47+
48+
```proto
49+
edition = "2023";
50+
message MyMessage {
51+
int32 value = 1; // 'explicit' presence by default in Editions
52+
}
53+
```
54+
55+
If you create two instances, one where `value` is unset and one where `value` is
56+
explicitly set to `0`, they will not be equal:
57+
58+
```python
59+
msg1 = MyMessage()
60+
msg2 = MyMessage()
61+
msg2.value = 0
62+
63+
assert not msg1.HasField("value")
64+
assert msg2.HasField("value")
65+
assert msg1 != msg2
66+
```
67+
68+
This same principle applies to sub-message fields: an unset sub-message is not
69+
equal to a sub-message that is present but empty (a default instance of the
70+
sub-message class).
71+
72+
For fields with [implicit presence](#singular-implicit), since presence cannot
73+
be tracked, the field is always compared by its value against the corresponding
74+
field in the other message.
75+
76+
This behavior, where presence is part of the equality check, is different from
77+
how some other languages or protobuf libraries might handle equality, where
78+
unset fields and fields set to their default value are sometimes treated as
79+
equivalent (often for wire-format compatibility). In Python, `==` performs a
80+
stricter check.
81+
82+
## Other Field Types {#other-types}
83+
84+
* **Repeated fields** are equal if they have the same number of elements and
85+
each corresponding element is equal. The order of elements matters.
86+
* **Map fields** are equal if they have the same set of key-value pairs. The
87+
order of pairs does not matter.
88+
* **Floating-point fields** (`float` and `double`) are compared by value. Be
89+
aware of the usual caveats with floating-point comparisons.

0 commit comments

Comments
 (0)