|
1 |
| -# Generating stubs |
| 1 | +# Generating stubs with gRPC Swift Protobuf |
2 | 2 |
|
3 | 3 | Learn how to generate stubs for gRPC Swift from a service defined using the Protocol Buffers IDL.
|
4 | 4 |
|
5 | 5 | ## Overview
|
6 | 6 |
|
7 |
| -If you've used Protocol Buffers before then generating gRPC Swift stubs should be simple. If you're |
8 |
| -unfamiliar with Protocol Buffers then you should get comfortable with the concepts before |
9 |
| -continuing; the [Protocol Buffers website](https://protobuf.dev/) is a great place to start. |
10 |
| - |
11 |
| -You can use the `protoc` plugin from the command line directly, or you can make use of a |
12 |
| - [Swift Package Manager build plugin](https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/Plugins.md) |
13 |
| -convenience which adds the stub generation to the Swift build graph. |
14 |
| -You may use the build plugin either from the command line or from Xcode. |
15 |
| - |
16 |
| -## Using the build plugin |
17 |
| - |
18 |
| -The build plugin (`GRPCProtobufGenerator`) is a great choice for convenient dynamic code generation, however it does come with some limitations. |
19 |
| -Because it generates the gRPC Swift stubs as part of the build it has the requirement that `protoc` must be available |
20 |
| -at compile time. This requirement means it is not a good fit for library authors who do not have |
21 |
| -direct control over this. |
22 |
| - |
23 |
| -The build plugin detects `.proto` files in the source tree and invokes `protoc` once for each file |
24 |
| -(caching results and performing the generation as necessary). |
25 |
| - |
26 |
| -### Adoption |
27 |
| -You must adopt Swift Package Manager build plugins on a per-target basis by modifying your package manifest |
28 |
| -(`Package.swift` file). To do this, declare the grpc-swift-protobuf package as a dependency and add the plugin |
29 |
| -to your desired targets. |
30 |
| - |
31 |
| -For example, to make use of the plugin for generating gRPC Swift stubs as part of the |
32 |
| -`echo-server` target: |
33 |
| -```swift |
34 |
| -targets: [ |
35 |
| - .executableTarget( |
36 |
| - name: "echo-server", |
37 |
| - dependencies: [ |
38 |
| - // ... |
39 |
| - ], |
40 |
| - plugins: [ |
41 |
| - .plugin(name: "GRPCProtobufGenerator", package: "grpc-swift-protobuf") |
42 |
| - ] |
43 |
| - ) |
44 |
| - ] |
45 |
| -``` |
46 |
| -Once this is done you need to ensure that the `.proto` files to be used for generation |
47 |
| -are included in the target's source directory and that you have defined at least one configuration file. |
48 |
| - |
49 |
| -### Configuration |
50 |
| - |
51 |
| -You must provide a configuration file in the directory which encloses all `.proto` files (in the same directory or a parent). |
52 |
| -Configuration files, written in JSON, tell the build plugin about the options used for `protoc` invocations. |
53 |
| -You must name the file `grpc-swift-proto-generator-config.json` and structure it in the following format: |
54 |
| -```json |
55 |
| -{ |
56 |
| - "generate": { |
57 |
| - "clients": true, |
58 |
| - "servers": true, |
59 |
| - "messages": true, |
60 |
| - }, |
61 |
| - "generatedSource": { |
62 |
| - "accessLevelOnImports": false, |
63 |
| - "accessLevel": "internal", |
64 |
| - } |
65 |
| - "protoc": { |
66 |
| - "executablePath": "/opt/homebrew/bin/protoc" |
67 |
| - "importPaths": [ |
68 |
| - "../directory_1", |
69 |
| - ], |
70 |
| - }, |
71 |
| -} |
72 |
| -``` |
73 |
| - |
74 |
| -The options do not need to be specified and each have default values. |
75 |
| - |
76 |
| -| Name | Possible Values | Default | Description | |
77 |
| -|----------------------------------------|--------------------------------------------|--------------|-----------------------------------------------------| |
78 |
| -| `generate.servers` | `true`, `false` | `true` | Generate server stubs | |
79 |
| -| `generate.clients` | `true`, `false` | `true` | Generate client stubs | |
80 |
| -| `generate.messages` | `true`, `false` | `true` | Generate message stubs | |
81 |
| -| `generatedSource.accessLevelOnImports` | `true`, `false` | `false` | Whether imports should have explicit access levels | |
82 |
| -| `generatedSource.accessLevel` | `"public"`, `"package"`, `"internal"` | `"internal"` | Access level for generated stubs | |
83 |
| -| `protoc.executablePath` | N/A | `null`† | Path to the `protoc` executable | |
84 |
| -| `protoc.importPaths` | N/A | `null`‡ | Import paths passed to `protoc` | |
85 |
| - |
86 |
| -† The Swift Package Manager build plugin infrastructure will attempt to discover the executable's location if you don't provide one. |
87 |
| - |
88 |
| -‡ If you don't provide any import paths then the path to the configuration file will be used on a per-source-file basis. |
89 |
| - |
90 |
| -Many of these options map to `protoc-gen-grpc-swift` and `protoc-gen-swift` options. |
91 |
| - |
92 |
| -If you require greater flexibility you may specify more than one configuration file. |
93 |
| -Configuration files apply to all `.proto` files equal to or below it in the file hierarchy. A configuration file |
94 |
| -lower in the file hierarchy supersedes one above it. |
95 |
| - |
96 |
| -### Using protoc |
97 |
| - |
98 |
| -The [`grpc-swift-protobuf`](https://github.com/grpc/grpc-swift-protobuf) package provides |
99 |
| -`protoc-gen-grpc-swift`, a program which is a plugin for the Protocol Buffers compiler, `protoc`. |
100 |
| -To generate gRPC stubs for your `.proto` files directly you must run the `protoc` command with |
101 |
| -the `--grpc-swift_out=<DIRECTORY>` option: |
102 |
| - |
103 |
| -```console |
104 |
| -protoc --grpc-swift_out=. my-service.proto |
105 |
| -``` |
106 |
| - |
107 |
| -> `protoc-gen-grpc-swift` only generates gRPC stubs, it doesn't generate messages. You must use |
108 |
| -> `protoc-gen-swift` to generate messages in addition to gRPC Stubs. |
109 |
| -
|
110 |
| -The presence of `--grpc-swift_out` tells `protoc` to use the `protoc-gen-grpc-swift` plugin. By |
111 |
| -default it'll look for the plugin in your `PATH`. You can also specify the path to the plugin |
112 |
| -explicitly: |
113 |
| - |
114 |
| -```console |
115 |
| -protoc --plugin=/path/to/protoc-gen-grpc-swift --grpc-swift_out=. my-service.proto |
116 |
| -``` |
117 |
| - |
118 |
| -You can also specify various option the `protoc-gen-grpc-swift` via `protoc` using |
119 |
| -the `--grpc-swift_opt` argument: |
120 |
| - |
121 |
| -```console |
122 |
| -protoc --grpc-swift_opt=<OPTION_NAME>=<OPTION_VALUE> --grpc-swift_out=. |
123 |
| -``` |
124 |
| - |
125 |
| -You can specify multiple options by passing the `--grpc-swift_opt` argument multiple times: |
126 |
| - |
127 |
| -```console |
128 |
| -protoc \ |
129 |
| - --grpc-swift_opt=<OPTION_NAME1>=<OPTION_VALUE1> \ |
130 |
| - --grpc-swift_opt=<OPTION_NAME2>=<OPTION_VALUE2> \ |
131 |
| - --grpc-swift_out=. |
132 |
| -``` |
133 |
| - |
134 |
| -#### Generator options |
135 |
| - |
136 |
| -| Name | Possible Values | Default | Description | |
137 |
| -|---------------------------|--------------------------------------------|------------|----------------------------------------------------------| |
138 |
| -| `Visibility` | `Public`, `Package`, `Internal` | `Internal` | Access level for generated stubs | |
139 |
| -| `Server` | `True`, `False` | `True` | Generate server stubs | |
140 |
| -| `Client` | `True`, `False` | `True` | Generate client stubs | |
141 |
| -| `FileNaming` | `FullPath`, `PathToUnderscore`, `DropPath` | `FullPath` | How generated source files should be named. (See below.) | |
142 |
| -| `ProtoPathModuleMappings` | | | Path to module map `.asciipb` file. (See below.) | |
143 |
| -| `UseAccessLevelOnImports` | `True`, `False` | `False` | Whether imports should have explicit access levels. | |
144 |
| - |
145 |
| -The `FileNaming` option has three possible values, for an input of `foo/bar/baz.proto` the following |
146 |
| -output file will be generated: |
147 |
| -- `FullPath`: `foo/bar/baz.grpc.swift`. |
148 |
| -- `PathToUnderscore`: `foo_bar_baz.grpc.swift` |
149 |
| -- `DropPath`: `baz.grpc.swift` |
150 |
| - |
151 |
| -The code generator assumes all inputs are generated into the same module, `ProtoPathModuleMappings` |
152 |
| -allows you to specify a mapping from `.proto` files to the Swift module they are generated in. This |
153 |
| -allows the code generator to add appropriate imports to your generated stubs. This is described in |
154 |
| -more detail in the [SwiftProtobuf documentation](https://github.com/apple/swift-protobuf/blob/main/Documentation/PLUGIN.md). |
155 |
| - |
156 |
| -#### Building the protoc plugin |
157 |
| - |
158 |
| -> The version of `protoc-gen-grpc-swift` you use mustn't be newer than the version of |
159 |
| -> the `grpc-swift-protobuf` you're using. |
160 |
| -
|
161 |
| -If your package depends on `grpc-swift-protobuf` then you can get a copy of `protoc-gen-grpc-swift` |
162 |
| -by building it directly: |
163 |
| - |
164 |
| -```console |
165 |
| -swift build --product protoc-gen-grpc-swift |
166 |
| -``` |
167 |
| - |
168 |
| -This command will build the plugin into `.build/debug` directory. You can get the full path using |
169 |
| -`swift build --show-bin-path`. |
| 7 | +You can learn about generating gRPC stubs from the [gRPC Swift Protobuf |
| 8 | +documentation](https://swiftpackageindex.com/grpc/grpc-swift-protobuf/documentation/grpcprotobuf/generating-stubs). |
0 commit comments