-
Notifications
You must be signed in to change notification settings - Fork 12
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
97 changes: 97 additions & 0 deletions
97
Sources/GRPCProtobuf/Documentation.docc/Articles/Code-generation-with-protoc.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 specify various options to `protoc-gen-grpc-swift-2` via `protoc` using | ||
the `--grpc-swift-2_opt` argument: | ||
|
||
```console | ||
protoc --grpc-swift-2_opt=<OPTION_NAME>=<OPTION_VALUE> --grpc-swift-2_out=. | ||
``` | ||
|
||
You can specify multiple options by repeating the `--grpc-swift-2_opt` argument: | ||
|
||
```console | ||
protoc \ | ||
--grpc-swift-2_opt=<OPTION_NAME1>=<OPTION_VALUE1> \ | ||
--grpc-swift-2_opt=<OPTION_NAME2>=<OPTION_VALUE2> \ | ||
--grpc-swift-2_out=. | ||
``` | ||
|
||
### Generator options | ||
|
||
| Name | Possible Values | Default | Description | | ||
|---------------------------|---------------------------------------------|-----------------|----------------------------------------------------------| | ||
| `Visibility` | `Public`, `Package`, `Internal` | `Internal` | Access level for generated stubs | | ||
| `Server` | `True`, `False` | `True` | Generate server stubs | | ||
| `Client` | `True`, `False` | `True` | Generate client stubs | | ||
| `FileNaming` | `FullPath`, `PathToUnderscores`, `DropPath` | `FullPath` | How generated source files should be named. † | | ||
| `ProtoPathModuleMappings` | | | Path to module map `.asciipb` file. ‡ | | ||
| `UseAccessLevelOnImports` | `True`, `False` | `False` | Whether imports should have explicit access levels. | | ||
| `GRPCModuleName` | | `GRPCCore` | The name of the `GRPCCore` module. | | ||
| `GRPCProtobufModuleName` | | `GRPCProtobuf` | The name of the `GRPCProtobuf` module. | | ||
| `SwiftProtobufModuleName` | | `SwiftProtobuf` | The name of the `SwiftProtobuf` module. | | ||
| `Availability` | String, in the form `OS Version` | | Platform availability to use in generated code. § | | ||
|
||
† The `FileNaming` option has three possible values, for an input of `foo/bar/baz.proto` the following | ||
output file will be generated: | ||
- `FullPath`: `foo/bar/baz.grpc.swift`. | ||
- `PathToUnderscores`: `foo_bar_baz.grpc.swift` | ||
- `DropPath`: `baz.grpc.swift` | ||
|
||
‡ The code generator assumes all inputs are generated into the same module, `ProtoPathModuleMappings` | ||
allows you to specify a mapping from `.proto` files to the Swift module they are generated in. This | ||
allows the code generator to add appropriate imports to your generated stubs. This is described in | ||
more detail in the [SwiftProtobuf documentation](https://github.com/apple/swift-protobuf/blob/main/Documentation/PLUGIN.md). | ||
|
||
§ If unspecified the following availability is used: macOS 15, iOS 18, tvOS 18, | ||
watchOS 11, visionOS 2. The `Availability` option may be specified multiple | ||
times, where each value is a space delimited pair of platform and version, e.g. | ||
`Availability=macOS 15.0`. | ||
|
||
### Building the protoc plugin | ||
|
||
> The version of `protoc-gen-grpc-swift-2` you use mustn't be newer than the version of | ||
> the `grpc-swift-protobuf` you're using. | ||
|
||
If your package depends on `grpc-swift-protobuf` then you can get a copy of `protoc-gen-grpc-swift-2` | ||
by building it directly: | ||
|
||
```console | ||
swift build --product protoc-gen-grpc-swift-2 | ||
``` | ||
|
||
This command will build the plugin into `.build/debug` directory. You can get the full path using | ||
`swift build --show-bin-path`. |
127 changes: 127 additions & 0 deletions
127
...PCProtobuf/Documentation.docc/Articles/Code-generation-with-the-build-plugin.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
80 changes: 80 additions & 0 deletions
80
...Protobuf/Documentation.docc/Articles/Code-generation-with-the-command-plugin.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.