From cc84beeb7e4091de35e487ba2849c53f37290217 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Sat, 26 Mar 2022 16:42:30 +0100 Subject: [PATCH 1/2] Expose Prost generation plugin Exposing such plugin allows independent code generators (outside of the vanilla `build.rs` workflow) to use tonic-build to get gRPC code generation. This paves the way for a `protoc-gen-tonic` plugin, opening integration in e.g. buf. --- tonic-build/src/lib.rs | 2 +- tonic-build/src/prost.rs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tonic-build/src/lib.rs b/tonic-build/src/lib.rs index 385051419..beb032f57 100644 --- a/tonic-build/src/lib.rs +++ b/tonic-build/src/lib.rs @@ -77,7 +77,7 @@ mod prost; #[cfg(feature = "prost")] #[cfg_attr(docsrs, doc(cfg(feature = "prost")))] -pub use prost::{compile_protos, configure, Builder}; +pub use prost::{compile_protos, configure, Builder, ServiceGenerator}; /// Service code generation for client pub mod client; diff --git a/tonic-build/src/prost.rs b/tonic-build/src/prost.rs index d5a1b2789..78300a959 100644 --- a/tonic-build/src/prost.rs +++ b/tonic-build/src/prost.rs @@ -133,14 +133,22 @@ fn is_google_type(ty: &str) -> bool { ty.starts_with(".google.protobuf") } -struct ServiceGenerator { +/// A service generator compatible with `prost_build`'s one, to extend its code generator. +/// +/// This is used internally by Tonic build, but also when the codegen output is not to be handled +/// by prost or tonic; e.g. such as in a flow for a `protoc` code generation plugin. When compiling +/// as part of a `build.rs` file, instead use [`compile_protos()`]. +#[derive(Debug)] +pub struct ServiceGenerator { builder: Builder, clients: TokenStream, servers: TokenStream, } impl ServiceGenerator { - fn new(builder: Builder) -> Self { + /// Create a new service generator from a configured builder, ready to be passed to + /// `prost_build`'s `Config::service_generator`. + pub fn new(builder: Builder) -> Self { ServiceGenerator { builder, clients: TokenStream::default(), From afb68eba54500d5d86bd46d6f531904c789270b0 Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Thu, 31 Mar 2022 10:25:51 +0200 Subject: [PATCH 2/2] build: Replace the pub service generator struct with a getter This simplifies the code as it allows to simply write `configure() /* opts */ .service_generator()`. --- tonic-build/src/lib.rs | 2 +- tonic-build/src/prost.rs | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tonic-build/src/lib.rs b/tonic-build/src/lib.rs index beb032f57..385051419 100644 --- a/tonic-build/src/lib.rs +++ b/tonic-build/src/lib.rs @@ -77,7 +77,7 @@ mod prost; #[cfg(feature = "prost")] #[cfg_attr(docsrs, doc(cfg(feature = "prost")))] -pub use prost::{compile_protos, configure, Builder, ServiceGenerator}; +pub use prost::{compile_protos, configure, Builder}; /// Service code generation for client pub mod client; diff --git a/tonic-build/src/prost.rs b/tonic-build/src/prost.rs index 78300a959..303f1c2df 100644 --- a/tonic-build/src/prost.rs +++ b/tonic-build/src/prost.rs @@ -133,22 +133,14 @@ fn is_google_type(ty: &str) -> bool { ty.starts_with(".google.protobuf") } -/// A service generator compatible with `prost_build`'s one, to extend its code generator. -/// -/// This is used internally by Tonic build, but also when the codegen output is not to be handled -/// by prost or tonic; e.g. such as in a flow for a `protoc` code generation plugin. When compiling -/// as part of a `build.rs` file, instead use [`compile_protos()`]. -#[derive(Debug)] -pub struct ServiceGenerator { +struct ServiceGenerator { builder: Builder, clients: TokenStream, servers: TokenStream, } impl ServiceGenerator { - /// Create a new service generator from a configured builder, ready to be passed to - /// `prost_build`'s `Config::service_generator`. - pub fn new(builder: Builder) -> Self { + fn new(builder: Builder) -> Self { ServiceGenerator { builder, clients: TokenStream::default(), @@ -420,10 +412,16 @@ impl Builder { config.protoc_arg(arg); } - config.service_generator(Box::new(ServiceGenerator::new(self))); + config.service_generator(self.service_generator()); config.compile_protos(protos, includes)?; Ok(()) } + + /// Turn the builder into a `ServiceGenerator` ready to be passed to `prost-build`s + /// `Config::service_generator`. + pub fn service_generator(self) -> Box { + Box::new(ServiceGenerator::new(self)) + } }