Schema and codegen
The gRPC toolchain in kotlinx.rpc is schema-first. .proto files are the source of truth, built-in protoc plugins generate Kotlin declarations from them, and the kotlinx.rpc compiler plugin synthesizes the additional declarations required to make those generated files usable from Kotlin code and visible to runtime APIs such as withService, registerService, grpcMarshallerOf, and protoDescriptorOf.
Input schemas
Place schemas in the proto source set directories described on Configuration. A minimal schema can declare both messages and services:
What protoc generates
The built-in protoc plugins are kotlin-multiplatform and grpc-kotlin-multiplatform. They generate source files into the module's build directory.
kotlin-multiplatformgenerates the public protobuf declarations. For a message file this means public message interfaces and enums in the declared package.kotlin-multiplatformalso generates a companion extension file named <FileName>.ext.kt and an internal support file in the _rpc_internal subdirectory.grpc-kotlin-multiplatformgenerates public@Grpcservice interfaces with unary and streaming signatures mapped tosuspendandFlow.
A typical public output for the schema above looks like this:
The companion extension file contains the user-facing builder and copy helpers:
The internal protobuf support file contains the implementation details used by the runtime and should not be used directly.
What the compiler plugin adds
The compiler plugin completes the generated declarations rather than replacing them. Its responsibilities are distinct from the protoc plugins:
- Companion and Builder synthesis
The public message interfaces generated by protoc are annotated with
@GeneratedProtoMessage. The compiler plugin synthesizes the nestedCompanionobject andBuilderinterface that make the generated .ext.kt builder helpers callable from Kotlin code.- Marshaller and descriptor binding
The compiler plugin associates each public generated message type with the corresponding internal
MARSHALLERandDESCRIPTORobjects. That is what makesgrpcMarshallerOf<Message>()andprotoDescriptorOf<Message>()work on the public type.- Service metadata synthesis
For
@Grpcservices, the compiler plugin synthesizes hidden stub metadata used bywithService,registerService, andserviceDescriptorOf.- Declaration validation
The compiler plugin validates generated and handwritten gRPC declarations during compilation.
In practice, the generated API is used like this:
Generated protobuf marshallers use ProtoConfig as their runtime configuration object. The current configuration options are discardUnknownFields, recursionLimit, and extensionRegistry.
Validation rules
The compiler plugin enforces the rules that are required by the current gRPC runtime and generator model.
A gRPC service function has exactly one parameter unless it is a zero-argument unary RPC.
Nullable request and response types are not allowed in
@Grpcservices.Client streaming must be the top-level parameter type. Nested flows inside request objects are rejected.
Overridden proto package names, service names, and method names must be valid protobuf identifiers.
@Grpc.Method(safe = true)also requiresidempotent = true.@GeneratedProtoMessagedeclarations are generator output. Do not write them by hand.