From e82f0b0399139fade3d9f890ae8ced7ad1be71cf Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 2 Jun 2021 16:58:43 +0200 Subject: [PATCH] build: generate root crate paths correctly (#623) We shouldn't append `proto_path` (`super` by default) if the path starts with `crate::`. Fixes https://github.com/hyperium/tonic/issues/548 --- Cargo.toml | 1 + tests/root-crate-path/Cargo.toml | 14 ++++++++++++++ tests/root-crate-path/build.rs | 7 +++++++ tests/root-crate-path/foo.proto | 10 ++++++++++ tests/root-crate-path/src/main.rs | 19 +++++++++++++++++++ tonic-build/src/prost.rs | 18 ++++++++++++++---- 6 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 tests/root-crate-path/Cargo.toml create mode 100644 tests/root-crate-path/build.rs create mode 100644 tests/root-crate-path/foo.proto create mode 100644 tests/root-crate-path/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 4d6f9c4..3d1cbb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,5 +20,6 @@ members = [ "tests/extern_path/my_application", "tests/integration_tests", "tests/stream_conflict", + "tests/root-crate-path", ] diff --git a/tests/root-crate-path/Cargo.toml b/tests/root-crate-path/Cargo.toml new file mode 100644 index 0000000..9a90bcc --- /dev/null +++ b/tests/root-crate-path/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "root-crate-path" +version = "0.1.0" +authors = ["Lucio Franco "] +edition = "2018" +publish = false +license = "MIT" + +[dependencies] +tonic = { path = "../../tonic" } +prost = "0.7" + +[build_dependencies] +tonic-build = { path = "../../tonic-build" } diff --git a/tests/root-crate-path/build.rs b/tests/root-crate-path/build.rs new file mode 100644 index 0000000..45a84c7 --- /dev/null +++ b/tests/root-crate-path/build.rs @@ -0,0 +1,7 @@ +fn main() -> Result<(), Box> { + tonic_build::configure() + .extern_path(".foo.bar.baz.Animal", "crate::Animal") + .compile(&["foo.proto"], &["."])?; + + Ok(()) +} diff --git a/tests/root-crate-path/foo.proto b/tests/root-crate-path/foo.proto new file mode 100644 index 0000000..9364143 --- /dev/null +++ b/tests/root-crate-path/foo.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package foo.bar.baz; + +message Animal { + optional string name = 1; +} +service Zoo { + rpc process_animal(Animal) returns (Animal) {}; +} diff --git a/tests/root-crate-path/src/main.rs b/tests/root-crate-path/src/main.rs new file mode 100644 index 0000000..bf879bc --- /dev/null +++ b/tests/root-crate-path/src/main.rs @@ -0,0 +1,19 @@ +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Animal { + #[prost(string, optional, tag = "1")] + pub name: ::core::option::Option<::prost::alloc::string::String>, +} + +// pub mod foo; + +pub mod foo { + pub mod bar { + pub mod baz { + tonic::include_proto!("foo.bar.baz"); + } + } +} + +fn main() { + println!("Hello, world!"); +} diff --git a/tonic-build/src/prost.rs b/tonic-build/src/prost.rs index 596c60b..ee62603 100644 --- a/tonic-build/src/prost.rs +++ b/tonic-build/src/prost.rs @@ -102,22 +102,28 @@ impl crate::Method for Method { proto_path: &str, compile_well_known_types: bool, ) -> (TokenStream, TokenStream) { - let request = if (self.input_proto_type.starts_with(".google.protobuf") - && !compile_well_known_types) + let request = if (is_google_type(&self.input_proto_type) && !compile_well_known_types) || self.input_type.starts_with("::") { self.input_type.parse::().unwrap() + } else if self.input_type.starts_with("crate::") { + syn::parse_str::(&self.input_type) + .unwrap() + .to_token_stream() } else { syn::parse_str::(&format!("{}::{}", proto_path, self.input_type)) .unwrap() .to_token_stream() }; - let response = if (self.output_proto_type.starts_with(".google.protobuf") - && !compile_well_known_types) + let response = if (is_google_type(&self.output_proto_type) && !compile_well_known_types) || self.output_type.starts_with("::") { self.output_type.parse::().unwrap() + } else if self.output_type.starts_with("crate::") { + syn::parse_str::(&self.output_type) + .unwrap() + .to_token_stream() } else { syn::parse_str::(&format!("{}::{}", proto_path, self.output_type)) .unwrap() @@ -128,6 +134,10 @@ impl crate::Method for Method { } } +fn is_google_type(ty: &str) -> bool { + ty.starts_with(".google.protobuf") +} + struct ServiceGenerator { builder: Builder, clients: TokenStream,