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