• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::fmt;
2 
3 use protobuf::descriptor::*;
4 use protobuf::reflect::FileDescriptor;
5 use protobuf::reflect::MessageDescriptor;
6 use protobuf_parse::snake_case;
7 
8 use crate::customize::ctx::CustomizeElemCtx;
9 use crate::customize::ctx::SpecialFieldPseudoDescriptor;
10 use crate::customize::rustproto_proto::customize_from_rustproto_for_message;
11 use crate::gen::code_writer::*;
12 use crate::gen::descriptor::write_fn_descriptor;
13 use crate::gen::enums::*;
14 use crate::gen::field::FieldGen;
15 use crate::gen::field::FieldKind;
16 use crate::gen::file_and_mod::FileAndMod;
17 use crate::gen::inside::protobuf_crate_path;
18 use crate::gen::oneof::OneofGen;
19 use crate::gen::oneof::OneofVariantGen;
20 use crate::gen::protoc_insertion_point::write_protoc_insertion_point_for_message;
21 use crate::gen::protoc_insertion_point::write_protoc_insertion_point_for_special_field;
22 use crate::gen::rust::ident::RustIdent;
23 use crate::gen::rust::ident_with_path::RustIdentWithPath;
24 use crate::gen::rust::rel_path::RustRelativePath;
25 use crate::gen::rust::snippets::expr_vec_with_capacity_const;
26 use crate::gen::rust::snippets::EXPR_NONE;
27 use crate::gen::rust_types_values::*;
28 use crate::gen::scope::MessageWithScope;
29 use crate::gen::scope::RootScope;
30 use crate::gen::scope::WithScope;
31 use crate::Customize;
32 
33 /// Protobuf message Rust type name
34 #[derive(Debug, Clone, PartialEq, Eq)]
35 pub(crate) struct RustTypeMessage(pub RustIdentWithPath);
36 
37 impl fmt::Display for RustTypeMessage {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result38     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39         fmt::Display::fmt(&self.0, f)
40     }
41 }
42 
43 impl<S: Into<RustIdentWithPath>> From<S> for RustTypeMessage {
from(s: S) -> Self44     fn from(s: S) -> Self {
45         RustTypeMessage(s.into())
46     }
47 }
48 
49 impl RustTypeMessage {
50     /// Code which emits default instance.
default_instance(&self, customize: &Customize) -> String51     pub fn default_instance(&self, customize: &Customize) -> String {
52         format!(
53             "<{} as {}::Message>::default_instance()",
54             self.0,
55             protobuf_crate_path(customize)
56         )
57     }
58 }
59 
60 /// Message info for codegen
61 pub(crate) struct MessageGen<'a> {
62     file_descriptor: &'a FileDescriptor,
63     message_descriptor: MessageDescriptor,
64     pub message: &'a MessageWithScope<'a>,
65     pub root_scope: &'a RootScope<'a>,
66     pub fields: Vec<FieldGen<'a>>,
67     pub lite_runtime: bool,
68     customize: CustomizeElemCtx<'a>,
69     path: &'a [i32],
70     info: Option<&'a SourceCodeInfo>,
71 }
72 
73 impl<'a> MessageGen<'a> {
new( file_descriptor: &'a FileDescriptor, message: &'a MessageWithScope<'a>, root_scope: &'a RootScope<'a>, parent_customize: &CustomizeElemCtx<'a>, path: &'a [i32], info: Option<&'a SourceCodeInfo>, ) -> anyhow::Result<MessageGen<'a>>74     pub fn new(
75         file_descriptor: &'a FileDescriptor,
76         message: &'a MessageWithScope<'a>,
77         root_scope: &'a RootScope<'a>,
78         parent_customize: &CustomizeElemCtx<'a>,
79         path: &'a [i32],
80         info: Option<&'a SourceCodeInfo>,
81     ) -> anyhow::Result<MessageGen<'a>> {
82         let message_descriptor = file_descriptor
83             .message_by_package_relative_name(&format!("{}", message.protobuf_name_to_package()))
84             .unwrap();
85 
86         let customize = parent_customize.child(
87             &customize_from_rustproto_for_message(message.message.proto().options.get_or_default()),
88             &message.message,
89         );
90 
91         static FIELD_NUMBER: protobuf::rt::Lazy<i32> = protobuf::rt::Lazy::new();
92         let field_number = *FIELD_NUMBER.get(|| {
93             protobuf::reflect::MessageDescriptor::for_type::<DescriptorProto>()
94                 .field_by_name("field")
95                 .expect("`field` must exist")
96                 .proto()
97                 .number()
98         });
99 
100         let fields: Vec<_> = message
101             .fields()
102             .into_iter()
103             .enumerate()
104             .map(|(id, field)| {
105                 let mut path = path.to_vec();
106                 path.extend_from_slice(&[field_number, id as i32]);
107                 FieldGen::parse(field, root_scope, &customize, path, info)
108             })
109             .collect::<anyhow::Result<Vec<_>>>()?;
110         let lite_runtime = customize.for_elem.lite_runtime.unwrap_or_else(|| {
111             message.file_descriptor().proto().options.optimize_for()
112                 == file_options::OptimizeMode::LITE_RUNTIME
113         });
114         Ok(MessageGen {
115             message_descriptor,
116             file_descriptor,
117             message,
118             root_scope,
119             fields,
120             lite_runtime,
121             customize,
122             path,
123             info,
124         })
125     }
126 
rust_name(&self) -> RustIdent127     fn rust_name(&self) -> RustIdent {
128         self.message.rust_name()
129     }
130 
mod_name(&self) -> RustRelativePath131     fn mod_name(&self) -> RustRelativePath {
132         self.message.scope.rust_path_to_file()
133     }
134 
file_and_mod(&self) -> FileAndMod135     pub fn file_and_mod(&self) -> FileAndMod {
136         self.message
137             .scope
138             .file_and_mod(self.customize.for_elem.clone())
139     }
140 
oneofs(&'a self) -> Vec<OneofGen<'a>>141     fn oneofs(&'a self) -> Vec<OneofGen<'a>> {
142         self.message
143             .oneofs()
144             .into_iter()
145             .map(|oneof| OneofGen::parse(self, oneof, &self.customize))
146             .collect()
147     }
148 
required_fields(&'a self) -> Vec<&'a FieldGen>149     fn required_fields(&'a self) -> Vec<&'a FieldGen> {
150         self.fields
151             .iter()
152             .filter(|f| match f.kind {
153                 FieldKind::Singular(ref singular) => singular.flag.is_required(),
154                 _ => false,
155             })
156             .collect()
157     }
158 
message_fields(&'a self) -> Vec<&'a FieldGen>159     fn message_fields(&'a self) -> Vec<&'a FieldGen> {
160         self.fields
161             .iter()
162             .filter(|f| f.proto_type == field_descriptor_proto::Type::TYPE_MESSAGE)
163             .collect()
164     }
165 
fields_except_oneof(&'a self) -> Vec<&'a FieldGen>166     fn fields_except_oneof(&'a self) -> Vec<&'a FieldGen> {
167         self.fields
168             .iter()
169             .filter(|f| match f.kind {
170                 FieldKind::Oneof(..) => false,
171                 _ => true,
172             })
173             .collect()
174     }
175 
fields_except_group(&'a self) -> Vec<&'a FieldGen>176     fn fields_except_group(&'a self) -> Vec<&'a FieldGen> {
177         self.fields
178             .iter()
179             .filter(|f| f.proto_type != field_descriptor_proto::Type::TYPE_GROUP)
180             .collect()
181     }
182 
fields_except_oneof_and_group(&'a self) -> Vec<&'a FieldGen>183     fn fields_except_oneof_and_group(&'a self) -> Vec<&'a FieldGen> {
184         self.fields
185             .iter()
186             .filter(|f| match f.kind {
187                 FieldKind::Oneof(..) => false,
188                 _ => f.proto_type != field_descriptor_proto::Type::TYPE_GROUP,
189             })
190             .collect()
191     }
192 
write_match_each_oneof_variant<F>(&self, w: &mut CodeWriter, cb: F) where F: Fn(&mut CodeWriter, &OneofVariantGen, &RustValueTyped),193     fn write_match_each_oneof_variant<F>(&self, w: &mut CodeWriter, cb: F)
194     where
195         F: Fn(&mut CodeWriter, &OneofVariantGen, &RustValueTyped),
196     {
197         for oneof in self.oneofs() {
198             let variants = oneof.variants_except_group();
199             if variants.is_empty() {
200                 // Special case because
201                 // https://github.com/rust-lang/rust/issues/50642
202                 continue;
203             }
204             w.if_let_stmt(
205                 "::std::option::Option::Some(ref v)",
206                 &format!("self.{}", oneof.oneof.field_name())[..],
207                 |w| {
208                     w.match_block("v", |w| {
209                         for variant in variants {
210                             let ref field = variant.field;
211 
212                             let (refv, vtype) = if field.elem_type_is_copy() {
213                                 ("v", variant.rust_type(&self.file_and_mod()))
214                             } else {
215                                 ("ref v", variant.rust_type(&self.file_and_mod()).ref_type())
216                             };
217                             w.case_block(
218                                 format!("&{}({})", variant.path(&self.file_and_mod()), refv),
219                                 |w| {
220                                     cb(
221                                         w,
222                                         &variant,
223                                         &RustValueTyped {
224                                             value: "v".to_owned(),
225                                             rust_type: vtype.clone(),
226                                         },
227                                     );
228                                 },
229                             );
230                         }
231                     });
232                 },
233             );
234         }
235     }
236 
write_write_to_with_cached_sizes(&self, w: &mut CodeWriter)237     fn write_write_to_with_cached_sizes(&self, w: &mut CodeWriter) {
238         let sig = format!(
239             "write_to_with_cached_sizes(&self, os: &mut {protobuf_crate}::CodedOutputStream<'_>) -> {protobuf_crate}::Result<()>",
240             protobuf_crate=protobuf_crate_path(&self.customize.for_elem),
241         );
242         w.def_fn(&sig, |w| {
243             // To have access to its methods but not polute the name space.
244             for f in self.fields_except_oneof_and_group() {
245                 f.write_message_write_field("os", w);
246             }
247             self.write_match_each_oneof_variant(w, |w, variant, v| {
248                 variant
249                     .field
250                     .write_write_element(variant.elem(), w, "os", v);
251             });
252             w.write_line("os.write_unknown_fields(self.special_fields.unknown_fields())?;");
253             w.write_line("::std::result::Result::Ok(())");
254         });
255     }
256 
write_default_instance_lazy(&self, w: &mut CodeWriter)257     fn write_default_instance_lazy(&self, w: &mut CodeWriter) {
258         w.lazy_static_decl_get_simple(
259             "instance",
260             &format!("{}", self.rust_name()),
261             &format!("{}::new", self.rust_name()),
262             &format!("{}", protobuf_crate_path(&self.customize.for_elem)),
263         );
264     }
265 
write_default_instance_static(&self, w: &mut CodeWriter)266     fn write_default_instance_static(&self, w: &mut CodeWriter) {
267         w.stmt_block(
268             &format!(
269                 "static instance: {} = {}",
270                 self.rust_name(),
271                 self.rust_name()
272             ),
273             |w| {
274                 for f in &self.fields_except_oneof_and_group() {
275                     w.field_entry(
276                         &f.rust_name.to_string(),
277                         &f.kind
278                             .default(&self.customize.for_elem, &self.file_and_mod(), true),
279                     );
280                 }
281                 for o in &self.oneofs() {
282                     w.field_entry(&o.oneof.field_name().to_string(), EXPR_NONE);
283                 }
284                 w.field_entry(
285                     "special_fields",
286                     &format!(
287                         "{}::SpecialFields::new()",
288                         protobuf_crate_path(&self.customize.for_elem)
289                     ),
290                 );
291             },
292         );
293         w.write_line("&instance");
294     }
295 
write_default_instance(&self, w: &mut CodeWriter)296     fn write_default_instance(&self, w: &mut CodeWriter) {
297         w.def_fn(
298             &format!("default_instance() -> &'static {}", self.rust_name()),
299             |w| {
300                 let has_map_field = self.fields.iter().any(|f| match f.kind {
301                     FieldKind::Map(..) => true,
302                     _ => false,
303                 });
304                 if has_map_field {
305                     self.write_default_instance_lazy(w)
306                 } else {
307                     self.write_default_instance_static(w)
308                 }
309             },
310         );
311     }
312 
write_compute_size(&self, w: &mut CodeWriter)313     fn write_compute_size(&self, w: &mut CodeWriter) {
314         // Append sizes of messages in the tree to the specified vector.
315         // First appended element is size of self, and then nested message sizes.
316         // in serialization order are appended recursively.");
317         w.comment("Compute sizes of nested messages");
318         // there are unused variables in oneof
319         w.allow(&["unused_variables"]);
320         w.def_fn("compute_size(&self) -> u64", |w| {
321             // To have access to its methods but not polute the name space.
322             w.write_line("let mut my_size = 0;");
323             for field in self.fields_except_oneof_and_group() {
324                 field.write_message_compute_field_size("my_size", w);
325             }
326             self.write_match_each_oneof_variant(w, |w, variant, v| {
327                 variant
328                     .field
329                     .write_element_size(variant.elem(), w, v, "my_size");
330             });
331             w.write_line(&format!(
332                 "my_size += {}::rt::unknown_fields_size(self.special_fields.unknown_fields());",
333                 protobuf_crate_path(&self.customize.for_elem)
334             ));
335             w.write_line("self.special_fields.cached_size().set(my_size as u32);");
336             w.write_line("my_size");
337         });
338     }
339 
write_field_accessors(&self, w: &mut CodeWriter)340     fn write_field_accessors(&self, w: &mut CodeWriter) {
341         for f in self.fields_except_group() {
342             f.write_message_single_field_accessors(w);
343         }
344     }
345 
write_impl_self(&self, w: &mut CodeWriter)346     fn write_impl_self(&self, w: &mut CodeWriter) {
347         w.impl_self_block(&format!("{}", self.rust_name()), |w| {
348             w.pub_fn(&format!("new() -> {}", self.rust_name()), |w| {
349                 w.write_line("::std::default::Default::default()");
350             });
351 
352             self.write_field_accessors(w);
353 
354             if !self.lite_runtime {
355                 w.write_line("");
356                 self.write_generated_message_descriptor_data(w);
357             }
358         });
359     }
360 
write_unknown_fields(&self, w: &mut CodeWriter)361     fn write_unknown_fields(&self, w: &mut CodeWriter) {
362         let sig = format!(
363             "special_fields(&self) -> &{}::SpecialFields",
364             protobuf_crate_path(&self.customize.for_elem)
365         );
366         w.def_fn(&sig, |w| {
367             w.write_line("&self.special_fields");
368         });
369         w.write_line("");
370         let sig = format!(
371             "mut_special_fields(&mut self) -> &mut {}::SpecialFields",
372             protobuf_crate_path(&self.customize.for_elem)
373         );
374         w.def_fn(&sig, |w| {
375             w.write_line("&mut self.special_fields");
376         });
377     }
378 
write_merge_from(&self, w: &mut CodeWriter)379     fn write_merge_from(&self, w: &mut CodeWriter) {
380         let sig = format!(
381             "merge_from(&mut self, is: &mut {}::CodedInputStream<'_>) -> {}::Result<()>",
382             protobuf_crate_path(&self.customize.for_elem),
383             protobuf_crate_path(&self.customize.for_elem),
384         );
385         w.def_fn(&sig, |w| {
386             w.while_block("let Some(tag) = is.read_raw_tag_or_eof()?", |w| {
387                 w.match_block("tag", |w| {
388                     for f in &self.fields_except_group() {
389                         f.write_merge_from_field_case_block(w);
390                     }
391                     w.case_block("tag", |w| {
392                         w.write_line(&format!("{}::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;", protobuf_crate_path(&self.customize.for_elem)));
393                     });
394                 });
395             });
396             w.write_line("::std::result::Result::Ok(())");
397         });
398     }
399 
write_impl_message_full_fn_descriptor(&self, w: &mut CodeWriter)400     fn write_impl_message_full_fn_descriptor(&self, w: &mut CodeWriter) {
401         write_fn_descriptor(
402             &self.message.message,
403             self.message.scope(),
404             &self.customize.for_elem,
405             w,
406         );
407     }
408 
write_generated_message_descriptor_data(&self, w: &mut CodeWriter)409     fn write_generated_message_descriptor_data(&self, w: &mut CodeWriter) {
410         let sig = format!(
411             "generated_message_descriptor_data() -> {}::reflect::GeneratedMessageDescriptorData",
412             protobuf_crate_path(&self.customize.for_elem)
413         );
414         w.fn_block(
415             Visibility::Path(self.message.scope().rust_path_to_file().to_reverse()),
416             &sig,
417             |w| {
418                 let fields = self.fields_except_group();
419                 let oneofs = self.oneofs();
420                 w.write_line(&format!(
421                     "let mut fields = {};",
422                     expr_vec_with_capacity_const(fields.len())
423                 ));
424                 w.write_line(&format!(
425                     "let mut oneofs = {};",
426                     expr_vec_with_capacity_const(oneofs.len())
427                 ));
428                 for field in fields {
429                     field.write_push_accessor("fields", w);
430                 }
431                 for oneof in oneofs {
432                     w.write_line(&format!(
433                         "oneofs.push({}::generated_oneof_descriptor_data());",
434                         oneof.type_name_relative(&self.mod_name())
435                     ));
436                 }
437                 w.write_line(&format!(
438                     "{}::reflect::GeneratedMessageDescriptorData::new_2::<{}>(",
439                     protobuf_crate_path(&self.customize.for_elem),
440                     self.rust_name(),
441                 ));
442                 w.indented(|w| {
443                     w.write_line(&format!("\"{}\",", self.message.name_to_package()));
444                     w.write_line("fields,");
445                     w.write_line("oneofs,");
446                 });
447                 w.write_line(")");
448             },
449         );
450     }
451 
write_is_initialized(&self, w: &mut CodeWriter)452     fn write_is_initialized(&self, w: &mut CodeWriter) {
453         w.def_fn(&format!("is_initialized(&self) -> bool"), |w| {
454             if !self.message.message.is_initialized_is_always_true() {
455                 // TODO: use single loop
456 
457                 for f in self.required_fields() {
458                     f.write_if_self_field_is_none(w, |w| {
459                         w.write_line("return false;");
460                     });
461                 }
462 
463                 for f in self.message_fields() {
464                     if let FieldKind::Map(..) = f.kind {
465                         // TODO
466                         w.comment("TODO: check map values are initialized");
467                         continue;
468                     }
469 
470                     f.write_for_self_field(w, "v", |w, _t| {
471                         w.if_stmt("!v.is_initialized()", |w| {
472                             w.write_line("return false;");
473                         });
474                     });
475                 }
476             }
477             w.write_line("true");
478         });
479     }
480 
write_impl_message(&self, w: &mut CodeWriter)481     fn write_impl_message(&self, w: &mut CodeWriter) {
482         w.impl_for_block(
483             &format!("{}::Message", protobuf_crate_path(&self.customize.for_elem),),
484             &format!("{}", self.rust_name()),
485             |w| {
486                 w.write_line(&format!(
487                     "const NAME: &'static str = \"{}\";",
488                     self.message.message.name()
489                 ));
490                 w.write_line("");
491                 self.write_is_initialized(w);
492                 w.write_line("");
493                 self.write_merge_from(w);
494                 w.write_line("");
495                 self.write_compute_size(w);
496                 w.write_line("");
497                 self.write_write_to_with_cached_sizes(w);
498                 w.write_line("");
499                 self.write_unknown_fields(w);
500                 w.write_line("");
501                 w.def_fn(&format!("new() -> {}", self.rust_name()), |w| {
502                     w.write_line(&format!("{}::new()", self.rust_name()));
503                 });
504                 w.write_line("");
505                 w.def_fn("clear(&mut self)", |w| {
506                     for f in self.fields_except_group() {
507                         f.write_clear(w);
508                     }
509                     w.write_line("self.special_fields.clear();");
510                 });
511                 w.write_line("");
512                 self.write_default_instance(w);
513             },
514         );
515     }
516 
write_impl_message_full(&self, w: &mut CodeWriter)517     fn write_impl_message_full(&self, w: &mut CodeWriter) {
518         w.impl_for_block(
519             &format!(
520                 "{}::MessageFull",
521                 protobuf_crate_path(&self.customize.for_elem),
522             ),
523             &format!("{}", self.rust_name()),
524             |w| {
525                 self.write_impl_message_full_fn_descriptor(w);
526             },
527         );
528     }
529 
write_impl_value(&self, w: &mut CodeWriter)530     fn write_impl_value(&self, w: &mut CodeWriter) {
531         w.impl_for_block(
532             &format!(
533                 "{}::reflect::ProtobufValue",
534                 protobuf_crate_path(&self.customize.for_elem)
535             ),
536             &format!("{}", self.rust_name()),
537             |w| {
538                 w.write_line(&format!(
539                     "type RuntimeType = {}::reflect::rt::RuntimeTypeMessage<Self>;",
540                     protobuf_crate_path(&self.customize.for_elem)
541                 ));
542             },
543         )
544     }
545 
write_impl_display(&self, w: &mut CodeWriter)546     fn write_impl_display(&self, w: &mut CodeWriter) {
547         w.impl_for_block(
548             "::std::fmt::Display",
549             &format!("{}", self.rust_name()),
550             |w| {
551                 w.def_fn(
552                     "fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result",
553                     |w| {
554                         w.write_line(&format!(
555                             "{}::text_format::fmt(self, f)",
556                             protobuf_crate_path(&self.customize.for_elem)
557                         ));
558                     },
559                 );
560             },
561         );
562     }
563 
supports_derive_partial_eq(&self) -> bool564     fn supports_derive_partial_eq(&self) -> bool {
565         // There's stack overflow in the compiler when struct has too many fields
566         // https://github.com/rust-lang/rust/issues/40119
567         self.fields.len() <= 500
568     }
569 
write_struct(&self, w: &mut CodeWriter)570     fn write_struct(&self, w: &mut CodeWriter) {
571         let mut derive = Vec::new();
572         if self.supports_derive_partial_eq() {
573             derive.push("PartialEq");
574         }
575         derive.extend(&["Clone", "Default", "Debug"]);
576         w.derive(&derive);
577         write_protoc_insertion_point_for_message(
578             w,
579             &self.customize.for_elem,
580             &self.message_descriptor,
581         );
582         w.pub_struct(&format!("{}", self.rust_name()), |w| {
583             if !self.fields_except_oneof().is_empty() {
584                 w.comment("message fields");
585                 for field in self.fields_except_oneof() {
586                     field.write_struct_field(w);
587                 }
588             }
589             if !self.oneofs().is_empty() {
590                 w.comment("message oneof groups");
591                 for oneof in self.oneofs() {
592                     w.field_decl_vis(
593                         Visibility::Public,
594                         &oneof.oneof.field_name().to_string(),
595                         &oneof.full_storage_type().to_code(&self.customize.for_elem),
596                     );
597                 }
598             }
599             w.comment("special fields");
600 
601             let customize_special_fields = self
602                 .customize
603                 .child(
604                     &Customize::default(),
605                     &SpecialFieldPseudoDescriptor {
606                         message: &self.message.message,
607                         field: "special_fields",
608                     },
609                 )
610                 .for_elem;
611 
612             write_protoc_insertion_point_for_special_field(
613                 w,
614                 &customize_special_fields,
615                 &self.message_descriptor,
616                 "special_fields",
617             );
618             w.pub_field_decl(
619                 "special_fields",
620                 &format!(
621                     "{}::SpecialFields",
622                     protobuf_crate_path(&self.customize.for_elem)
623                 ),
624             );
625         });
626     }
627 
write_impl_default_for_amp(&self, w: &mut CodeWriter)628     fn write_impl_default_for_amp(&self, w: &mut CodeWriter) {
629         w.impl_args_for_block(
630             &["'a"],
631             "::std::default::Default",
632             &format!("&'a {}", self.rust_name()),
633             |w| {
634                 w.def_fn(&format!("default() -> &'a {}", self.rust_name()), |w| {
635                     w.write_line(&format!(
636                         "<{} as {}::Message>::default_instance()",
637                         self.rust_name(),
638                         protobuf_crate_path(&self.customize.for_elem),
639                     ));
640                 });
641             },
642         );
643     }
644 
write_dummy_impl_partial_eq(&self, w: &mut CodeWriter)645     fn write_dummy_impl_partial_eq(&self, w: &mut CodeWriter) {
646         w.impl_for_block(
647             "::std::cmp::PartialEq",
648             &format!("{}", self.rust_name()),
649             |w| {
650                 w.def_fn("eq(&self, _: &Self) -> bool", |w| {
651                     w.comment("https://github.com/rust-lang/rust/issues/40119");
652                     w.unimplemented();
653                 });
654             },
655         );
656     }
657 
write(&self, w: &mut CodeWriter) -> anyhow::Result<()>658     pub fn write(&self, w: &mut CodeWriter) -> anyhow::Result<()> {
659         w.all_documentation(self.info, self.path);
660         self.write_struct(w);
661 
662         w.write_line("");
663         self.write_impl_default_for_amp(w);
664 
665         if !self.supports_derive_partial_eq() {
666             w.write_line("");
667             self.write_dummy_impl_partial_eq(w);
668         }
669 
670         w.write_line("");
671         self.write_impl_self(w);
672         w.write_line("");
673         self.write_impl_message(w);
674         if !self.lite_runtime {
675             w.write_line("");
676             self.write_impl_message_full(w);
677         }
678         if !self.lite_runtime {
679             w.write_line("");
680             self.write_impl_display(w);
681 
682             w.write_line("");
683             self.write_impl_value(w);
684         }
685 
686         let mod_name = message_name_to_nested_mod_name(&self.message.message.name());
687 
688         let oneofs = self.oneofs();
689         let nested_messages: Vec<_> = self
690             .message
691             .to_scope()
692             .messages()
693             .into_iter()
694             .filter(|nested| {
695                 // ignore map entries, because they are not used in map fields
696                 !nested.is_map()
697             })
698             .collect();
699         let nested_enums = self.message.to_scope().enums();
700 
701         if !oneofs.is_empty() || !nested_messages.is_empty() || !nested_enums.is_empty() {
702             w.write_line("");
703             w.write_line(&format!(
704                 "/// Nested message and enums of message `{}`",
705                 self.message.message.name()
706             ));
707             w.pub_mod(&mod_name.to_string(), |w| {
708                 let mut first = true;
709 
710                 for oneof in &oneofs {
711                     w.write_line("");
712                     oneof.write(w);
713                 }
714 
715                 static NESTED_TYPE_NUMBER: protobuf::rt::Lazy<i32> = protobuf::rt::Lazy::new();
716                 let nested_type_number = *NESTED_TYPE_NUMBER.get(|| {
717                     MessageDescriptor::for_type::<DescriptorProto>()
718                         .field_by_name("nested_type")
719                         .expect("`nested_type` must exist")
720                         .proto()
721                         .number()
722                 });
723 
724                 let mut path = self.path.to_vec();
725                 path.extend(&[nested_type_number, 0]);
726                 for (id, nested) in nested_messages.iter().enumerate() {
727                     let len = path.len() - 1;
728                     path[len] = id as i32;
729 
730                     if !first {
731                         w.write_line("");
732                     }
733                     first = false;
734                     MessageGen::new(
735                         &self.file_descriptor,
736                         nested,
737                         self.root_scope,
738                         &self.customize,
739                         &path,
740                         self.info,
741                     )
742                     // TODO: do not unwrap.
743                     .unwrap()
744                     .write(w)
745                     // TODO: do not unwrap.
746                     .unwrap();
747                 }
748 
749                 static ENUM_TYPE_NUMBER: protobuf::rt::Lazy<i32> = protobuf::rt::Lazy::new();
750                 let enum_type_number = *ENUM_TYPE_NUMBER.get(|| {
751                     MessageDescriptor::for_type::<DescriptorProto>()
752                         .field_by_name("enum_type")
753                         .expect("`enum_type` must exist")
754                         .proto()
755                         .number()
756                 });
757 
758                 let len = path.len() - 2;
759                 path[len] = enum_type_number;
760                 for (id, enum_type) in self.message.to_scope().enums().iter().enumerate() {
761                     let len = path.len() - 1;
762                     path[len] = id as i32;
763 
764                     if !first {
765                         w.write_line("");
766                     }
767                     first = false;
768                     EnumGen::new(
769                         enum_type,
770                         &self.customize,
771                         self.root_scope,
772                         &path,
773                         self.info,
774                     )
775                     .write(w);
776                 }
777             });
778         }
779         Ok(())
780     }
781 }
782 
message_name_to_nested_mod_name(message_name: &str) -> RustIdent783 pub(crate) fn message_name_to_nested_mod_name(message_name: &str) -> RustIdent {
784     let mod_name = snake_case(message_name);
785     RustIdent::new(&mod_name)
786 }
787