Skip to content

Commit

Permalink
Add disable_comments option
Browse files Browse the repository at this point in the history
  • Loading branch information
bouzuya committed Nov 5, 2022
1 parent 1f5bc9b commit 3659c6d
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -8,6 +8,7 @@ members = [
"tonic-web", # Non-published crates
"examples",
"interop", # Tests
"tests/disable_comments",
"tests/included_service",
"tests/same_name",
"tests/service_named_service",
Expand Down
1 change: 1 addition & 0 deletions tests/disable_comments/.gitignore
@@ -0,0 +1 @@
/src/generated/
17 changes: 17 additions & 0 deletions tests/disable_comments/Cargo.toml
@@ -0,0 +1,17 @@
[package]
authors = ["bouzuya <m@bouzuya.net>"]
edition = "2018"
license = "MIT"
name = "disable-comments"
publish = false
version = "0.1.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
prost = "0.11"
tonic = {path = "../../tonic"}

[build-dependencies]
prost-build = "0.11"
tonic-build = {path = "../../tonic-build"}
18 changes: 18 additions & 0 deletions tests/disable_comments/build.rs
@@ -0,0 +1,18 @@
use std::{fs, path::PathBuf};

fn main() {
let out_dir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR"))
.join("src")
.join("generated");
fs::create_dir_all(out_dir.as_path()).unwrap();
let mut config = prost_build::Config::default();
config.disable_comments(&["test.Input1", "test.Output1"]);
tonic_build::configure()
.disable_comments("test.Service1")
.disable_comments("test.Service1.Rpc1")
.build_client(true)
.build_server(true)
.out_dir(format!("{}", out_dir.display()))
.compile_with_config(config, &["proto/test.proto"], &["proto"])
.unwrap();
}
29 changes: 29 additions & 0 deletions tests/disable_comments/proto/test.proto
@@ -0,0 +1,29 @@
syntax = "proto3";

package test;

// This comment will be removed.
service Service1 {
// This comment will be removed.
rpc Rpc1(Input1) returns (Output1);
// This comment will not be removed.
rpc Rpc2(Input2) returns (Output2);
}

// This comment will not be removed.
service Service2 {
// This comment will not be removed.
rpc Rpc(Input1) returns (Output1);
}

// This comment will be removed.
message Input1 {}

// This comment will not be removed.
message Input2 {}

// This comment will be removed.
message Output1 {}

// This comment will not be removed.
message Output2 {}
3 changes: 3 additions & 0 deletions tests/disable_comments/src/lib.rs
@@ -0,0 +1,3 @@
pub mod pb {
include!("generated/test.rs");
}
18 changes: 18 additions & 0 deletions tests/disable_comments/tests/disable_comments.rs
@@ -0,0 +1,18 @@
use std::{fs, path::PathBuf};

#[test]
fn test() {
let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR"))
.join("src")
.join("generated")
.join("test.rs");
let s = fs::read_to_string(path).unwrap();
assert!(!s.contains("This comment will be removed."));
let mut count = 0_usize;
let mut index = 0_usize;
while let Some(found) = s[index..].find("This comment will not be removed.") {
index += found + 1;
count += 1;
}
assert_eq!(count, 2 + 3 + 3); // message: 2, client: 3, server: 3
}
29 changes: 26 additions & 3 deletions tonic-build/src/client.rs
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use super::{Attributes, Method, Service};
use crate::{generate_doc_comments, naive_snake_case};
use proc_macro2::TokenStream;
Expand All @@ -14,13 +16,19 @@ pub fn generate<T: Service>(
compile_well_known_types: bool,
build_transport: bool,
attributes: &Attributes,
disable_comments: &HashSet<String>,
) -> TokenStream {
let service_ident = quote::format_ident!("{}Client", service.name());
let client_mod = quote::format_ident!("{}_client", naive_snake_case(service.name()));
let methods = generate_methods(service, emit_package, proto_path, compile_well_known_types);
let methods = generate_methods(
service,
emit_package,
proto_path,
compile_well_known_types,
disable_comments,
);

let connect = generate_connect(&service_ident, build_transport);
let service_doc = generate_doc_comments(service.comment());

let package = if emit_package { service.package() } else { "" };
let path = format!(
Expand All @@ -30,6 +38,12 @@ pub fn generate<T: Service>(
service.identifier()
);

let service_doc = if disable_comments.contains(&path) {
TokenStream::new()
} else {
generate_doc_comments(service.comment())
};

let mod_attributes = attributes.for_mod(package);
let struct_attributes = attributes.for_struct(&path);

Expand Down Expand Up @@ -142,6 +156,7 @@ fn generate_methods<T: Service>(
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
disable_comments: &HashSet<String>,
) -> TokenStream {
let mut stream = TokenStream::new();
let package = if emit_package { service.package() } else { "" };
Expand All @@ -155,7 +170,15 @@ fn generate_methods<T: Service>(
method.identifier()
);

stream.extend(generate_doc_comments(method.comment()));
if !disable_comments.contains(&format!(
"{}{}{}.{}",
package,
if package.is_empty() { "" } else { "." },
service.identifier(),
method.identifier()
)) {
stream.extend(generate_doc_comments(method.comment()));
}

let method = match (method.client_streaming(), method.server_streaming()) {
(false, false) => generate_unary(method, proto_path, compile_well_known_types, path),
Expand Down
3 changes: 3 additions & 0 deletions tonic-build/src/manual.rs
Expand Up @@ -32,6 +32,7 @@ use super::{client, server, Attributes};
use proc_macro2::TokenStream;
use quote::ToTokens;
use std::{
collections::HashSet,
fs,
path::{Path, PathBuf},
};
Expand Down Expand Up @@ -357,6 +358,7 @@ impl ServiceGenerator {
"", // proto_path, -- not used
false, // compile_well_known_types -- not used
&Attributes::default(),
&HashSet::default(),
);
self.servers.extend(server);
}
Expand All @@ -369,6 +371,7 @@ impl ServiceGenerator {
false, // compile_well_known_types, -- not used
self.builder.build_transport,
&Attributes::default(),
&HashSet::default(),
);
self.clients.extend(client);
}
Expand Down
11 changes: 11 additions & 0 deletions tonic-build/src/prost.rs
Expand Up @@ -3,6 +3,7 @@ use proc_macro2::TokenStream;
use prost_build::{Config, Method, Service};
use quote::ToTokens;
use std::{
collections::HashSet,
ffi::OsString,
io,
path::{Path, PathBuf},
Expand All @@ -29,6 +30,7 @@ pub fn configure() -> Builder {
protoc_args: Vec::new(),
include_file: None,
emit_rerun_if_changed: std::env::var_os("CARGO").is_some(),
disable_comments: HashSet::default(),
}
}

Expand Down Expand Up @@ -163,6 +165,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
&self.builder.proto_path,
self.builder.compile_well_known_types,
&self.builder.server_attributes,
&self.builder.disable_comments,
);
self.servers.extend(server);
}
Expand All @@ -175,6 +178,7 @@ impl prost_build::ServiceGenerator for ServiceGenerator {
self.builder.compile_well_known_types,
self.builder.build_transport,
&self.builder.client_attributes,
&self.builder.disable_comments,
);
self.clients.extend(client);
}
Expand Down Expand Up @@ -229,6 +233,7 @@ pub struct Builder {
pub(crate) protoc_args: Vec<OsString>,
pub(crate) include_file: Option<PathBuf>,
pub(crate) emit_rerun_if_changed: bool,
pub(crate) disable_comments: HashSet<String>,

out_dir: Option<PathBuf>,
}
Expand Down Expand Up @@ -354,6 +359,12 @@ impl Builder {
self
}

/// Disable service and rpc comments emission.
pub fn disable_comments(mut self, path: impl AsRef<str>) -> Self {
self.disable_comments.insert(path.as_ref().to_string());
self
}

/// Emits GRPC endpoints with no attached package. Effectively ignores protofile package declaration from grpc context.
///
/// This effectively sets prost's exported package to an empty string.
Expand Down
38 changes: 35 additions & 3 deletions tonic-build/src/server.rs
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use super::{Attributes, Method, Service};
use crate::{generate_doc_comment, generate_doc_comments, naive_snake_case};
use proc_macro2::{Span, TokenStream};
Expand All @@ -14,6 +16,7 @@ pub fn generate<T: Service>(
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 All @@ -22,11 +25,12 @@ pub fn generate<T: Service>(
let server_mod = quote::format_ident!("{}_server", naive_snake_case(service.name()));
let generated_trait = generate_trait(
service,
emit_package,
proto_path,
compile_well_known_types,
server_trait.clone(),
disable_comments,
);
let service_doc = generate_doc_comments(service.comment());
let package = if emit_package { service.package() } else { "" };
// Transport based implementations
let path = format!(
Expand All @@ -35,6 +39,13 @@ pub fn generate<T: Service>(
if package.is_empty() { "" } else { "." },
service.identifier()
);

let service_doc = if disable_comments.contains(&path) {
TokenStream::new()
} else {
generate_doc_comments(service.comment())
};

let named = generate_named(&server_service, &server_trait, &path);
let mod_attributes = attributes.for_mod(package);
let struct_attributes = attributes.for_struct(&path);
Expand Down Expand Up @@ -167,11 +178,19 @@ pub fn generate<T: Service>(

fn generate_trait<T: Service>(
service: &T,
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
server_trait: Ident,
disable_comments: &HashSet<String>,
) -> TokenStream {
let methods = generate_trait_methods(service, proto_path, compile_well_known_types);
let methods = generate_trait_methods(
service,
emit_package,
proto_path,
compile_well_known_types,
disable_comments,
);
let trait_doc = generate_doc_comment(&format!(
" Generated trait containing gRPC methods that should be implemented for use with {}Server.",
service.name()
Expand All @@ -188,18 +207,31 @@ fn generate_trait<T: Service>(

fn generate_trait_methods<T: Service>(
service: &T,
emit_package: bool,
proto_path: &str,
compile_well_known_types: bool,
disable_comments: &HashSet<String>,
) -> TokenStream {
let mut stream = TokenStream::new();

let package = if emit_package { service.package() } else { "" };
for method in service.methods() {
let name = quote::format_ident!("{}", method.name());

let (req_message, res_message) =
method.request_response_name(proto_path, compile_well_known_types);

let method_doc = generate_doc_comments(method.comment());
let method_doc = if disable_comments.contains(&format!(
"{}{}{}.{}",
package,
if package.is_empty() { "" } else { "." },
service.identifier(),
method.identifier()
)) {
TokenStream::new()
} else {
generate_doc_comments(method.comment())
};

let method = match (method.client_streaming(), method.server_streaming()) {
(false, false) => {
Expand Down

0 comments on commit 3659c6d

Please sign in to comment.