Skip to content

Commit

Permalink
fix: fq_message_name should begin with one dot (#981)
Browse files Browse the repository at this point in the history
When package name is empty, but type_path is filled, the fq_message_name should begin with a single dot.

Two duplicate implementations are moved to a separate function.

A test is added that creates a sub message without a package name. The code generator uses the message name to generate a rust module path, which is invalid.

fixes: #843
  • Loading branch information
caspermeijn committed Feb 28, 2024
1 parent 7f1c303 commit a4538f2
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 24 deletions.
38 changes: 14 additions & 24 deletions prost-build/src/code_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,7 @@ impl<'a> CodeGenerator<'a> {
debug!(" message: {:?}", message.name());

let message_name = message.name().to_string();
let fq_message_name = format!(
"{}{}{}{}.{}",
if self.package.is_empty() && self.type_path.is_empty() {
""
} else {
"."
},
self.package.trim_matches('.'),
if self.type_path.is_empty() { "" } else { "." },
self.type_path.join("."),
message_name,
);
let fq_message_name = self.fq_name(&message_name);

// Skip external types.
if self.extern_paths.resolve_ident(&fq_message_name).is_some() {
Expand Down Expand Up @@ -701,18 +690,7 @@ impl<'a> CodeGenerator<'a> {
let enum_name = to_upper_camel(proto_enum_name);

let enum_values = &desc.value;
let fq_proto_enum_name = format!(
"{}{}{}{}.{}",
if self.package.is_empty() && self.type_path.is_empty() {
""
} else {
"."
},
self.package.trim_matches('.'),
if self.type_path.is_empty() { "" } else { "." },
self.type_path.join("."),
proto_enum_name,
);
let fq_proto_enum_name = self.fq_name(proto_enum_name);

if self
.extern_paths
Expand Down Expand Up @@ -1065,6 +1043,18 @@ impl<'a> CodeGenerator<'a> {
.as_ref()
.map_or(false, FieldOptions::deprecated)
}

/// Returns the fully-qualified name, starting with a dot
fn fq_name(&self, message_name: &str) -> String {
format!(
"{}{}{}{}.{}",
if self.package.is_empty() { "" } else { "." },
self.package.trim_matches('.'),
if self.type_path.is_empty() { "" } else { "." },
self.type_path.join("."),
message_name,
)
}
}

/// Returns `true` if the repeated field type can be packed.
Expand Down
4 changes: 4 additions & 0 deletions tests/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ fn main() {
.compile_protos(&[src.join("option_struct.proto")], includes)
.unwrap();

config
.compile_protos(&[src.join("submessage_without_package.proto")], includes)
.unwrap();

prost_build::Config::new()
.protoc_arg("--experimental_allow_proto3_optional")
.compile_protos(&[src.join("proto3_presence.proto")], includes)
Expand Down
2 changes: 2 additions & 0 deletions tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ mod no_unused_results;
#[cfg(feature = "std")]
mod skip_debug;
#[cfg(test)]
mod submessage_without_package;
#[cfg(test)]
mod type_names;

mod test_enum_named_option_value {
Expand Down
8 changes: 8 additions & 0 deletions tests/src/submessage_without_package.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto3";

message M {
message SubMessage {
map<string, string> item = 1;
}
SubMessage reply = 2;
}
6 changes: 6 additions & 0 deletions tests/src/submessage_without_package.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include!(concat!(env!("OUT_DIR"), "/_.rs"));

#[test]
fn test_submessage_without_package() {
let _msg = M::default();
}

0 comments on commit a4538f2

Please sign in to comment.