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

tonic-build fails in replace_wellknown when .extern_path is specified #271

Closed
swilcox3 opened this issue Feb 19, 2020 · 3 comments
Closed

Comments

@swilcox3
Copy link

Bug Report

Version

tonic = "0.1.1"
tonic-build = "0.1.1"

Platform

64-bit Windows 10

Crates

tonic-build

Description

I've got two crates, one is a library and one is a tonic server. The library has a .proto that it builds with prost-build which I want to include in the server .proto, so I've specified them with .extern_path. When I build, I get this error (only relevant parts of backtrace included):

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("expected identifier")', src\libcore\result.rs:1165:5
  14:     0x7ff60ba70c68 - core::result::Result<syn::path::Path, syn::error::Error>::unwrap<syn::path::Path,syn::error::Error>
                               at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14\src\libcore\result.rs:933
  15:     0x7ff60ba678e5 - tonic_build::replace_wellknown
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\tonic-build-0.1.1\src\lib.rs:332
  16:     0x7ff60ba8e63e - tonic_build::server::generate_streaming
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\tonic-build-0.1.1\src\server.rs:397
  17:     0x7ff60ba81b1f - tonic_build::server::generate_methods
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\tonic-build-0.1.1\src\server.rs:228
  18:     0x7ff60ba738df - tonic_build::server::generate
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\tonic-build-0.1.1\src\server.rs:8
  19:     0x7ff60ba66ac6 - tonic_build::{{impl}}::generate
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\tonic-build-0.1.1\src\lib.rs:254
  20:     0x7ff60bc9ae8a - prost_build::code_generator::{{impl}}::push_service::{{closure}}
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\prost-build-0.6.1\src\code_generator.rs:676
  21:     0x7ff60bc78831 - core::option::Option<mut alloc::boxed::Box<ServiceGenerator>*>::map<mut alloc::boxed::Box<ServiceGenerator>*,(),closure-1>
                               at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14\src\libcore\option.rs:447
  22:     0x7ff60bc9a246 - prost_build::code_generator::CodeGenerator::push_service
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\prost-build-0.6.1\src\code_generator.rs:673
  23:     0x7ff60bc913b0 - prost_build::code_generator::CodeGenerator::generate
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\prost-build-0.6.1\src\code_generator.rs:103
  24:     0x7ff60bc5bba0 - prost_build::Config::generate
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\prost-build-0.6.1\src\lib.rs:593
  25:     0x7ff60ba2c000 - prost_build::Config::compile_protos<str*>
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\prost-build-0.6.1\src\lib.rs:552
  26:     0x7ff60ba4eb61 - tonic_build::Builder::compile<str*>
                               at C:\Users\SWilcox\.cargo\registry\src\github.aaakk.us.kg-1ecc6299db9ec823\tonic-build-0.1.1\src\lib.rs:167

My build.rs looks like this:

fn main() {
    tonic_build::configure()
        .build_client(true)
        .build_server(true)
        .extern_path(".obj_traits", "::obj_traits")
        .compile(&["../model_state.proto"], &["../", "../../obj-traits/"])
        .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
    /*prost_build::Config::default()
    .extern_path(".obj_traits", "::obj_traits")
    .compile_protos(&["../model_state.proto"], &["../", "../../obj-traits/"])
    .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));*/
}

You can see in the commented section that I've tested this with prost_build, and that succeeds just fine.

Here's the server model_state.proto:

syntax = "proto3";
import "obj_traits.proto";

package model_state;

message AddEntityInput
{
    string file = 1;
    string user = 2;
    obj_traits.DataObjectMsg object = 3;
}

message GetEntityInput
{
    string file = 1;
    string user = 2;
    string id = 3;
}

message ModifyEntityInput
{
    string file = 1;
    string user = 2;
    obj_traits.DataObjectMsg object = 3;
}

message DeleteEntityInput
{
    string file = 1;
    string user = 2;
    string id = 3;
}

message ClearFileInput
{
    string file = 1;
}

message ClearUserInput
{
    string file = 1;
    string user = 2;
}

message EmptyOutput{}

service ModelState {
    rpc AddEntity(stream AddEntityInput) returns (stream obj_traits.UpdateChangeMsg);
    rpc GetEntity(stream GetEntityInput) returns (stream obj_traits.DataObjectMsg);
    rpc ModifyEntity(stream ModifyEntityInput) returns (stream obj_traits.UpdateChangeMsg);
    rpc DeleteEntity(stream DeleteEntityInput) returns (stream obj_traits.UpdateChangeMsg);
    rpc ClearUser(ClearUserInput) returns (EmptyOutput);
    rpc ClearFile(ClearFileInput) returns (EmptyOutput); 
}

And the library obj_traits.proto:

syntax = "proto3";

package obj_traits;

message DataObjectMsg
{
    string obj_type = 1;
    bytes object = 2;
}

message MeshDataMsg
{
    string id = 1;
    repeated double positions = 2;
    repeated uint64 indices = 3;
    string meta_json = 4;
}

message UpdateOutputMsg
{
    oneof output {
        string empty = 1;
        string delete = 2;
        MeshDataMsg mesh = 3;
        string other_json = 4;
    }
}

message UpdateChangeMsg
{
    uint64 change = 1;
    UpdateOutputMsg update = 2;
}

I see that the failure is coming from replace_wellknown. I used to have a reference to a well known type in the server .proto, but I removed it. This error doesn't go away after a clean build either.

@swilcox3
Copy link
Author

It seems to be related to using obj_traits.* in the output of the rpc definitions. If I change the service to look like this it works fine:

message AddEntityOutput
{
    obj_traits.UpdateChangeMsg update = 1;
}

message GetEntityOutput
{
    obj_traits.DataObjectMsg object = 1;
}

message ModifyEntityOutput
{
    obj_traits.UpdateChangeMsg update = 2;
}

message DeleteEntityOutput
{
    obj_traits.UpdateChangeMsg update = 3;
}

message EmptyOutput{}

service ModelState {
    rpc AddEntity(stream AddEntityInput) returns (stream AddEntityOutput);
    rpc GetEntity(stream GetEntityInput) returns (stream GetEntityOutput);
    rpc ModifyEntity(stream ModifyEntityInput) returns (stream ModifyEntityOutput);
    rpc DeleteEntity(stream DeleteEntityInput) returns (stream DeleteEntityOutput);
    rpc ClearUser(ClearUserInput) returns (EmptyOutput);
    rpc ClearFile(ClearFileInput) returns (EmptyOutput); 
}

That's better practice anyways, so I'll go ahead and do that going forward, but the first case should either work out of the box or have a more descriptive error message.

@cthulhua
Copy link
Contributor

This looks to me like #260 which was merged to master in #261
Do you mind seeing if this works against master?

@swilcox3
Copy link
Author

Yep, that looks like the same issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants