-
Notifications
You must be signed in to change notification settings - Fork 14
Add more documentation about code generation #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,97 @@ | ||||||
# Code generation with protoc | ||||||
|
||||||
This article describes how to use the Swift Package Manager build plugin to | ||||||
generate gRPC Swift and Swift Protobuf code from your Protocol Buffers `.proto` files. | ||||||
|
||||||
## Overview | ||||||
|
||||||
If you've used Protocol Buffers before then generating gRPC Swift stubs should be simple. If you're | ||||||
unfamiliar with Protocol Buffers then you should get comfortable with the concepts before | ||||||
continuing; the [Protocol Buffers website](https://protobuf.dev/) is a great place to start. | ||||||
|
||||||
If you haven't installed `protoc` yet refer to <doc:Installing-protoc> for | ||||||
instructions. | ||||||
|
||||||
## Using protoc | ||||||
|
||||||
The [`grpc-swift-protobuf`](https://github.com/grpc/grpc-swift-protobuf) package provides | ||||||
`protoc-gen-grpc-swift-2`, a program which is a plugin for the Protocol Buffers compiler, `protoc`. | ||||||
To generate gRPC stubs for your `.proto` files directly you must run the `protoc` command with | ||||||
the `--grpc-swift-2_out=<DIRECTORY>` option: | ||||||
|
||||||
```console | ||||||
protoc --grpc-swift-2_out=. my-service.proto | ||||||
``` | ||||||
|
||||||
> `protoc-gen-grpc-swift-2` only generates gRPC stubs, it doesn't generate messages. You must use | ||||||
> `protoc-gen-swift` to generate messages in addition to gRPC Stubs. | ||||||
|
||||||
The presence of `--grpc-swift-2_out` tells `protoc` to use the `protoc-gen-grpc-swift-2` plugin. By | ||||||
default it'll look for the plugin in your `PATH`. You can also specify the path to the plugin | ||||||
explicitly: | ||||||
|
||||||
```console | ||||||
protoc --plugin=/path/to/protoc-gen-grpc-swift-2 --grpc-swift-2_out=. my-service.proto | ||||||
``` | ||||||
|
||||||
You can also specify various option the `protoc-gen-grpc-swift-2` via `protoc` using | ||||||
|
You can also specify various option the `protoc-gen-grpc-swift-2` via `protoc` using | |
You can specify an option to the `protoc-gen-grpc-swift-2` plugin via `protoc` using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think neither of these are right 😀
glbrntt marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can specify multiple options by passing the `--grpc-swift-2_opt` argument multiple times: | |
You can also specify multiple options by passing the `--grpc-swift-2_opt` argument multiple times: |
glbrntt marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Code generation with the build plugin | ||
|
||
This article describes how to use `protoc` to generate stubs for gRPC Swift and | ||
Swift Protobuf from your Protocol Buffers `.proto` files. | ||
|
||
## Overview | ||
|
||
The build plugin (`GRPCProtobufGenerator`) is a great choice for convenient | ||
dynamic code generation, however it does come with some limitations. Because it | ||
generates the gRPC Swift stubs as part of the build it has the requirement that | ||
`protoc` must be available at compile time. This requirement means it is not a | ||
good fit for library authors who do not have direct control over this. | ||
|
||
To learn more about other options for code generation see <doc:Generating-stubs>. | ||
|
||
The build plugin works by detecting `.proto` files in the source tree and | ||
invokes `protoc` once for each file (caching results and performing the | ||
generation as necessary). | ||
|
||
If you haven't installed `protoc` yet refer to <doc:Installing-protoc> for | ||
instructions. | ||
|
||
### Adoption | ||
|
||
You must adopt Swift Package Manager build plugins on a per-target basis by | ||
modifying your package manifest (`Package.swift` file). To do this, declare the | ||
`grpc-swift-protobuf` package as a dependency and add the plugin to your desired | ||
targets. | ||
|
||
For example, to make use of the plugin for generating gRPC Swift stubs as part | ||
of the `echo-server` target: | ||
|
||
```swift | ||
targets: [ | ||
.executableTarget( | ||
name: "echo-server", | ||
dependencies: [ | ||
// ... | ||
], | ||
plugins: [ | ||
.plugin( | ||
name: "GRPCProtobufGenerator", | ||
package: "grpc-swift-protobuf" | ||
) | ||
] | ||
) | ||
] | ||
``` | ||
|
||
Once this is done you need to ensure that the `.proto` files to be used for | ||
generation are included in the target's source directory and that you have | ||
defined a configuration file. | ||
|
||
## Configuration | ||
|
||
You must provide a configuration file named | ||
`grpc-swift-proto-generator-config.json` in the directory which encloses all | ||
`.proto` files (in the same directory as the files or a parent directory). The | ||
configuration file tells the build plugin about the options used for `protoc` | ||
invocations. | ||
|
||
> Warning: | ||
> The name of the config file is important and must match exactly, the | ||
> plugin won't be applied if it can't find the config file. | ||
|
||
You can use the following as a starting point for your configuration: | ||
|
||
```json | ||
{ | ||
"generate": { | ||
"clients": true, | ||
"servers": true, | ||
"messages": true | ||
} | ||
} | ||
``` | ||
|
||
By default clients, servers, and messages will be generated with the `internal` | ||
access level. | ||
|
||
The full structure of the config file looks like this: | ||
|
||
```json | ||
{ | ||
"generate": { | ||
"clients": true, | ||
"servers": true, | ||
"messages": true | ||
}, | ||
"generatedSource": { | ||
"accessLevelOnImports": false, | ||
"accessLevel": "internal" | ||
}, | ||
"protoc": { | ||
"executablePath": "/opt/homebrew/bin/protoc", | ||
"importPaths": [ | ||
"../directory_1" | ||
] | ||
} | ||
} | ||
``` | ||
|
||
Each of the options are described below: | ||
|
||
| Name | Possible Values | Default | Description | | ||
|----------------------------------------|--------------------------------------------|--------------|-----------------------------------------------------| | ||
| `generate.servers` | `true`, `false` | `true` | Generate server stubs | | ||
| `generate.clients` | `true`, `false` | `true` | Generate client stubs | | ||
| `generate.messages` | `true`, `false` | `true` | Generate message stubs | | ||
| `generatedSource.accessLevelOnImports` | `true`, `false` | `false` | Whether imports should have explicit access levels | | ||
| `generatedSource.accessLevel` | `"public"`, `"package"`, `"internal"` | `"internal"` | Access level for generated stubs | | ||
| `protoc.executablePath` | N/A | `null`† | Path to the `protoc` executable | | ||
| `protoc.importPaths` | N/A | `null`‡ | Import paths passed to `protoc` | | ||
|
||
† The Swift Package Manager build plugin infrastructure will attempt to discover | ||
the executable's location if you don't provide one. | ||
|
||
‡ If you don't provide any import paths then the path to the configuration file | ||
will be used on a per-source-file basis. | ||
|
||
Many of these options map to `protoc-gen-grpc-swift-2` and `protoc-gen-swift` | ||
options. | ||
|
||
If you require greater flexibility you may specify more than one configuration | ||
file. Configuration files apply to all `.proto` files equal to or below it in | ||
the file hierarchy. A configuration file lower in the file hierarchy supersedes | ||
one above it. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Code generation with generate-grpc-code-from-protos | ||
|
||
This article describes how to use the `generate-grpc-code-from-protos` Swift | ||
Package Manager command plugin to generate gRPC Swift and Swift Protobuf code | ||
from your Protocol Buffers `.proto` files. | ||
|
||
This plugin is particularly useful for: | ||
|
||
- **Manual, on-demand code generation:** When you prefer to explicitly generate | ||
code rather than relying on a build tool plugin. | ||
- **Libraries:** For Swift packages intended as libraries, where generated | ||
source code should be checked into your repository to avoid external `protoc` | ||
dependencies for your library's consumers. | ||
|
||
If you haven't installed `protoc` yet refer to <doc:Installing-protoc> for | ||
instructions. | ||
|
||
## Adding the Plugin to Your Package | ||
|
||
To use `generate-grpc-code-from-protos` your package needs to depend on | ||
`grpc-swift-protobuf`. You **don't** need to add a dependency on each target | ||
like you would for the build plugin. | ||
|
||
## Basic Usage | ||
|
||
Once your package depends on `grpc-swift-protobuf` you can invoke it using: | ||
|
||
```sh | ||
swift package generate-grpc-code-from-protos path/to/YourService.proto path/to/YourMessages.proto | ||
``` | ||
|
||
If you've organised your protos within a single directory then you can | ||
pass the path of the directory as an argument instead, the plugin will find | ||
all `.proto` files nested within that directory: | ||
|
||
```sh | ||
swift package generate-grpc-code-from-protos Protos | ||
``` | ||
|
||
By default the plugin generates code for gRPC servers, clients, and Protobuf | ||
messages into the current working directory. To change where the code is | ||
generated you can specify the `--output-path` option: | ||
|
||
|
||
```sh | ||
swift package generate-grpc-code-from-protos --output-path Sources/Generated -- Protos | ||
``` | ||
|
||
> Important: The "`--`" separates options and inputs passed to the plugin. | ||
> | ||
> Everything after "`--`" is treated as an input (a `.proto` file or a | ||
> directory), everything before "`--`" is treated as an option with a value or | ||
> a flag. If there is no "`--`" then all arguments are treated as input. | ||
|
||
You should now have a basic understanding of how to use the plugin. You can | ||
configure how the code is generated via a number of options, a few commonly used | ||
ones are: | ||
- `--no-client` disables client code generation, | ||
- `--no-server` disables server code generation, | ||
- `--no-messages` disables message code generation, | ||
- `--access-level <access>` specifies the access level of the generated code, | ||
(`<access>` must be one of "internal", "package", or "public"). | ||
|
||
You can read about other options by referring to the `--help` text: | ||
|
||
```sh | ||
swift package generate-grpc-code-from-protos --help | ||
``` | ||
|
||
### Permissions | ||
|
||
Swift Package Manager command plugins require permission to create files. You'll | ||
be prompted to give `generate-grpc-code-from-protos` permission when running it. | ||
To avoid being prompted you can grant permissions ahead of time by specifying | ||
`--allow-writing-to-package-directory` to the `swift package` command. For | ||
example: | ||
|
||
```sh | ||
swift package --allow-writing-to-package-directory generate-grpc-code-from-protos Protos | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure about this, but should we maybe put this at the top of this section and slightly rephrase it to something like "you should first make sure you've generated your proto messages by using
protoc-gen-swift
before generating gRPC Stubs?I just feel like if you're completely new to all of this, this paragraph may be confusing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter which order they're generated in, it can be before or after generating gRPC stubs. I think this is in the right place because the paragraph above sets the scene by explaining that we provide a plugin for protoc which generates the gRPC bits. This is just making it more explicit that it only generates the gRPC bits.