Skip to content

[protoc-gen-tonic] Honor default_package_filename for package-less protos #142

Description

@fivetran-auslacroix

Summary

For a proto file with no package, protoc-gen-prost honors default_package_filename, but protoc-gen-tonic still derives its filename from the empty package name. This produces a hidden .tonic.rs file and inserts include!(".tonic.rs"); into the Prost output.

Tested with protoc-gen-prost and protoc-gen-tonic 0.5.0 built from current main at 3e44d8a, using protoc 36.0.

Reproduction

package_less.proto:

syntax = "proto3";

message PingRequest {}
message PingResponse {}

service PingService {
  rpc Ping(PingRequest) returns (PingResponse);
}

With both plugin binaries on PATH:

mkdir out
protoc -I . package_less.proto \
  --prost_out=out --prost_opt=default_package_filename=_ \
  --tonic_out=out --tonic_opt=default_package_filename=_
find out -maxdepth 1 -type f -print

Actual behavior

The generated files are out/_ and out/.tonic.rs. The Prost output contains:

include!(".tonic.rs");

Expected behavior

The Tonic output should use the filename already selected by ModuleRequestSet: out/_.tonic.rs, with include!("_.tonic.rs"); in out/_.

The current implementation constructs the name from proto_package_name(), even though ModuleRequest already exposes output_filename().

Proposed patch

I compiled this patch and reran the reproduction. It generated out/_ and out/_.tonic.rs, and the include changed to include!("_.tonic.rs");.

Patch against current main
diff --git a/protoc-gen-tonic/src/generator.rs b/protoc-gen-tonic/src/generator.rs
index 6eefc8b..8f55150 100644
--- a/protoc-gen-tonic/src/generator.rs
+++ b/protoc-gen-tonic/src/generator.rs
@@ -130,7 +130,11 @@ impl TonicGenerator {
     fn handle_module_request(&self, module: &Module, request: &ModuleRequest) -> Option<Vec<File>> {
         const PROTO_PATH: &str = "super";
 
-        let output_filename = format!("{}.tonic.rs", request.proto_package_name());
+        let output_stem = request
+            .output_filename()
+            .unwrap_or_else(|| request.proto_package_name());
+        let output_stem = output_stem.strip_suffix(".rs").unwrap_or(output_stem);
+        let output_filename = format!("{output_stem}.tonic.rs");
 
         let services = request
             .files()

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions