22id : 4210
33state : approved
44created : 2018-06-22
5+ js_scripts :
6+ - /assets/js/graphviz/viz.js
7+ - /assets/js/graphviz/lite.render.js
8+ - /assets/js/aip/aip-graphviz.js
59---
610
711# Client library generators
@@ -31,25 +35,87 @@ expectation.
3135
3236## Guidance
3337
38+ The general flow of code generation for client libraries and supporting code in
39+ most supported languages is outlined below.
40+
41+ ** Note:** Exceptions to this pattern are typically due to use of a unique stack
42+ e.g. Node.js use of ` protobuf.js ` and ` grpc-node ` which don't have code
43+ generation, or Python using a protobuf wrapper in ` proto-plus-python ` , but the
44+ general GAPIC flow remains the same.
45+
46+ ``` graphviz
47+ digraph {
48+ node [ style="filled,solid" shape=box fontname="Roboto" ];
49+ splines=ortho;
50+ nodesep=0.3;
51+ center=true;
52+
53+ proto [ label="API Protobuf\nDescriptors" shape=rectancle fillcolor=aliceblue ];
54+
55+ subgraph cluster_code_generators {
56+ rank = same;
57+ style = filled;
58+ fillcolor = lightgrey;
59+ node [ shape=oval ];
60+
61+ protobuf [ label="protobuf\ngenerator" fillcolor=deepskyblue3 ];
62+ grpc [ label="gRPC\ngenerator" fillcolor=gold3 ];
63+ gapic [ label="GAPIC\ngenerator" fillcolor=darkseagreen ];
64+ }
65+
66+ proto -> protobuf;
67+ proto -> grpc;
68+ proto -> gapic;
69+
70+ subgraph cluster_generated_code {
71+ rank = same;
72+ style = filled;
73+ fillcolor = lightgrey;
74+ node [ shape=rectangle ];
75+
76+ protobuf_output [ label="Message & Enum\nCode" fillcolor=deepskyblue3 ];
77+ grpc_output [ label="Server & Client\nStubs" fillcolor=gold3 ];
78+ gapic_output [ label="Google API\nClient" fillcolor=darkseagreen ];
79+ }
80+
81+ protobuf -> protobuf_output;
82+ grpc -> grpc_output;
83+ gapic -> gapic_output;
84+
85+ assembly [ label="Package\nassembly" shape=oval fillcolor=aliceblue ];
86+
87+ protobuf_output -> assembly
88+ grpc_output -> assembly
89+ gapic_output -> assembly
90+
91+ assembled_package [ label="Package of\ngenerated code" fillcolor=aliceblue ];
92+
93+ assembly -> assembled_package
94+ }
95+ ```
96+
97+ The following sections focus on the "GAPIC generator" in the above diagram.
98+
3499### Protobuf plugins
35100
36- Code generators ** must** be implemented as plugins to ` protoc ` , the protocol
37- buffer compiler. The [ plugin system] [ 0 ] allows plugins to be written in any
38- language, and plugins ** should** ordinarily be written in the language being
39- targeted, in order to take advantage of in-language tooling, and to ensure that
40- experts in the target environment are able to meaningfully contribute.
101+ The protobuf compiler, ` protoc ` , supports a [ plugin system] [ 0 ] for code
102+ generation. The plugin system allows plugins to be written _ in_ and _ for_ any
103+ language.
104+
105+ Code generators ** must** be implemented as ` protoc ` plugins. The following
106+ rules apply to the implementation of a client library generator as a ` protoc `
107+ plugin:
41108
109+ - The plugin ** should** be written in the language being targeted for
110+ generation.
42111- ` protoc ` expects plugins to be an executable in ` $PATH ` , and named
43112 ` protoc-gen-{plugin_name} ` , corresponding to the ` --{plugin_name}_out ` option
44- sent to the ` protoc ` executable.
45- - For a plugin creating client libraries for a specific language, the option
46- name ** should** follow the convention ` --{lang}_gapic_out ` (meaning the
47- corresponding plugin executable is named ` protoc-gen-{lang}_gapic ` ).
48- - Plugins ** must** accept a serialized ` CodeGeneratorRequest ` object (defined
49- in [ ` plugin.proto ` ] [ 1 ] ) on ` stdin ` ; the bulk of this is a series of
50- ` FileDescriptorProto ` messages (defined in [ ` descriptor.proto ` ] [ 2 ] ).
51- - Plugins ** must** emit a serialized ` CodeGeneratorResponse ` object (defined in
52- [ ` plugin.proto ` ] [ 1 ] ) on ` stdout ` .
113+ sent to the ` protoc ` executable. As such:
114+ - the plugin executable ** should** be named ` protoc-gen-{lang}_gapic `
115+ - the plugin option ** should** follow the convention ` --{lang}_gapic_out `
116+ - The plugin ** must not** leverage ` protoc ` "insertion points". Despite the
117+ ` protoc ` plugin documentation indicating the existence of insertion points,
118+ their use is unsupported and discouraged by the Protobuf team.
53119
54120### CLI options
55121
@@ -59,6 +125,10 @@ options are required, `protoc` allows them to be passed as
59125` --{plugin_name}_opt ` , and the string provided here becomes set as the
60126` parameter ` string on the ` CodeGeneratorRequest ` .
61127
128+ ** Important:** The ` CodeGeneratorRequest.parameter ` value is a comma-delimited
129+ string of _ all_ associated plugin option values that appear at execution time.
130+ This means that commas cannot be used to delimit list-like plugin option values.
131+
62132Code generators ** must not** rely on environment variables for configuration.
63133
64134## Expected behavior
@@ -68,6 +138,12 @@ client library generator (in other words: the libraries that the generators
68138write). Client libraries ** must** implement these concepts in order to be
69139considered complete.
70140
141+ ### Messages and Enums
142+
143+ Client library generators ** should not** generate code for ` message ` or ` enum `
144+ descriptors which are already generated by the Protobuf-provided code
145+ generators.
146+
71147### Services and methods
72148
73149Each of the ` service ` and ` rpc ` directives in the requested protos ** must** be
@@ -96,10 +172,12 @@ methods for each RPC.
96172- Finally, service classes ** must** also accept credentials, which are used
97173 appropriately when requests are made. (Accepting a custom gRPC channel
98174 satisfies this requirement.)
175+ - Code generators ** must not** generate client _ stub_ classes, that would
176+ normally be generated by gRPC, in addition to client library classes.
99177
100178### Long-running operations
101179
102- <!-- TODO(b/126177694 ): Reference the LRO AIP once we have it . -->
180+ <!-- TODO(1145 ): Move to its own client library AIP . -->
103181
104182An RPC is considered to be a "long-running" RPC if (and only if) the RPC's
105183return type is [ ` google.longrunning.Operation ` ] [ 3 ] . Any API which has one or
@@ -135,11 +213,16 @@ in the [`MethodDescriptorProto`][6] message using the `client_streaming` and
135213` server_streaming ` keys.
136214
137215<!-- prettier-ignore-start -->
138- [ 0 ] : https://developers.google.com/protocol-buffers/docs /reference/other
216+ [ 0 ] : https://protobuf.dev /reference/other
139217[ 1 ] : https://github.com/google/protobuf/blob/master/src/google/protobuf/compiler/plugin.proto
140218[ 2 ] : https://github.com/google/protobuf/blob/master/src/google/protobuf/descriptor.proto
141219[ 3 ] : https://github.com/googleapis/googleapis/blob/master/google/longrunning/operations.proto#L122
142220[ 4 ] : https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto
143221[ 5 ] : https://github.com/googleapis/googleapis/blob/master/google/longrunning/operations.proto#L222
144222[ 6 ] : https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto#L269
145223<!-- prettier-ignore-end -->
224+
225+ ## Changelog
226+
227+ - ** 2023-06-22** : Added code gen diagram, message/enum guidance, and cleaned up
228+ plugin & option guidance.
0 commit comments