|
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