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
This commit is contained in:
David Pedersen
2021-06-02 16:58:43 +02:00
committed by GitHub
parent 0fa391eca4
commit e82f0b0399
6 changed files with 65 additions and 4 deletions
+1
View File
@@ -20,5 +20,6 @@ members = [
"tests/extern_path/my_application",
"tests/integration_tests",
"tests/stream_conflict",
"tests/root-crate-path",
]
+14
View File
@@ -0,0 +1,14 @@
[package]
name = "root-crate-path"
version = "0.1.0"
authors = ["Lucio Franco <luciofranco14@gmail.com>"]
edition = "2018"
publish = false
license = "MIT"
[dependencies]
tonic = { path = "../../tonic" }
prost = "0.7"
[build_dependencies]
tonic-build = { path = "../../tonic-build" }
+7
View File
@@ -0,0 +1,7 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure()
.extern_path(".foo.bar.baz.Animal", "crate::Animal")
.compile(&["foo.proto"], &["."])?;
Ok(())
}
+10
View File
@@ -0,0 +1,10 @@
syntax = "proto2";
package foo.bar.baz;
message Animal {
optional string name = 1;
}
service Zoo {
rpc process_animal(Animal) returns (Animal) {};
}
+19
View File
@@ -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!");
}
+14 -4
View File
@@ -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::<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 (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::<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()
@@ -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,