Skip to content

Commit

Permalink
fix(build): Correctly convert Empty to () (#734)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Dyas committed Oct 22, 2021
1 parent 4947b07 commit ff6a690
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 31 deletions.
1 change: 1 addition & 0 deletions tests/wellknown-compiled/Cargo.toml
Expand Up @@ -16,4 +16,5 @@ tonic = { path = "../../tonic" }
prost = "0.9"

[build-dependencies]
prost-build = "0.9"
tonic-build = { path = "../../tonic-build" }
9 changes: 8 additions & 1 deletion tests/wellknown-compiled/build.rs
@@ -1,6 +1,13 @@
fn main() {
let mut config = prost_build::Config::new();
config.extern_path(".google.protobuf.Empty", "()");

tonic_build::configure()
.compile_well_known_types(true)
.compile(&["proto/google.proto"], &["proto"])
.compile_with_config(
config,
&["proto/google.proto", "proto/test.proto"],
&["proto"],
)
.unwrap();
}
11 changes: 11 additions & 0 deletions tests/wellknown-compiled/proto/test.proto
@@ -0,0 +1,11 @@
syntax = "proto3";
package test;

import "google/protobuf/empty.proto";

message Input {
}

service Service {
rpc Call(Input) returns (google.protobuf.Empty);
}
17 changes: 13 additions & 4 deletions tests/wellknown-compiled/src/lib.rs
@@ -1,9 +1,18 @@
pub mod google {
pub mod protobuf {
tonic::include_proto!("google.protobuf");
pub mod gen {
pub mod google {
pub mod protobuf {
tonic::include_proto!("google.protobuf");
}
}

pub mod test {
tonic::include_proto!("test");
}
}

pub fn grok() {
let _empty = crate::google::protobuf::Empty {};
let _any = crate::gen::google::protobuf::Any {
type_url: "foo".to_owned(),
value: Vec::new(),
};
}
46 changes: 20 additions & 26 deletions tonic-build/src/prost.rs
Expand Up @@ -49,6 +49,9 @@ pub fn compile_protos(proto: impl AsRef<Path>) -> io::Result<()> {

const PROST_CODEC_PATH: &str = "tonic::codec::ProstCodec";

/// Non-path Rust types allowed for request/response types.
const NON_PATH_TYPE_ALLOWLIST: &[&str] = &["()"];

impl crate::Service for Service {
const CODEC_PATH: &'static str = PROST_CODEC_PATH;

Expand Down Expand Up @@ -105,34 +108,25 @@ impl crate::Method for Method {
proto_path: &str,
compile_well_known_types: bool,
) -> (TokenStream, TokenStream) {
let request = if (is_google_type(&self.input_proto_type) && !compile_well_known_types)
|| self.input_type.starts_with("::")
{
self.input_type.parse::<TokenStream>().unwrap()
} else if self.input_type.starts_with("crate::") {
syn::parse_str::<syn::Path>(&self.input_type)
.unwrap()
.to_token_stream()
} else {
syn::parse_str::<syn::Path>(&format!("{}::{}", proto_path, self.input_type))
.unwrap()
.to_token_stream()
};

let response = if (is_google_type(&self.output_proto_type) && !compile_well_known_types)
|| self.output_type.starts_with("::")
{
self.output_type.parse::<TokenStream>().unwrap()
} else if self.output_type.starts_with("crate::") {
syn::parse_str::<syn::Path>(&self.output_type)
.unwrap()
.to_token_stream()
} else {
syn::parse_str::<syn::Path>(&format!("{}::{}", proto_path, self.output_type))
.unwrap()
.to_token_stream()
let convert_type = |proto_type: &str, rust_type: &str| -> TokenStream {
if (is_google_type(proto_type) && !compile_well_known_types)
|| rust_type.starts_with("::")
|| NON_PATH_TYPE_ALLOWLIST.iter().any(|ty| *ty == rust_type)
{
rust_type.parse::<TokenStream>().unwrap()
} else if rust_type.starts_with("crate::") {
syn::parse_str::<syn::Path>(rust_type)
.unwrap()
.to_token_stream()
} else {
syn::parse_str::<syn::Path>(&format!("{}::{}", proto_path, rust_type))
.unwrap()
.to_token_stream()
}
};

let request = convert_type(&self.input_proto_type, &self.input_type);
let response = convert_type(&self.output_proto_type, &self.output_type);
(request, response)
}
}
Expand Down

0 comments on commit ff6a690

Please sign in to comment.