@@ -29,6 +29,7 @@ enum Syntax {
2929pub struct CodeGenerator < ' a > {
3030 config : & ' a mut Config ,
3131 package : String ,
32+ type_path : Vec < String > ,
3233 source_info : Option < SourceCodeInfo > ,
3334 syntax : Syntax ,
3435 message_graph : & ' a MessageGraph ,
@@ -69,6 +70,7 @@ impl<'a> CodeGenerator<'a> {
6970 let mut code_gen = CodeGenerator {
7071 config,
7172 package : file. package . unwrap_or_default ( ) ,
73+ type_path : Vec :: new ( ) ,
7274 source_info,
7375 syntax,
7476 message_graph,
@@ -84,13 +86,6 @@ impl<'a> CodeGenerator<'a> {
8486 code_gen. package
8587 ) ;
8688
87- if code_gen. config . enable_type_names {
88- code_gen. buf . push_str ( & format ! (
89- "const PACKAGE: &str = \" {}\" ;\n " ,
90- code_gen. package,
91- ) ) ;
92- }
93-
9489 code_gen. path . push ( 4 ) ;
9590 for ( idx, message) in file. message_type . into_iter ( ) . enumerate ( ) {
9691 code_gen. path . push ( idx as i32 ) ;
@@ -128,10 +123,16 @@ impl<'a> CodeGenerator<'a> {
128123
129124 let message_name = message. name ( ) . to_string ( ) ;
130125 let fq_message_name = format ! (
131- "{}{}.{}" ,
132- if self . package. is_empty( ) { "" } else { "." } ,
133- self . package,
134- message. name( )
126+ "{}{}{}{}.{}" ,
127+ if self . package. is_empty( ) && self . type_path. is_empty( ) {
128+ ""
129+ } else {
130+ "."
131+ } ,
132+ self . package. trim_matches( '.' ) ,
133+ if self . type_path. is_empty( ) { "" } else { "." } ,
134+ self . type_path. join( "." ) ,
135+ message_name,
135136 ) ;
136137
137138 // Skip external types.
@@ -282,19 +283,34 @@ impl<'a> CodeGenerator<'a> {
282283 ) ) ;
283284 self . depth += 1 ;
284285
285- self . buf
286- . push_str ( "const PACKAGE: &'static str = PACKAGE;\n " ) ;
287286 self . buf . push_str ( & format ! (
288287 "const NAME: &'static str = \" {}\" ;\n " ,
289- message_name
288+ message_name,
289+ ) ) ;
290+ self . buf . push_str ( & format ! (
291+ "const PACKAGE: &'static str = \" {}\" ;\n " ,
292+ self . package,
293+ ) ) ;
294+
295+ let prost_path = self . config . prost_path . as_deref ( ) . unwrap_or ( "::prost" ) ;
296+ let string_path = format ! ( "{}::alloc::string::String" , prost_path) ;
297+ let format_path = format ! ( "{}::alloc::format" , prost_path) ;
298+
299+ self . buf . push_str ( & format ! (
300+ r#"fn full_name() -> {string_path} {{
301+ {format_path}!("{}{}{}{}{{}}", Self::NAME)
302+ }}"# ,
303+ self . package. trim_matches( '.' ) ,
304+ if self . package. is_empty( ) { "" } else { "." } ,
305+ self . type_path. join( "." ) ,
306+ if self . type_path. is_empty( ) { "" } else { "." } ,
290307 ) ) ;
291308
292309 if let Some ( domain_name) = self . config . type_name_domains . get_first ( fq_message_name) {
293310 self . buf . push_str ( & format ! (
294- r#"fn type_url() -> String {{
295- format !("{}/{{}}", Self::full_name())
311+ r#"fn type_url() -> {string_path} {{
312+ {format_path} !("{domain_name }/{{}}", Self::full_name())
296313 }}"# ,
297- domain_name
298314 ) ) ;
299315 }
300316
@@ -684,11 +700,18 @@ impl<'a> CodeGenerator<'a> {
684700
685701 let enum_values = & desc. value ;
686702 let fq_proto_enum_name = format ! (
687- "{}{}.{}" ,
688- if self . package. is_empty( ) { "" } else { "." } ,
689- self . package,
690- proto_enum_name
703+ "{}{}{}{}.{}" ,
704+ if self . package. is_empty( ) && self . type_path. is_empty( ) {
705+ ""
706+ } else {
707+ "."
708+ } ,
709+ self . package. trim_matches( '.' ) ,
710+ if self . type_path. is_empty( ) { "" } else { "." } ,
711+ self . type_path. join( "." ) ,
712+ proto_enum_name,
691713 ) ;
714+
692715 if self
693716 . extern_paths
694717 . resolve_ident ( & fq_proto_enum_name)
@@ -906,17 +929,15 @@ impl<'a> CodeGenerator<'a> {
906929 self . buf . push_str ( & to_snake ( module) ) ;
907930 self . buf . push_str ( " {\n " ) ;
908931
909- self . package . push ( '.' ) ;
910- self . package . push_str ( module) ;
932+ self . type_path . push ( module. into ( ) ) ;
911933
912934 self . depth += 1 ;
913935 }
914936
915937 fn pop_mod ( & mut self ) {
916938 self . depth -= 1 ;
917939
918- let idx = self . package . rfind ( '.' ) . unwrap ( ) ;
919- self . package . truncate ( idx) ;
940+ self . type_path . pop ( ) ;
920941
921942 self . push_indent ( ) ;
922943 self . buf . push_str ( "}\n " ) ;
@@ -954,7 +975,11 @@ impl<'a> CodeGenerator<'a> {
954975 return proto_ident;
955976 }
956977
957- let mut local_path = self . package . split ( '.' ) . peekable ( ) ;
978+ let mut local_path = self
979+ . package
980+ . split ( '.' )
981+ . chain ( self . type_path . iter ( ) . map ( String :: as_str) )
982+ . peekable ( ) ;
958983
959984 // If no package is specified the start of the package name will be '.'
960985 // and split will return an empty string ("") which breaks resolution
0 commit comments