xref: /aosp_15_r20/external/pigweed/docs/style/protobuf.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _docs-pw-style-protobuf:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker==============
4*61c4878aSAndroid Build Coastguard WorkerProtobuf style
5*61c4878aSAndroid Build Coastguard Worker==============
6*61c4878aSAndroid Build Coastguard WorkerThe Pigweed protobuf style guide is closely based on `Google's public
7*61c4878aSAndroid Build Coastguard Workerprotobuf style guide <https://protobuf.dev/programming-guides/style/>`_.
8*61c4878aSAndroid Build Coastguard WorkerThe Google Protobuf Style Guide applies to Pigweed except as described in this
9*61c4878aSAndroid Build Coastguard Workerdocument.
10*61c4878aSAndroid Build Coastguard Worker
11*61c4878aSAndroid Build Coastguard WorkerThe Pigweed protobuf style guide only applies to Pigweed itself. It does not
12*61c4878aSAndroid Build Coastguard Workerapply to projects that use Pigweed or to the third-party code included with
13*61c4878aSAndroid Build Coastguard WorkerPigweed.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker--------
16*61c4878aSAndroid Build Coastguard WorkerEditions
17*61c4878aSAndroid Build Coastguard Worker--------
18*61c4878aSAndroid Build Coastguard WorkerPigweed only allows ``proto3`` (i.e. ``syntax = "proto3";``) at this time.
19*61c4878aSAndroid Build Coastguard Worker``proto2`` is not supported, and the ``edition`` versions (e.g.
20*61c4878aSAndroid Build Coastguard Worker``edition = "2023";``) will be considered when sufficient motivation arises.
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker------
23*61c4878aSAndroid Build Coastguard WorkerNaming
24*61c4878aSAndroid Build Coastguard Worker------
25*61c4878aSAndroid Build Coastguard WorkerProtobuf library structure
26*61c4878aSAndroid Build Coastguard Worker==========================
27*61c4878aSAndroid Build Coastguard WorkerAll protobuf files should live in a ``proto`` subdirectory within their
28*61c4878aSAndroid Build Coastguard Workerrespective modules. This produces an ``import`` path that matches the pattern of
29*61c4878aSAndroid Build Coastguard Worker``[module name]/proto/[proto file].proto``\. If a module exposes multiple proto
30*61c4878aSAndroid Build Coastguard Workerlibraries that need to be grouped separately from a build/distribution
31*61c4878aSAndroid Build Coastguard Workerperspective, additional directories may be introduced that follow the pattern
32*61c4878aSAndroid Build Coastguard Worker``[module name]/[group name]_proto/[proto file].proto``\.
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard WorkerExamples:
35*61c4878aSAndroid Build Coastguard Worker
36*61c4878aSAndroid Build Coastguard Worker* ``pw_log/proto``
37*61c4878aSAndroid Build Coastguard Worker* ``pw_unit_test/proto``
38*61c4878aSAndroid Build Coastguard Worker* ``pw_snapshot/proto``
39*61c4878aSAndroid Build Coastguard Worker* ``pw_snapshot/metadata_proto``
40*61c4878aSAndroid Build Coastguard Worker
41*61c4878aSAndroid Build Coastguard WorkerRationale: This overlays the include paths of native libraries, but introduces
42*61c4878aSAndroid Build Coastguard Worker``proto`` to the enclosing directory hierarchy to make it clearer that generated
43*61c4878aSAndroid Build Coastguard Workerproto libraries are being introduced.
44*61c4878aSAndroid Build Coastguard Worker
45*61c4878aSAndroid Build Coastguard WorkerProtobuf package names
46*61c4878aSAndroid Build Coastguard Worker======================
47*61c4878aSAndroid Build Coastguard WorkerProtobuf library packages should append a ``proto`` suffix to package
48*61c4878aSAndroid Build Coastguard Workernamespaces. If a module exposes multiple proto
49*61c4878aSAndroid Build Coastguard Workerlibraries that need to be grouped separately from a build/distribution
50*61c4878aSAndroid Build Coastguard Workerperspective, a ``*_proto`` suffix may be used instead.
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard WorkerExample:
53*61c4878aSAndroid Build Coastguard Worker
54*61c4878aSAndroid Build Coastguard Worker.. code-block:: protobuf
55*61c4878aSAndroid Build Coastguard Worker   :emphasize-lines: 3
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker   // This lives inside of pw_file.
58*61c4878aSAndroid Build Coastguard Worker
59*61c4878aSAndroid Build Coastguard Worker   package pw.file.proto;
60*61c4878aSAndroid Build Coastguard Worker
61*61c4878aSAndroid Build Coastguard Worker   service FileSystem {
62*61c4878aSAndroid Build Coastguard Worker     // ...
63*61c4878aSAndroid Build Coastguard Worker   }
64*61c4878aSAndroid Build Coastguard Worker
65*61c4878aSAndroid Build Coastguard WorkerRationale: This prevents collisions between generated proto types and
66*61c4878aSAndroid Build Coastguard Workerlanguage-native types.
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard WorkerRPC service names
69*61c4878aSAndroid Build Coastguard Worker=================
70*61c4878aSAndroid Build Coastguard WorkerServices should strive for simple, intuitive, globally unique names, and should
71*61c4878aSAndroid Build Coastguard Worker**not** be suffixed with ``*Service``.
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard WorkerExample:
74*61c4878aSAndroid Build Coastguard Worker
75*61c4878aSAndroid Build Coastguard Worker.. code-block:: protobuf
76*61c4878aSAndroid Build Coastguard Worker   :emphasize-lines: 1
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker   service PwEcho {
79*61c4878aSAndroid Build Coastguard Worker     rpc Echo(EchoRequest) returns (EchoResponse) {}
80*61c4878aSAndroid Build Coastguard Worker   }
81*61c4878aSAndroid Build Coastguard Worker
82*61c4878aSAndroid Build Coastguard WorkerRationale: Pigweed's C++ RPC codegen namespaces services differently than
83*61c4878aSAndroid Build Coastguard Workerregular protos (for example, ``pw::file::pw_rpc::raw::FileSystem::Service``),
84*61c4878aSAndroid Build Coastguard Workerwhich makes it sufficiently clear when a name refers to a service.
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker------
87*61c4878aSAndroid Build Coastguard WorkerTyping
88*61c4878aSAndroid Build Coastguard Worker------
89*61c4878aSAndroid Build Coastguard WorkerUsing ``optional``
90*61c4878aSAndroid Build Coastguard Worker==================
91*61c4878aSAndroid Build Coastguard WorkerWhen presence or absence of a field's value has a semantic meaning, the field
92*61c4878aSAndroid Build Coastguard Workershould be marked as ``optional`` to signal the distinction. Otherwise,
93*61c4878aSAndroid Build Coastguard Worker``optional`` should be omitted. This causes the field to still be optional, but
94*61c4878aSAndroid Build Coastguard Workerindicates that the default value of zero is semantically equivalent to an
95*61c4878aSAndroid Build Coastguard Workerexplicit value of zero.
96*61c4878aSAndroid Build Coastguard Worker
97*61c4878aSAndroid Build Coastguard WorkerExample:
98*61c4878aSAndroid Build Coastguard Worker
99*61c4878aSAndroid Build Coastguard Worker.. code-block:: protobuf
100*61c4878aSAndroid Build Coastguard Worker   :emphasize-lines: 6
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker   message MyRequest {
103*61c4878aSAndroid Build Coastguard Worker     // The maximum number of `foo` entries to return in the response message.
104*61c4878aSAndroid Build Coastguard Worker     // If this is not set, the response may contain as many `foo` entries
105*61c4878aSAndroid Build Coastguard Worker     // as needed. If `max_foo` is zero, no `foo` entries should be included
106*61c4878aSAndroid Build Coastguard Worker     // in the response.
107*61c4878aSAndroid Build Coastguard Worker     optional uint32 max_foo = 1;
108*61c4878aSAndroid Build Coastguard Worker   }
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard WorkerRationale: ``optional`` is very useful for clarifying cases where an implied
111*61c4878aSAndroid Build Coastguard Workerdefault value seems ambiguous, and it also signals codegen for ``has_max_foo``
112*61c4878aSAndroid Build Coastguard Workergetters in various languages.
113*61c4878aSAndroid Build Coastguard Worker
114*61c4878aSAndroid Build Coastguard WorkerUsing ``required``
115*61c4878aSAndroid Build Coastguard Worker==================
116*61c4878aSAndroid Build Coastguard Worker``required`` fields are strictly forbidden within Pigweed.
117*61c4878aSAndroid Build Coastguard Worker
118*61c4878aSAndroid Build Coastguard Worker-----
119*61c4878aSAndroid Build Coastguard WorkerEnums
120*61c4878aSAndroid Build Coastguard Worker-----
121*61c4878aSAndroid Build Coastguard WorkerDefault values
122*61c4878aSAndroid Build Coastguard Worker==============
123*61c4878aSAndroid Build Coastguard WorkerAll enums must have a safe default zero value. Usually this is ``UNKNOWN`` or
124*61c4878aSAndroid Build Coastguard Worker``NONE``, but may be any other semantically similar default.
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard WorkerRationale: Enums are default-initialized to zero, which means that a zero value
127*61c4878aSAndroid Build Coastguard Workerthat conveys anything beyond "unset" may be misleading.
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker.. code-block:: protobuf
130*61c4878aSAndroid Build Coastguard Worker   :emphasize-lines: 5
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard Worker   package pw.chrono.proto;
133*61c4878aSAndroid Build Coastguard Worker
134*61c4878aSAndroid Build Coastguard Worker   message EpochType {
135*61c4878aSAndroid Build Coastguard Worker     enum Enum {
136*61c4878aSAndroid Build Coastguard Worker       UNKNOWN = 0;
137*61c4878aSAndroid Build Coastguard Worker       TIME_SINCE_BOOT = 1;
138*61c4878aSAndroid Build Coastguard Worker       UTC_WALL_CLOCK = 2;
139*61c4878aSAndroid Build Coastguard Worker       GPS_WALL_CLOCK = 3;
140*61c4878aSAndroid Build Coastguard Worker       TAI_WALL_CLOCK = 4;
141*61c4878aSAndroid Build Coastguard Worker     };
142*61c4878aSAndroid Build Coastguard Worker   }
143*61c4878aSAndroid Build Coastguard Worker
144*61c4878aSAndroid Build Coastguard WorkerNamespacing
145*61c4878aSAndroid Build Coastguard Worker===========
146*61c4878aSAndroid Build Coastguard WorkerPrefer to place ``enum`` definitions within a ``message`` to namespace the
147*61c4878aSAndroid Build Coastguard Workergenerated names for the values.
148*61c4878aSAndroid Build Coastguard Worker
149*61c4878aSAndroid Build Coastguard WorkerRationale: Enum value names can easily collide if you don't prefix them (i.e.
150*61c4878aSAndroid Build Coastguard Worker``UNKNOWN`` from one enum will collide with ``UNKNOWN`` from another enum).
151*61c4878aSAndroid Build Coastguard WorkerNamespacing them within a message prevents these collisions.
152*61c4878aSAndroid Build Coastguard Worker
153*61c4878aSAndroid Build Coastguard Worker.. code-block:: protobuf
154*61c4878aSAndroid Build Coastguard Worker   :emphasize-lines: 3, 4
155*61c4878aSAndroid Build Coastguard Worker
156*61c4878aSAndroid Build Coastguard Worker   package pw.chrono.proto;
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard Worker   message EpochType {
159*61c4878aSAndroid Build Coastguard Worker     enum Enum {
160*61c4878aSAndroid Build Coastguard Worker       UNKNOWN = 0;
161*61c4878aSAndroid Build Coastguard Worker       TIME_SINCE_BOOT = 1;
162*61c4878aSAndroid Build Coastguard Worker       UTC_WALL_CLOCK = 2;
163*61c4878aSAndroid Build Coastguard Worker       GPS_WALL_CLOCK = 3;
164*61c4878aSAndroid Build Coastguard Worker       TAI_WALL_CLOCK = 4;
165*61c4878aSAndroid Build Coastguard Worker     };
166*61c4878aSAndroid Build Coastguard Worker   }
167