Skip to content
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

feat(build): Add CodeGenBuilder #1154

Merged
merged 2 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tonic-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license = "MIT"
name = "tonic-build"
readme = "README.md"
repository = "https://github.com/hyperium/tonic"
version = "0.8.2"
version = "0.8.3"

[dependencies]
prettyplease = { version = "0.1" }
Expand Down
20 changes: 20 additions & 0 deletions tonic-build/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,33 @@ use quote::{format_ident, quote};
///
/// This takes some `Service` and will generate a `TokenStream` that contains
/// a public module with the generated client.
#[deprecated(since = "0.8.3", note = "Use the CodeGenBuilder::generate_client")]
pub fn generate<T: Service>(
service: &T,
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
build_transport: bool,
attributes: &Attributes,
) -> TokenStream {
generate_internal(
service,
emit_package,
proto_path,
compile_well_known_types,
build_transport,
attributes,
&HashSet::default(),
)
}

pub(crate) fn generate_internal<T: Service>(
service: &T,
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
build_transport: bool,
attributes: &Attributes,
disable_comments: &HashSet<String>,
) -> TokenStream {
let service_ident = quote::format_ident!("{}Client", service.name());
Expand Down
102 changes: 102 additions & 0 deletions tonic-build/src/code_gen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use std::collections::HashSet;

use proc_macro2::TokenStream;

use crate::{Attributes, Service};

/// Builder for the generic code generation of server and clients.
#[derive(Debug)]
pub struct CodeGen8uilder {
emit_package: bool,
compile_well_known_types: bool,
attributes: Attributes,
build_transport: bool,
disable_comments: HashSet<String>,
}

impl CodeGen8uilder {
/// Create a new code gen builder with default options.
pub fn new() -> Self {
Default::default()
}

/// Enable code generation to emit the package name.
pub fn emit_package(&mut self, enable: bool) -> &mut Self {
self.emit_package = enable;
self
}

/// Attributes that will be added to `mod` and `struct` items.
///
/// Reference [`Attributes`] for more information.
pub fn attributes(&mut self, attributes: Attributes) -> &mut Self {
self.attributes = attributes;
self
}

/// Enable transport code to be generated, this requires `tonic`'s `transport`
/// feature.
///
/// This allows codegen level control of generating the transport code and
/// is a work around when other crates in a workspace enable this feature.
pub fn build_transport(&mut self, build_transport: bool) -> &mut Self {
self.build_transport = build_transport;
self
}

/// Enable compiling well knonw types, this will force codegen to not
/// use the well known types from `prost-types`.
pub fn compile_well_known_types(&mut self, enable: bool) -> &mut Self {
self.compile_well_known_types = enable;
self
}

/// Disable comments based on a proto path.
pub fn disable_comments(&mut self, disable_comments: HashSet<String>) -> &mut Self {
self.disable_comments = disable_comments;
self
}

/// Generate client code based on `Service`.
///
/// This takes some `Service` and will generate a `TokenStream` that contains
/// a public module with the generated client.
pub fn generate_client(&self, service: &impl Service, proto_path: &str) -> TokenStream {
crate::client::generate_internal(
service,
self.emit_package,
proto_path,
self.compile_well_known_types,
self.build_transport,
&self.attributes,
&self.disable_comments,
)
}

/// Generate server code based on `Service`.
///
/// This takes some `Service` and will generate a `TokenStream` that contains
/// a public module with the generated client.
pub fn generate_server(&self, service: &impl Service, proto_path: &str) -> TokenStream {
crate::server::generate_internal(
service,
self.emit_package,
proto_path,
self.compile_well_known_types,
&self.attributes,
&self.disable_comments,
)
}
}

impl Default for CodeGen8uilder {
fn default() -> Self {
Self {
emit_package: true,
compile_well_known_types: false,
attributes: Attributes::default(),
build_transport: true,
disable_comments: HashSet::default(),
}
}
}
3 changes: 3 additions & 0 deletions tonic-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ pub mod client;
/// Service code generation for Server
pub mod server;

mod code_gen;
pub use code_gen::CodeGen8uilder;

/// Service generation trait.
///
/// This trait can be implemented and consumed
Expand Down
32 changes: 13 additions & 19 deletions tonic-build/src/manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
//! }
//! ```

use super::{client, server, Attributes};
use crate::code_gen::CodeGen8uilder;

use proc_macro2::TokenStream;
use quote::ToTokens;
use std::{
collections::HashSet,
fs,
path::{Path, PathBuf},
};
Expand Down Expand Up @@ -352,27 +352,21 @@ struct ServiceGenerator {
impl ServiceGenerator {
fn generate(&mut self, service: &Service) {
if self.builder.build_server {
let server = server::generate(
service,
true, // emit_package,
"", // proto_path, -- not used
false, // compile_well_known_types -- not used
&Attributes::default(),
&HashSet::default(),
);
let server = CodeGen8uilder::new()
.emit_package(true)
.compile_well_known_types(false)
.generate_server(service, "");

self.servers.extend(server);
}

if self.builder.build_client {
let client = client::generate(
service,
true, // emit_package,
"", // proto_path, -- not used
false, // compile_well_known_types, -- not used
self.builder.build_transport,
&Attributes::default(),
&HashSet::default(),
);
let client = CodeGen8uilder::new()
.emit_package(true)
.compile_well_known_types(false)
.build_transport(self.builder.build_transport)
.generate_client(service, "");

self.clients.extend(client);
}
}
Expand Down
36 changes: 18 additions & 18 deletions tonic-build/src/prost.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::{client, server, Attributes};
use crate::code_gen::CodeGen8uilder;

use super::Attributes;
use proc_macro2::TokenStream;
use prost_build::{Config, Method, Service};
use quote::ToTokens;
Expand Down Expand Up @@ -159,27 +161,25 @@ impl ServiceGenerator {
impl prost_build::ServiceGenerator for ServiceGenerator {
fn generate(&mut self, service: prost_build::Service, _buf: &mut String) {
if self.builder.build_server {
let server = server::generate(
&service,
self.builder.emit_package,
&self.builder.proto_path,
self.builder.compile_well_known_types,
&self.builder.server_attributes,
&self.builder.disable_comments,
);
let server = CodeGen8uilder::new()
.emit_package(self.builder.emit_package)
.compile_well_known_types(self.builder.compile_well_known_types)
.attributes(self.builder.server_attributes.clone())
.disable_comments(self.builder.disable_comments.clone())
.generate_server(&service, &self.builder.proto_path);

self.servers.extend(server);
}

if self.builder.build_client {
let client = client::generate(
&service,
self.builder.emit_package,
&self.builder.proto_path,
self.builder.compile_well_known_types,
self.builder.build_transport,
&self.builder.client_attributes,
&self.builder.disable_comments,
);
let client = CodeGen8uilder::new()
.emit_package(self.builder.emit_package)
.compile_well_known_types(self.builder.compile_well_known_types)
.attributes(self.builder.client_attributes.clone())
.disable_comments(self.builder.disable_comments.clone())
.build_transport(self.builder.build_transport)
.generate_client(&service, &self.builder.proto_path);

self.clients.extend(client);
}
}
Expand Down
18 changes: 18 additions & 0 deletions tonic-build/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,30 @@ use syn::{Ident, Lit, LitStr};
///
/// This takes some `Service` and will generate a `TokenStream` that contains
/// a public module containing the server service and handler trait.
#[deprecated(since = "0.8.3", note = "Use CodeGenBuilder::generate_server")]
pub fn generate<T: Service>(
service: &T,
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
attributes: &Attributes,
) -> TokenStream {
generate_internal(
service,
emit_package,
proto_path,
compile_well_known_types,
attributes,
&HashSet::default(),
)
}

pub(crate) fn generate_internal<T: Service>(
service: &T,
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
attributes: &Attributes,
disable_comments: &HashSet<String>,
) -> TokenStream {
let methods = generate_methods(service, proto_path, compile_well_known_types);
Expand Down