1 mod accessor;
2 pub(crate) mod elem;
3 mod option_kind;
4 mod repeated;
5 mod singular;
6 mod tag;
7 pub(crate) mod type_ext;
8 
9 use protobuf::descriptor::field_descriptor_proto::Type;
10 use protobuf::descriptor::*;
11 use protobuf::reflect::ReflectValueRef;
12 use protobuf::reflect::RuntimeFieldType;
13 use protobuf::reflect::Syntax;
14 use protobuf::rt;
15 use protobuf::rt::WireType;
16 use protobuf_parse::camel_case;
17 use protobuf_parse::ProtobufAbsPath;
18 
19 use crate::customize::ctx::CustomizeElemCtx;
20 use crate::customize::rustproto_proto::customize_from_rustproto_for_field;
21 use crate::customize::Customize;
22 use crate::gen::code_writer::CodeWriter;
23 use crate::gen::code_writer::Visibility;
24 use crate::gen::field::elem::field_elem;
25 use crate::gen::field::elem::FieldElem;
26 use crate::gen::field::elem::FieldElemEnum;
27 use crate::gen::field::elem::HowToGetMessageSize;
28 use crate::gen::field::option_kind::OptionKind;
29 use crate::gen::field::repeated::RepeatedField;
30 use crate::gen::field::singular::SingularField;
31 use crate::gen::field::singular::SingularFieldFlag;
32 use crate::gen::field::tag::make_tag;
33 use crate::gen::field::type_ext::TypeExt;
34 use crate::gen::file_and_mod::FileAndMod;
35 use crate::gen::inside::protobuf_crate_path;
36 use crate::gen::map::map_entry;
37 use crate::gen::oneof::OneofField;
38 use crate::gen::protoc_insertion_point::write_protoc_insertion_point_for_field;
39 use crate::gen::rust::ident::RustIdent;
40 use crate::gen::rust::quote::quote_escape_bytes;
41 use crate::gen::rust::quote::quote_escape_str;
42 use crate::gen::rust::snippets::EXPR_NONE;
43 use crate::gen::rust_types_values::PrimitiveTypeVariant;
44 use crate::gen::rust_types_values::RustType;
45 use crate::gen::rust_types_values::RustValueTyped;
46 use crate::gen::scope::FieldWithContext;
47 use crate::gen::scope::MessageWithScope;
48 use crate::gen::scope::RootScope;
49 
field_type_protobuf_name<'a>(field: &'a FieldDescriptorProto) -> &'a str50 fn field_type_protobuf_name<'a>(field: &'a FieldDescriptorProto) -> &'a str {
51     if field.has_type_name() {
52         field.type_name()
53     } else {
54         field.type_().protobuf_name()
55     }
56 }
57 
58 #[derive(Clone)]
59 pub struct MapField<'a> {
60     _message: MessageWithScope<'a>,
61     key: FieldElem<'a>,
62     value: FieldElem<'a>,
63 }
64 
65 #[derive(Clone)]
66 pub(crate) enum FieldKind<'a> {
67     // optional or required
68     Singular(SingularField<'a>),
69     // repeated except map
70     Repeated(RepeatedField<'a>),
71     // map
72     Map(MapField<'a>),
73     // part of oneof
74     Oneof(OneofField<'a>),
75 }
76 
77 impl<'a> FieldKind<'a> {
default( &self, customize: &Customize, reference: &FileAndMod, const_expr: bool, ) -> String78     pub(crate) fn default(
79         &self,
80         customize: &Customize,
81         reference: &FileAndMod,
82         const_expr: bool,
83     ) -> String {
84         match self {
85             FieldKind::Singular(s) => s.default_value(customize, reference, const_expr),
86             FieldKind::Repeated(r) => r.default(),
87             FieldKind::Oneof(..) => EXPR_NONE.to_owned(),
88             FieldKind::Map(..) => panic!("map fields cannot have field value"),
89         }
90     }
91 }
92 
93 #[derive(Clone)]
94 pub(crate) enum SingularOrOneofField<'a> {
95     Singular(SingularField<'a>),
96     Oneof(OneofField<'a>),
97 }
98 
99 impl<'a> SingularOrOneofField<'a> {
elem(&self) -> &FieldElem100     fn elem(&self) -> &FieldElem {
101         match self {
102             SingularOrOneofField::Singular(SingularField { ref elem, .. }) => elem,
103             SingularOrOneofField::Oneof(OneofField { ref elem, .. }) => elem,
104         }
105     }
106 
107     // Type of `xxx` function for singular type.
getter_return_type(&self, reference: &FileAndMod) -> RustType108     pub(crate) fn getter_return_type(&self, reference: &FileAndMod) -> RustType {
109         let elem = self.elem();
110         if let FieldElem::Enum(ref en) = elem {
111             en.enum_rust_type(reference)
112         } else if elem.is_copy() {
113             elem.rust_storage_elem_type(reference)
114         } else {
115             elem.rust_storage_elem_type(reference).ref_type()
116         }
117     }
118 }
119 
120 // Representation of map entry: key type and value type
121 #[derive(Clone, Debug)]
122 pub struct EntryKeyValue<'a>(FieldElem<'a>, FieldElem<'a>);
123 
124 #[derive(Clone)]
125 pub(crate) struct FieldGen<'a> {
126     syntax: Syntax,
127     pub proto_field: FieldWithContext<'a>,
128     // field name in generated code
129     pub rust_name: RustIdent,
130     pub proto_type: Type,
131     wire_type: WireType,
132     pub kind: FieldKind<'a>,
133     pub generate_accessors: bool,
134     pub generate_getter: bool,
135     customize: Customize,
136     path: Vec<i32>,
137     info: Option<&'a SourceCodeInfo>,
138 }
139 
140 impl<'a> FieldGen<'a> {
parse( field: FieldWithContext<'a>, root_scope: &'a RootScope<'a>, parent_customize: &CustomizeElemCtx<'a>, path: Vec<i32>, info: Option<&'a SourceCodeInfo>, ) -> anyhow::Result<FieldGen<'a>>141     pub(crate) fn parse(
142         field: FieldWithContext<'a>,
143         root_scope: &'a RootScope<'a>,
144         parent_customize: &CustomizeElemCtx<'a>,
145         path: Vec<i32>,
146         info: Option<&'a SourceCodeInfo>,
147     ) -> anyhow::Result<FieldGen<'a>> {
148         let customize = parent_customize
149             .child(
150                 &customize_from_rustproto_for_field(field.field.proto().options.get_or_default()),
151                 &field.field,
152             )
153             .for_elem;
154 
155         let syntax = field.message.scope.file_scope.syntax();
156 
157         let field_may_have_custom_default_value = syntax == Syntax::Proto2
158             && field.field.proto().label() != field_descriptor_proto::Label::LABEL_REPEATED
159             && field.field.proto().type_() != Type::TYPE_MESSAGE;
160 
161         let generate_accessors = customize
162             .generate_accessors
163             .unwrap_or(field_may_have_custom_default_value)
164             || field.is_oneof();
165 
166         let default_generate_getter = generate_accessors || field_may_have_custom_default_value;
167         let generate_getter =
168             customize.generate_getter.unwrap_or(default_generate_getter) || field.is_oneof();
169 
170         let kind = match field.field.runtime_field_type() {
171             RuntimeFieldType::Map(..) => {
172                 let message = root_scope
173                     .find_message(&ProtobufAbsPath::from(field.field.proto().type_name()));
174 
175                 let (key, value) = map_entry(&message).unwrap();
176 
177                 let key = field_elem(&key, root_scope, &customize);
178                 let value = field_elem(&value, root_scope, &customize);
179 
180                 FieldKind::Map(MapField {
181                     _message: message,
182                     key,
183                     value,
184                 })
185             }
186             RuntimeFieldType::Repeated(..) => {
187                 let elem = field_elem(&field, root_scope, &customize);
188 
189                 FieldKind::Repeated(RepeatedField {
190                     elem,
191                     packed: field.field.proto().options.get_or_default().packed(),
192                 })
193             }
194             RuntimeFieldType::Singular(..) => {
195                 let elem = field_elem(&field, root_scope, &customize);
196 
197                 if let Some(oneof) = field.oneof() {
198                     FieldKind::Oneof(OneofField::parse(&oneof, &field.field, elem, root_scope))
199                 } else {
200                     let flag = if field.message.scope.file_scope.syntax() == Syntax::Proto3
201                         && field.field.proto().type_() != field_descriptor_proto::Type::TYPE_MESSAGE
202                         && !field.field.proto().proto3_optional()
203                     {
204                         SingularFieldFlag::WithoutFlag
205                     } else {
206                         let required = field.field.proto().label()
207                             == field_descriptor_proto::Label::LABEL_REQUIRED;
208                         let option_kind = match field.field.proto().type_() {
209                             field_descriptor_proto::Type::TYPE_MESSAGE => OptionKind::MessageField,
210                             _ => OptionKind::Option,
211                         };
212 
213                         SingularFieldFlag::WithFlag {
214                             required,
215                             option_kind,
216                         }
217                     };
218                     FieldKind::Singular(SingularField { elem, flag })
219                 }
220             }
221         };
222 
223         Ok(FieldGen {
224             syntax: field.message.message.file_descriptor().syntax(),
225             rust_name: rust_field_name_for_protobuf_field_name(&field.field.name()),
226             proto_type: field.field.proto().type_(),
227             wire_type: WireType::for_type(field.field.proto().type_()),
228             proto_field: field,
229             kind,
230             generate_accessors,
231             generate_getter,
232             customize,
233             path,
234             info,
235         })
236     }
237 
238     // for message level
file_and_mod(&self) -> FileAndMod239     fn file_and_mod(&self) -> FileAndMod {
240         self.proto_field
241             .message
242             .scope
243             .file_and_mod(self.customize.clone())
244     }
245 
tag_size(&self) -> u32246     fn tag_size(&self) -> u32 {
247         rt::tag_size(self.proto_field.number() as u32) as u32
248     }
249 
is_singular(&self) -> bool250     fn is_singular(&self) -> bool {
251         match self.kind {
252             FieldKind::Singular(..) => true,
253             _ => false,
254         }
255     }
256 
is_repeated_packed(&self) -> bool257     fn is_repeated_packed(&self) -> bool {
258         match self.kind {
259             FieldKind::Repeated(RepeatedField { packed: true, .. }) => true,
260             _ => false,
261         }
262     }
263 
elem(&self) -> &FieldElem264     pub(crate) fn elem(&self) -> &FieldElem {
265         match self.kind {
266             FieldKind::Singular(SingularField { ref elem, .. }) => &elem,
267             FieldKind::Repeated(RepeatedField { ref elem, .. }) => &elem,
268             FieldKind::Oneof(OneofField { ref elem, .. }) => &elem,
269             FieldKind::Map(..) => unreachable!(),
270         }
271     }
272 
273     // type of field in struct
full_storage_type(&self, reference: &FileAndMod) -> RustType274     pub(crate) fn full_storage_type(&self, reference: &FileAndMod) -> RustType {
275         match self.kind {
276             FieldKind::Repeated(ref repeated) => repeated.rust_type(reference),
277             FieldKind::Map(MapField {
278                 ref key, ref value, ..
279             }) => RustType::HashMap(
280                 Box::new(key.rust_storage_elem_type(reference)),
281                 Box::new(value.rust_storage_elem_type(reference)),
282             ),
283             FieldKind::Singular(ref singular) => singular.rust_storage_type(reference),
284             FieldKind::Oneof(..) => unreachable!(),
285         }
286     }
287 
288     // type of `v` in `for v in field`
full_storage_iter_elem_type(&self, reference: &FileAndMod) -> RustType289     fn full_storage_iter_elem_type(&self, reference: &FileAndMod) -> RustType {
290         if let FieldKind::Oneof(ref oneof) = self.kind {
291             oneof.elem.rust_storage_elem_type(reference)
292         } else {
293             self.full_storage_type(reference).iter_elem_type()
294         }
295     }
296 
297     // suffix `xxx` as in `os.write_xxx_no_tag(..)`
os_write_fn_suffix(&self) -> &str298     fn os_write_fn_suffix(&self) -> &str {
299         self.proto_type.protobuf_name()
300     }
301 
os_write_fn_suffix_with_unknown_for_enum(&self) -> &str302     fn os_write_fn_suffix_with_unknown_for_enum(&self) -> &str {
303         if self.proto_type == field_descriptor_proto::Type::TYPE_ENUM {
304             "enum_or_unknown"
305         } else {
306             self.os_write_fn_suffix()
307         }
308     }
309 
310     // for field `foo`, type of param of `fn set_foo(..)`
set_xxx_param_type(&self, reference: &FileAndMod) -> RustType311     fn set_xxx_param_type(&self, reference: &FileAndMod) -> RustType {
312         match self.kind {
313             FieldKind::Singular(SingularField { ref elem, .. })
314             | FieldKind::Oneof(OneofField { ref elem, .. }) => {
315                 elem.rust_set_xxx_param_type(reference)
316             }
317             FieldKind::Repeated(..) | FieldKind::Map(..) => self.full_storage_type(reference),
318         }
319     }
320 
321     // for field `foo`, return type if `fn take_foo(..)`
take_xxx_return_type(&self, reference: &FileAndMod) -> RustType322     fn take_xxx_return_type(&self, reference: &FileAndMod) -> RustType {
323         self.set_xxx_param_type(reference)
324     }
325 
326     // for field `foo`, return type of `fn mut_foo(..)`
mut_xxx_return_type(&self, reference: &FileAndMod) -> RustType327     fn mut_xxx_return_type(&self, reference: &FileAndMod) -> RustType {
328         RustType::Ref(Box::new(match self.kind {
329             FieldKind::Singular(SingularField { ref elem, .. })
330             | FieldKind::Oneof(OneofField { ref elem, .. }) => {
331                 elem.rust_storage_elem_type(reference)
332             }
333             FieldKind::Repeated(..) | FieldKind::Map(..) => self.full_storage_type(reference),
334         }))
335     }
336 
337     // for field `foo`, return type of `fn foo(..)`
getter_return_type(&self) -> RustType338     fn getter_return_type(&self) -> RustType {
339         let reference = self
340             .proto_field
341             .message
342             .scope
343             .file_and_mod(self.customize.clone());
344         match &self.kind {
345             FieldKind::Singular(s) => {
346                 SingularOrOneofField::Singular(s.clone()).getter_return_type(&reference)
347             }
348             FieldKind::Oneof(o) => {
349                 SingularOrOneofField::Oneof(o.clone()).getter_return_type(&reference)
350             }
351             FieldKind::Repeated(RepeatedField { ref elem, .. }) => RustType::Ref(Box::new(
352                 RustType::Slice(Box::new(elem.rust_storage_elem_type(&reference))),
353             )),
354             FieldKind::Map(..) => RustType::Ref(Box::new(self.full_storage_type(&reference))),
355         }
356     }
357 
358     // elem data is not stored in heap
elem_type_is_copy(&self) -> bool359     pub(crate) fn elem_type_is_copy(&self) -> bool {
360         self.proto_type.is_copy()
361     }
362 
defaut_value_from_proto_float(f: f64, type_name: &str) -> String363     fn defaut_value_from_proto_float(f: f64, type_name: &str) -> String {
364         if f.is_nan() {
365             format!("::std::{}::NAN", type_name)
366         } else if f.is_infinite() {
367             if f > 0.0 {
368                 format!("::std::{}::INFINITY", type_name)
369             } else {
370                 format!("::std::{}::NEG_INFINITY", type_name)
371             }
372         } else {
373             format!("{:?}{}", f, type_name)
374         }
375     }
376 
singular_or_oneof_default_value_from_proto(&self, elem: &FieldElem) -> Option<String>377     fn singular_or_oneof_default_value_from_proto(&self, elem: &FieldElem) -> Option<String> {
378         if !self.proto_field.field.proto().has_default_value() {
379             return None;
380         }
381 
382         let default_value = self.proto_field.field.singular_default_value();
383         Some(match default_value {
384             ReflectValueRef::Bool(b) => format!("{}", b),
385             ReflectValueRef::I32(v) => format!("{}i32", v),
386             ReflectValueRef::I64(v) => format!("{}i64", v),
387             ReflectValueRef::U32(v) => format!("{}u32", v),
388             ReflectValueRef::U64(v) => format!("{}u64", v),
389             ReflectValueRef::String(v) => quote_escape_str(v),
390             ReflectValueRef::Bytes(v) => quote_escape_bytes(v),
391             ReflectValueRef::F32(v) => Self::defaut_value_from_proto_float(v as f64, "f32"),
392             ReflectValueRef::F64(v) => Self::defaut_value_from_proto_float(v as f64, "f64"),
393             ReflectValueRef::Enum(_e, _v) => {
394                 if let &FieldElem::Enum(ref e) = elem {
395                     format!("{}", e.default_value_rust_expr(&self.file_and_mod()))
396                 } else {
397                     unreachable!()
398                 }
399             }
400             t => panic!("default value is not implemented for type: {:?}", t),
401         })
402     }
403 
default_value_from_proto(&self) -> Option<String>404     fn default_value_from_proto(&self) -> Option<String> {
405         match self.kind {
406             FieldKind::Oneof(OneofField { ref elem, .. })
407             | FieldKind::Singular(SingularField { ref elem, .. }) => {
408                 self.singular_or_oneof_default_value_from_proto(elem)
409             }
410             _ => unreachable!(),
411         }
412     }
413 
default_value_from_proto_typed(&self) -> Option<RustValueTyped>414     fn default_value_from_proto_typed(&self) -> Option<RustValueTyped> {
415         self.default_value_from_proto().map(|v| {
416             let default_value_type = match self.proto_type {
417                 field_descriptor_proto::Type::TYPE_STRING => RustType::Ref(Box::new(RustType::Str)),
418                 field_descriptor_proto::Type::TYPE_BYTES => {
419                     RustType::Ref(Box::new(RustType::Slice(Box::new(RustType::u8()))))
420                 }
421                 _ => self.full_storage_iter_elem_type(
422                     &self
423                         .proto_field
424                         .message
425                         .scope
426                         .file_and_mod(self.customize.clone()),
427                 ),
428             };
429 
430             RustValueTyped {
431                 value: v,
432                 rust_type: default_value_type,
433             }
434         })
435     }
436 
437     // default value to be returned from `fn xxx` for field `xxx`.
xxx_default_value_rust(&self) -> String438     fn xxx_default_value_rust(&self) -> String {
439         match self.kind {
440             FieldKind::Singular(..) | FieldKind::Oneof(..) => {
441                 self.default_value_from_proto().unwrap_or_else(|| {
442                     self.getter_return_type()
443                         .default_value(&self.customize, false)
444                 })
445             }
446             _ => unreachable!(),
447         }
448     }
449 
450     // default to be assigned to field
element_default_value_rust(&self) -> RustValueTyped451     fn element_default_value_rust(&self) -> RustValueTyped {
452         match self.kind {
453             FieldKind::Singular(..) | FieldKind::Oneof(..) => {
454                 self.default_value_from_proto_typed().unwrap_or_else(|| {
455                     self.elem()
456                         .rust_storage_elem_type(
457                             &self
458                                 .proto_field
459                                 .message
460                                 .scope
461                                 .file_and_mod(self.customize.clone()),
462                         )
463                         .default_value_typed(&self.customize, false)
464                 })
465             }
466             _ => unreachable!(),
467         }
468     }
469 
reconstruct_def(&self) -> String470     pub(crate) fn reconstruct_def(&self) -> String {
471         let prefix = match (self.proto_field.field.proto().label(), self.syntax) {
472             (field_descriptor_proto::Label::LABEL_REPEATED, _) => "repeated ",
473             (_, Syntax::Proto3) => "",
474             (field_descriptor_proto::Label::LABEL_OPTIONAL, _) => "optional ",
475             (field_descriptor_proto::Label::LABEL_REQUIRED, _) => "required ",
476         };
477         format!(
478             "{}{} {} = {}",
479             prefix,
480             field_type_protobuf_name(self.proto_field.field.proto()),
481             self.proto_field.name(),
482             self.proto_field.number()
483         )
484     }
485 
write_clear(&self, w: &mut CodeWriter)486     pub(crate) fn write_clear(&self, w: &mut CodeWriter) {
487         match self.kind {
488             FieldKind::Oneof(ref o) => {
489                 w.write_line(&format!(
490                     "self.{} = ::std::option::Option::None;",
491                     o.oneof_field_name
492                 ));
493             }
494             _ => {
495                 let clear_expr = self
496                     .full_storage_type(
497                         &self
498                             .proto_field
499                             .message
500                             .scope
501                             .file_and_mod(self.customize.clone()),
502                     )
503                     .clear(&self.self_field(), &self.customize);
504                 w.write_line(&format!("{};", clear_expr));
505             }
506         }
507     }
508 
509     // output code that writes single element to stream
write_write_element( &self, elem: &FieldElem, w: &mut CodeWriter, os: &str, v: &RustValueTyped, )510     pub(crate) fn write_write_element(
511         &self,
512         elem: &FieldElem,
513         w: &mut CodeWriter,
514         os: &str,
515         v: &RustValueTyped,
516     ) {
517         assert!(!self.is_repeated_packed());
518 
519         elem.write_write_element(
520             self.proto_field.number() as u32,
521             v,
522             &self.file_and_mod(),
523             &self.customize,
524             os,
525             w,
526         );
527     }
528 
self_field(&self) -> String529     fn self_field(&self) -> String {
530         format!("self.{}", self.rust_name)
531     }
532 
self_field_is_some(&self) -> String533     fn self_field_is_some(&self) -> String {
534         assert!(self.is_singular());
535         format!("{}.is_some()", self.self_field())
536     }
537 
self_field_is_none(&self) -> String538     fn self_field_is_none(&self) -> String {
539         assert!(self.is_singular());
540         format!("{}.is_none()", self.self_field())
541     }
542 
543     // field data viewed as Option
self_field_as_option(&self, elem: &FieldElem, option_kind: OptionKind) -> RustValueTyped544     fn self_field_as_option(&self, elem: &FieldElem, option_kind: OptionKind) -> RustValueTyped {
545         match self.full_storage_type(
546             &self
547                 .proto_field
548                 .message
549                 .scope
550                 .file_and_mod(self.customize.clone()),
551         ) {
552             RustType::Option(ref e) if e.is_copy() => {
553                 return RustType::Option(e.clone()).value(self.self_field());
554             }
555             _ => {}
556         };
557 
558         let as_option_type = option_kind.as_ref_type(
559             elem.rust_storage_elem_type(
560                 &self
561                     .proto_field
562                     .message
563                     .scope
564                     .file_and_mod(self.customize.clone()),
565             ),
566         );
567 
568         as_option_type.value(format!("{}.as_ref()", self.self_field()))
569     }
570 
write_struct_field(&self, w: &mut CodeWriter)571     pub(crate) fn write_struct_field(&self, w: &mut CodeWriter) {
572         if self.proto_type == field_descriptor_proto::Type::TYPE_GROUP {
573             w.comment(&format!("{}: <group>", &self.rust_name));
574         } else {
575             w.all_documentation(self.info, &self.path);
576 
577             write_protoc_insertion_point_for_field(w, &self.customize, &self.proto_field.field);
578             w.field_decl_vis(
579                 Visibility::Public,
580                 &self.rust_name.to_string(),
581                 &self
582                     .full_storage_type(
583                         &self
584                             .proto_field
585                             .message
586                             .scope
587                             .file_and_mod(self.customize.clone()),
588                     )
589                     .to_code(&self.customize),
590             );
591         }
592     }
593 
write_if_let_self_field_is_some<F>(&self, s: &SingularField, w: &mut CodeWriter, cb: F) where F: Fn(&RustValueTyped, &mut CodeWriter),594     fn write_if_let_self_field_is_some<F>(&self, s: &SingularField, w: &mut CodeWriter, cb: F)
595     where
596         F: Fn(&RustValueTyped, &mut CodeWriter),
597     {
598         match s {
599             SingularField {
600                 flag: SingularFieldFlag::WithFlag { option_kind, .. },
601                 ref elem,
602             } => {
603                 let var = "v";
604                 let ref_prefix = match elem
605                     .rust_storage_elem_type(
606                         &self
607                             .proto_field
608                             .message
609                             .scope
610                             .file_and_mod(self.customize.clone()),
611                     )
612                     .is_copy()
613                 {
614                     true => "",
615                     false => "",
616                 };
617                 let as_option = self.self_field_as_option(elem, *option_kind);
618                 w.if_let_stmt(
619                     &format!("Some({}{})", ref_prefix, var),
620                     &as_option.value,
621                     |w| {
622                         let v = RustValueTyped {
623                             value: var.to_owned(),
624                             rust_type: as_option.rust_type.elem_type(),
625                         };
626                         cb(&v, w);
627                     },
628                 );
629             }
630             SingularField {
631                 flag: SingularFieldFlag::WithoutFlag,
632                 ref elem,
633             } => match *elem {
634                 FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)
635                 | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => {
636                     w.if_stmt(format!("!{}.is_empty()", self.self_field()), |w| {
637                         let v = RustValueTyped {
638                             value: self.self_field(),
639                             rust_type: self.full_storage_type(
640                                 &self
641                                     .proto_field
642                                     .message
643                                     .scope
644                                     .file_and_mod(self.customize.clone()),
645                             ),
646                         };
647                         cb(&v, w);
648                     });
649                 }
650                 _ => {
651                     w.if_stmt(
652                         format!(
653                             "{} != {}",
654                             self.self_field(),
655                             self.full_storage_type(
656                                 &self
657                                     .proto_field
658                                     .message
659                                     .scope
660                                     .file_and_mod(self.customize.clone())
661                             )
662                             .default_value(&self.customize, false)
663                         ),
664                         |w| {
665                             let v = RustValueTyped {
666                                 value: self.self_field(),
667                                 rust_type: self.full_storage_type(
668                                     &self
669                                         .proto_field
670                                         .message
671                                         .scope
672                                         .file_and_mod(self.customize.clone()),
673                                 ),
674                             };
675                             cb(&v, w);
676                         },
677                     );
678                 }
679             },
680         }
681     }
682 
write_if_self_field_is_none<F>(&self, w: &mut CodeWriter, cb: F) where F: Fn(&mut CodeWriter),683     pub(crate) fn write_if_self_field_is_none<F>(&self, w: &mut CodeWriter, cb: F)
684     where
685         F: Fn(&mut CodeWriter),
686     {
687         let self_field_is_none = self.self_field_is_none();
688         w.if_stmt(self_field_is_none, cb)
689     }
690 
691     // repeated or singular
write_for_self_field<F>(&self, w: &mut CodeWriter, varn: &str, cb: F) where F: Fn(&mut CodeWriter, &RustType),692     pub(crate) fn write_for_self_field<F>(&self, w: &mut CodeWriter, varn: &str, cb: F)
693     where
694         F: Fn(&mut CodeWriter, &RustType),
695     {
696         let file_and_mod = self
697             .proto_field
698             .message
699             .scope
700             .file_and_mod(self.customize.clone());
701 
702         match &self.kind {
703             FieldKind::Oneof(oneof_field) => {
704                 let cond = format!(
705                     "Some({}(ref {}))",
706                     oneof_field.variant_path(&file_and_mod.relative_mod),
707                     varn
708                 );
709                 w.if_let_stmt(
710                     &cond,
711                     &format!("self.{}", oneof_field.oneof_field_name),
712                     |w| cb(w, &oneof_field.elem.rust_storage_elem_type(&file_and_mod)),
713                 )
714             }
715             _ => {
716                 let v_type = self.full_storage_iter_elem_type(&file_and_mod);
717                 let self_field = self.self_field();
718                 w.for_stmt(&format!("&{}", self_field), varn, |w| cb(w, &v_type));
719             }
720         }
721     }
722 
write_self_field_assign(&self, w: &mut CodeWriter, value: &str)723     fn write_self_field_assign(&self, w: &mut CodeWriter, value: &str) {
724         let self_field = self.self_field();
725         w.write_line(&format!("{} = {};", self_field, value));
726     }
727 
write_self_field_assign_some(&self, w: &mut CodeWriter, s: &SingularField, value: &str)728     fn write_self_field_assign_some(&self, w: &mut CodeWriter, s: &SingularField, value: &str) {
729         match s {
730             &SingularField {
731                 flag: SingularFieldFlag::WithFlag { option_kind, .. },
732                 ..
733             } => {
734                 self.write_self_field_assign(w, &option_kind.wrap_value(value, &self.customize));
735             }
736             &SingularField {
737                 flag: SingularFieldFlag::WithoutFlag,
738                 ..
739             } => {
740                 self.write_self_field_assign(w, value);
741             }
742         }
743     }
744 
write_self_field_assign_value_singular( &self, w: &mut CodeWriter, s: &SingularField, value: &RustValueTyped, )745     fn write_self_field_assign_value_singular(
746         &self,
747         w: &mut CodeWriter,
748         s: &SingularField,
749         value: &RustValueTyped,
750     ) {
751         let SingularField { ref elem, ref flag } = s;
752         let converted = value.into_type(
753             elem.rust_storage_elem_type(
754                 &self
755                     .proto_field
756                     .message
757                     .scope
758                     .file_and_mod(self.customize.clone()),
759             )
760             .clone(),
761             &self.customize,
762         );
763         let wrapped = match flag {
764             SingularFieldFlag::WithoutFlag => converted.value,
765             SingularFieldFlag::WithFlag { option_kind, .. } => {
766                 option_kind.wrap_value(&converted.value, &self.customize)
767             }
768         };
769         self.write_self_field_assign(w, &wrapped);
770     }
771 
write_self_field_assign_value(&self, w: &mut CodeWriter, value: &RustValueTyped)772     fn write_self_field_assign_value(&self, w: &mut CodeWriter, value: &RustValueTyped) {
773         match self.kind {
774             FieldKind::Repeated(..) | FieldKind::Map(..) => {
775                 let converted = value.into_type(
776                     self.full_storage_type(
777                         &self
778                             .proto_field
779                             .message
780                             .scope
781                             .file_and_mod(self.customize.clone()),
782                     ),
783                     &self.customize,
784                 );
785                 self.write_self_field_assign(w, &converted.value);
786             }
787             FieldKind::Singular(ref s) => {
788                 self.write_self_field_assign_value_singular(w, s, value);
789             }
790             FieldKind::Oneof(..) => unreachable!(),
791         }
792     }
793 
write_self_field_assign_default( &self, field_kind: &SingularOrOneofField, w: &mut CodeWriter, )794     fn write_self_field_assign_default(
795         &self,
796         field_kind: &SingularOrOneofField,
797         w: &mut CodeWriter,
798     ) {
799         match field_kind {
800             SingularOrOneofField::Oneof(oneof) => {
801                 w.write_line(format!(
802                     "self.{} = ::std::option::Option::Some({}({}))",
803                     oneof.oneof_field_name,
804                     oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
805                     // TODO: default from .proto is not needed here (?)
806                     self.element_default_value_rust()
807                         .into_type(
808                             self.full_storage_iter_elem_type(
809                                 &self
810                                     .proto_field
811                                     .message
812                                     .scope
813                                     .file_and_mod(self.customize.clone())
814                             ),
815                             &self.customize
816                         )
817                         .value
818                 ));
819             }
820             SingularOrOneofField::Singular(singular) => {
821                 // Note it is different from C++ protobuf, where field is initialized
822                 // with default value
823                 match singular.flag {
824                     SingularFieldFlag::WithFlag { option_kind, .. } => match option_kind {
825                         OptionKind::MessageField => {
826                             let self_field = self.self_field();
827                             w.write_line(&format!("{}.set_default();", self_field));
828                         }
829                         _ => {
830                             self.write_self_field_assign_some(
831                                 w,
832                                 singular,
833                                 &self
834                                     .elem()
835                                     .rust_storage_elem_type(
836                                         &self
837                                             .proto_field
838                                             .message
839                                             .scope
840                                             .file_and_mod(self.customize.clone()),
841                                     )
842                                     .default_value_typed(&self.customize, false)
843                                     .into_type(
844                                         singular.elem.rust_storage_elem_type(
845                                             &self
846                                                 .proto_field
847                                                 .message
848                                                 .scope
849                                                 .file_and_mod(self.customize.clone()),
850                                         ),
851                                         &self.customize,
852                                     )
853                                     .value,
854                             );
855                         }
856                     },
857                     SingularFieldFlag::WithoutFlag => unimplemented!(),
858                 }
859             }
860         }
861     }
862 
self_field_vec_packed_size(&self) -> String863     fn self_field_vec_packed_size(&self) -> String {
864         let fn_name = match self.proto_type {
865             Type::TYPE_ENUM => "vec_packed_enum_or_unknown_size",
866             Type::TYPE_SINT32 => "vec_packed_sint32_size",
867             Type::TYPE_SINT64 => "vec_packed_sint64_size",
868             Type::TYPE_INT32 => "vec_packed_int32_size",
869             Type::TYPE_INT64 => "vec_packed_int64_size",
870             Type::TYPE_UINT32 => "vec_packed_uint32_size",
871             Type::TYPE_UINT64 => "vec_packed_uint64_size",
872             Type::TYPE_BOOL => "vec_packed_bool_size",
873             Type::TYPE_FIXED32 => "vec_packed_fixed32_size",
874             Type::TYPE_FIXED64 => "vec_packed_fixed64_size",
875             Type::TYPE_SFIXED32 => "vec_packed_sfixed32_size",
876             Type::TYPE_SFIXED64 => "vec_packed_sfixed64_size",
877             Type::TYPE_FLOAT => "vec_packed_float_size",
878             Type::TYPE_DOUBLE => "vec_packed_double_size",
879             t => unreachable!("{:?}", t),
880         };
881         format!(
882             "{}::rt::{fn_name}({}, &{})",
883             protobuf_crate_path(&self.customize),
884             self.proto_field.number(),
885             self.self_field()
886         )
887     }
888 
clear_field_func(&self) -> String889     pub(crate) fn clear_field_func(&self) -> String {
890         format!("clear_{}", self.rust_name)
891     }
892 
write_merge_from_field_message_string_bytes_repeated( &self, r: &RepeatedField, w: &mut CodeWriter, )893     fn write_merge_from_field_message_string_bytes_repeated(
894         &self,
895         r: &RepeatedField,
896         w: &mut CodeWriter,
897     ) {
898         let read_fn = match &r.elem {
899             FieldElem::Message(..) => "read_message",
900             FieldElem::Primitive(Type::TYPE_STRING, PrimitiveTypeVariant::Default) => "read_string",
901             FieldElem::Primitive(Type::TYPE_STRING, PrimitiveTypeVariant::TokioBytes) => {
902                 "read_tokio_chars"
903             }
904             FieldElem::Primitive(Type::TYPE_BYTES, PrimitiveTypeVariant::Default) => "read_bytes",
905             FieldElem::Primitive(Type::TYPE_BYTES, PrimitiveTypeVariant::TokioBytes) => {
906                 "read_tokio_bytes"
907             }
908             _ => unreachable!("for field {}", self.proto_field.field),
909         };
910         w.write_line(&format!("self.{}.push(is.{}()?);", self.rust_name, read_fn,));
911     }
912 
tag_with_wire_type(&self, wire_type: WireType) -> u32913     fn tag_with_wire_type(&self, wire_type: WireType) -> u32 {
914         make_tag(self.proto_field.number() as u32, wire_type)
915     }
916 
tag(&self) -> u32917     fn tag(&self) -> u32 {
918         self.tag_with_wire_type(self.wire_type)
919     }
920 
921     // Write `merge_from` part for this oneof field
write_merge_from_oneof_case_block(&self, o: &OneofField, w: &mut CodeWriter)922     fn write_merge_from_oneof_case_block(&self, o: &OneofField, w: &mut CodeWriter) {
923         w.case_block(&format!("{}", self.tag()), |w| {
924             let typed = RustValueTyped {
925                 value: format!(
926                     "{}?",
927                     self.proto_type.read("is", o.elem.primitive_type_variant())
928                 ),
929                 rust_type: self.full_storage_iter_elem_type(
930                     &self
931                         .proto_field
932                         .message
933                         .scope
934                         .file_and_mod(self.customize.clone()),
935                 ),
936             };
937 
938             let maybe_boxed = if o.boxed {
939                 typed.boxed(&self.customize)
940             } else {
941                 typed
942             };
943 
944             w.write_line(&format!(
945                 "self.{} = ::std::option::Option::Some({}({}));",
946                 o.oneof_field_name,
947                 o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
948                 maybe_boxed.value
949             ));
950         })
951     }
952 
953     // Write `merge_from` part for this map field
write_merge_from_map_case_block(&self, map: &MapField, w: &mut CodeWriter)954     fn write_merge_from_map_case_block(&self, map: &MapField, w: &mut CodeWriter) {
955         let MapField { key, value, .. } = map;
956         w.case_block(&format!("{}", self.tag()), |w| {
957             w.write_line(&format!("let len = is.read_raw_varint32()?;",));
958             w.write_line(&format!("let old_limit = is.push_limit(len as u64)?;"));
959             w.write_line(&format!(
960                 "let mut key = ::std::default::Default::default();"
961             ));
962             w.write_line(&format!(
963                 "let mut value = ::std::default::Default::default();"
964             ));
965             w.while_block("let Some(tag) = is.read_raw_tag_or_eof()?", |w| {
966                 w.match_block("tag", |w| {
967                     let key_tag = make_tag(1, WireType::for_type(key.proto_type()));
968                     let value_tag = make_tag(2, WireType::for_type(value.proto_type()));
969                     w.case_expr(
970                         &format!("{key_tag}"),
971                         &format!("key = {read}", read = key.read_one_liner()),
972                     );
973                     w.case_expr(
974                         &format!("{value_tag}"),
975                         &format!("value = {read}", read = value.read_one_liner()),
976                     );
977                     w.case_expr(
978                         "_",
979                         &format!(
980                             "{protobuf_crate}::rt::skip_field_for_tag(tag, is)?",
981                             protobuf_crate = protobuf_crate_path(&self.customize)
982                         ),
983                     );
984                 });
985             });
986             w.write_line(&format!("is.pop_limit(old_limit);"));
987             w.write_line(&format!(
988                 "{field}.insert(key, value);",
989                 field = self.self_field()
990             ));
991         });
992     }
993 
994     // Write `merge_from` part for this singular field
write_merge_from_singular_case_block(&self, s: &SingularField, w: &mut CodeWriter)995     fn write_merge_from_singular_case_block(&self, s: &SingularField, w: &mut CodeWriter) {
996         w.case_block(&format!("{}", self.tag()), |w| match s.elem {
997             FieldElem::Message(..) => {
998                 w.write_line(&format!(
999                     "{}::rt::read_singular_message_into_field(is, &mut self.{})?;",
1000                     protobuf_crate_path(&self.customize),
1001                     self.rust_name,
1002                 ));
1003             }
1004             _ => {
1005                 let read_proc = s.elem.read_one_liner();
1006                 self.write_self_field_assign_some(w, s, &read_proc);
1007             }
1008         })
1009     }
1010 
1011     // Write `merge_from` part for this repeated field
write_merge_from_repeated_case_block(&self, w: &mut CodeWriter)1012     fn write_merge_from_repeated_case_block(&self, w: &mut CodeWriter) {
1013         let field = match self.kind {
1014             FieldKind::Repeated(ref field) => field,
1015             _ => panic!(),
1016         };
1017 
1018         match field.elem {
1019             FieldElem::Message(..)
1020             | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)
1021             | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => {
1022                 w.case_block(&format!("{}", self.tag()), |w| {
1023                     self.write_merge_from_field_message_string_bytes_repeated(field, w);
1024                 })
1025             }
1026             FieldElem::Enum(..) => {
1027                 w.case_block(
1028                     &format!("{}", self.tag_with_wire_type(WireType::Varint)),
1029                     |w| {
1030                         w.write_line(&format!(
1031                             "self.{}.push(is.read_enum_or_unknown()?);",
1032                             self.rust_name,
1033                         ));
1034                     },
1035                 );
1036                 w.case_block(
1037                     &format!("{}", self.tag_with_wire_type(WireType::LengthDelimited)),
1038                     |w| {
1039                         w.write_line(&format!(
1040                             "{}::rt::read_repeated_packed_enum_or_unknown_into(is, &mut self.{})?",
1041                             protobuf_crate_path(&self.customize),
1042                             self.rust_name,
1043                         ));
1044                     },
1045                 );
1046             }
1047             _ => {
1048                 assert_ne!(self.wire_type, WireType::LengthDelimited);
1049                 w.case_block(
1050                     &format!("{}", self.tag_with_wire_type(WireType::LengthDelimited)),
1051                     |w| {
1052                         w.write_line(&format!(
1053                             "is.read_repeated_packed_{}_into(&mut self.{})?;",
1054                             self.proto_type.protobuf_name(),
1055                             self.rust_name
1056                         ));
1057                     },
1058                 );
1059                 w.case_block(&format!("{}", self.tag()), |w| {
1060                     w.write_line(&format!(
1061                         "self.{}.push(is.read_{}()?);",
1062                         self.rust_name,
1063                         self.proto_type.protobuf_name(),
1064                     ));
1065                 });
1066             }
1067         }
1068     }
1069 
1070     /// Write `merge_from` part for this field
write_merge_from_field_case_block(&self, w: &mut CodeWriter)1071     pub(crate) fn write_merge_from_field_case_block(&self, w: &mut CodeWriter) {
1072         match &self.kind {
1073             FieldKind::Oneof(oneof) => self.write_merge_from_oneof_case_block(oneof, w),
1074             FieldKind::Map(map) => self.write_merge_from_map_case_block(map, w),
1075             FieldKind::Singular(ref s) => self.write_merge_from_singular_case_block(s, w),
1076             FieldKind::Repeated(..) => self.write_merge_from_repeated_case_block(w),
1077         }
1078     }
1079 
write_element_size( &self, elem: &FieldElem, w: &mut CodeWriter, item_var: &RustValueTyped, sum_var: &str, )1080     pub(crate) fn write_element_size(
1081         &self,
1082         elem: &FieldElem,
1083         w: &mut CodeWriter,
1084         item_var: &RustValueTyped,
1085         sum_var: &str,
1086     ) {
1087         assert!(!self.is_repeated_packed());
1088 
1089         elem.write_element_size(
1090             self.proto_field.number() as u32,
1091             item_var,
1092             HowToGetMessageSize::Compute,
1093             sum_var,
1094             &self.customize,
1095             w,
1096         );
1097     }
1098 
write_write_map_field( &self, key: &FieldElem, value: &FieldElem, os: &str, w: &mut CodeWriter, )1099     fn write_write_map_field(
1100         &self,
1101         key: &FieldElem,
1102         value: &FieldElem,
1103         os: &str,
1104         w: &mut CodeWriter,
1105     ) {
1106         self.for_each_map_entry(key, value, w, |k, v, w| {
1107             w.write_line("let mut entry_size = 0;");
1108             key.write_element_size(
1109                 1,
1110                 k,
1111                 HowToGetMessageSize::GetCached,
1112                 "entry_size",
1113                 &self.customize,
1114                 w,
1115             );
1116             value.write_element_size(
1117                 2,
1118                 v,
1119                 HowToGetMessageSize::GetCached,
1120                 "entry_size",
1121                 &self.customize,
1122                 w,
1123             );
1124             w.write_line(&format!(
1125                 "{os}.write_raw_varint32({tag})?; // Tag.",
1126                 tag = make_tag(self.proto_field.number() as u32, WireType::LengthDelimited),
1127             ));
1128             w.write_line(&format!("{os}.write_raw_varint32(entry_size as u32)?;",));
1129             key.write_write_element(1, k, &self.file_and_mod(), &self.customize, os, w);
1130             value.write_write_element(2, v, &self.file_and_mod(), &self.customize, os, w);
1131         });
1132     }
1133 
write_message_write_field(&self, os: &str, w: &mut CodeWriter)1134     pub(crate) fn write_message_write_field(&self, os: &str, w: &mut CodeWriter) {
1135         match &self.kind {
1136             FieldKind::Singular(s @ SingularField { elem, .. }) => {
1137                 self.write_if_let_self_field_is_some(s, w, |v, w| {
1138                     self.write_write_element(&elem, w, os, &v);
1139                 });
1140             }
1141             FieldKind::Repeated(RepeatedField {
1142                 packed: false,
1143                 elem,
1144                 ..
1145             }) => {
1146                 self.write_for_self_field(w, "v", |w, v_type| {
1147                     let v = RustValueTyped {
1148                         value: "v".to_owned(),
1149                         rust_type: v_type.clone(),
1150                     };
1151                     self.write_write_element(elem, w, "os", &v);
1152                 });
1153             }
1154             FieldKind::Repeated(RepeatedField { packed: true, .. }) => {
1155                 w.write_line(&format!(
1156                     "os.write_repeated_packed_{}({}, &{})?;",
1157                     self.os_write_fn_suffix_with_unknown_for_enum(),
1158                     self.proto_field.number(),
1159                     self.self_field()
1160                 ));
1161             }
1162             FieldKind::Map(MapField { key, value, .. }) => {
1163                 self.write_write_map_field(key, value, os, w)
1164             }
1165             FieldKind::Oneof(..) => unreachable!(),
1166         };
1167     }
1168 
for_each_map_entry( &self, key: &FieldElem, value: &FieldElem, w: &mut CodeWriter, cb: impl FnOnce(&RustValueTyped, &RustValueTyped, &mut CodeWriter), )1169     fn for_each_map_entry(
1170         &self,
1171         key: &FieldElem,
1172         value: &FieldElem,
1173         w: &mut CodeWriter,
1174         cb: impl FnOnce(&RustValueTyped, &RustValueTyped, &mut CodeWriter),
1175     ) {
1176         w.for_stmt(&format!("&{}", self.self_field()), "(k, v)", move |w| {
1177             let k = RustValueTyped {
1178                 value: "k".to_owned(),
1179                 rust_type: key.rust_storage_elem_type(&self.file_and_mod()).wrap_ref(),
1180             };
1181             let v = RustValueTyped {
1182                 value: "v".to_owned(),
1183                 rust_type: value
1184                     .rust_storage_elem_type(&self.file_and_mod())
1185                     .wrap_ref(),
1186             };
1187             cb(&k, &v, w)
1188         });
1189     }
1190 
write_compute_map_field_size( &self, sum_var: &str, key: &FieldElem<'a>, value: &FieldElem<'a>, w: &mut CodeWriter, )1191     fn write_compute_map_field_size(
1192         &self,
1193         sum_var: &str,
1194         key: &FieldElem<'a>,
1195         value: &FieldElem<'a>,
1196         w: &mut CodeWriter,
1197     ) {
1198         self.for_each_map_entry(key, value, w, |k, v, w| {
1199                 w.write_line("let mut entry_size = 0;");
1200                 key.write_element_size(1, k, HowToGetMessageSize::Compute, "entry_size", &self.customize, w);
1201                 value.write_element_size(2, v, HowToGetMessageSize::Compute, "entry_size", &self.customize, w);
1202                 w.write_line(&format!("{sum_var} += {tag_size} + {protobuf_crate}::rt::compute_raw_varint64_size(entry_size) + entry_size",
1203                     tag_size = self.tag_size(),
1204                     protobuf_crate = protobuf_crate_path(&self.customize),
1205                 ));
1206         });
1207     }
1208 
write_message_compute_field_size(&self, sum_var: &str, w: &mut CodeWriter)1209     pub(crate) fn write_message_compute_field_size(&self, sum_var: &str, w: &mut CodeWriter) {
1210         match &self.kind {
1211             FieldKind::Singular(s @ SingularField { elem, .. }) => {
1212                 self.write_if_let_self_field_is_some(s, w, |v, w| {
1213                     self.write_element_size(&elem, w, v, sum_var)
1214                 });
1215             }
1216             FieldKind::Repeated(RepeatedField {
1217                 packed: false,
1218                 elem,
1219                 ..
1220             }) => {
1221                 match elem.proto_type().encoded_size() {
1222                     Some(s) => {
1223                         let tag_size = self.tag_size();
1224                         let self_field = self.self_field();
1225                         w.write_line(&format!(
1226                             "{} += {} * {}.len() as u64;",
1227                             sum_var,
1228                             (s + tag_size) as isize,
1229                             self_field
1230                         ));
1231                     }
1232                     None => {
1233                         self.write_for_self_field(w, "value", |w, value_type| {
1234                             self.write_element_size(
1235                                 elem,
1236                                 w,
1237                                 &RustValueTyped {
1238                                     value: "value".to_owned(),
1239                                     rust_type: value_type.clone(),
1240                                 },
1241                                 sum_var,
1242                             );
1243                         });
1244                     }
1245                 };
1246             }
1247             FieldKind::Repeated(RepeatedField { packed: true, .. }) => {
1248                 let size_expr = self.self_field_vec_packed_size();
1249                 w.write_line(&format!("{} += {};", sum_var, size_expr));
1250             }
1251             FieldKind::Map(MapField { key, value, .. }) => {
1252                 self.write_compute_map_field_size(sum_var, key, value, w)
1253             }
1254             FieldKind::Oneof(..) => unreachable!(),
1255         }
1256     }
1257 
write_message_field_get_singular_message(&self, s: &SingularField, w: &mut CodeWriter)1258     fn write_message_field_get_singular_message(&self, s: &SingularField, w: &mut CodeWriter) {
1259         match s.flag {
1260             SingularFieldFlag::WithoutFlag => unimplemented!(),
1261             SingularFieldFlag::WithFlag { option_kind, .. } => {
1262                 let self_field = self.self_field();
1263                 let ref field_type_name = self.elem().rust_storage_elem_type(
1264                     &self
1265                         .proto_field
1266                         .message
1267                         .scope
1268                         .file_and_mod(self.customize.clone()),
1269                 );
1270                 w.write_line(option_kind.unwrap_ref_or_else(
1271                     &format!("{}.as_ref()", self_field),
1272                     &format!(
1273                         "<{} as {}::Message>::default_instance()",
1274                         field_type_name.to_code(&self.customize),
1275                         protobuf_crate_path(&self.customize),
1276                     ),
1277                 ));
1278             }
1279         }
1280     }
1281 
write_message_field_get_singular_enum( &self, flag: SingularFieldFlag, _elem: &FieldElemEnum, w: &mut CodeWriter, )1282     fn write_message_field_get_singular_enum(
1283         &self,
1284         flag: SingularFieldFlag,
1285         _elem: &FieldElemEnum,
1286         w: &mut CodeWriter,
1287     ) {
1288         match flag {
1289             SingularFieldFlag::WithoutFlag => {
1290                 w.write_line(&format!("self.{}.enum_value_or_default()", self.rust_name));
1291             }
1292             SingularFieldFlag::WithFlag { .. } => {
1293                 w.match_expr(&self.self_field(), |w| {
1294                     let default_value = self.xxx_default_value_rust();
1295                     w.case_expr("Some(e)", &format!("e.enum_value_or({})", default_value));
1296                     w.case_expr("None", &format!("{}", default_value));
1297                 });
1298             }
1299         }
1300     }
1301 
write_message_field_get_singular(&self, singular: &SingularField, w: &mut CodeWriter)1302     fn write_message_field_get_singular(&self, singular: &SingularField, w: &mut CodeWriter) {
1303         let get_xxx_return_type = self.getter_return_type();
1304 
1305         match singular.elem {
1306             FieldElem::Message(..) => self.write_message_field_get_singular_message(singular, w),
1307             FieldElem::Enum(ref en) => {
1308                 self.write_message_field_get_singular_enum(singular.flag, en, w)
1309             }
1310             _ => {
1311                 let get_xxx_default_value_rust = self.xxx_default_value_rust();
1312                 let self_field = self.self_field();
1313                 match singular {
1314                     &SingularField {
1315                         ref elem,
1316                         flag: SingularFieldFlag::WithFlag { option_kind, .. },
1317                         ..
1318                     } => {
1319                         if get_xxx_return_type.is_ref().is_some() {
1320                             let as_option = self.self_field_as_option(elem, option_kind);
1321                             w.match_expr(&as_option.value, |w| {
1322                                 let v_type = as_option.rust_type.elem_type();
1323                                 let r_type = self.getter_return_type();
1324                                 w.case_expr(
1325                                     "Some(v)",
1326                                     v_type.into_target(&r_type, "v", &self.customize),
1327                                 );
1328                                 let get_xxx_default_value_rust = self.xxx_default_value_rust();
1329                                 w.case_expr("None", get_xxx_default_value_rust);
1330                             });
1331                         } else {
1332                             w.write_line(&format!(
1333                                 "{}.unwrap_or({})",
1334                                 self_field, get_xxx_default_value_rust
1335                             ));
1336                         }
1337                     }
1338                     &SingularField {
1339                         flag: SingularFieldFlag::WithoutFlag,
1340                         ..
1341                     } => {
1342                         w.write_line(
1343                             self.full_storage_type(
1344                                 &self
1345                                     .proto_field
1346                                     .message
1347                                     .scope
1348                                     .file_and_mod(self.customize.clone()),
1349                             )
1350                             .into_target(
1351                                 &get_xxx_return_type,
1352                                 &self_field,
1353                                 &self.customize,
1354                             ),
1355                         );
1356                     }
1357                 }
1358             }
1359         }
1360     }
1361 
write_message_field_get_oneof(&self, o: &OneofField, w: &mut CodeWriter)1362     fn write_message_field_get_oneof(&self, o: &OneofField, w: &mut CodeWriter) {
1363         let get_xxx_return_type = SingularOrOneofField::Oneof(o.clone()).getter_return_type(
1364             &self
1365                 .proto_field
1366                 .message
1367                 .scope
1368                 .file_and_mod(self.customize.clone()),
1369         );
1370         let OneofField { ref elem, .. } = o;
1371         w.match_expr(&format!("self.{}", o.oneof_field_name), |w| {
1372             let (refv, vtype) = if !elem.is_copy() {
1373                 (
1374                     "ref v",
1375                     elem.rust_storage_elem_type(
1376                         &self
1377                             .proto_field
1378                             .message
1379                             .scope
1380                             .file_and_mod(self.customize.clone()),
1381                     )
1382                     .ref_type(),
1383                 )
1384             } else {
1385                 (
1386                     "v",
1387                     elem.rust_storage_elem_type(
1388                         &self
1389                             .proto_field
1390                             .message
1391                             .scope
1392                             .file_and_mod(self.customize.clone()),
1393                     ),
1394                 )
1395             };
1396             w.case_expr(
1397                 format!(
1398                     "::std::option::Option::Some({}({}))",
1399                     o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
1400                     refv
1401                 ),
1402                 vtype.into_target(&get_xxx_return_type, "v", &self.customize),
1403             );
1404             w.case_expr("_", self.xxx_default_value_rust());
1405         });
1406     }
1407 
write_message_field_get(&self, w: &mut CodeWriter)1408     fn write_message_field_get(&self, w: &mut CodeWriter) {
1409         let get_xxx_return_type = self.getter_return_type();
1410         let fn_def = format!(
1411             "{}(&self) -> {}",
1412             self.rust_name,
1413             get_xxx_return_type.to_code(&self.customize)
1414         );
1415 
1416         w.pub_fn(&fn_def, |w| match self.kind {
1417             FieldKind::Oneof(ref o) => {
1418                 self.write_message_field_get_oneof(o, w);
1419             }
1420             FieldKind::Singular(ref s) => {
1421                 self.write_message_field_get_singular(s, w);
1422             }
1423             FieldKind::Repeated(..) | FieldKind::Map(..) => {
1424                 let self_field = self.self_field();
1425                 w.write_line(&format!("&{}", self_field));
1426             }
1427         });
1428     }
1429 
has_has(&self) -> bool1430     fn has_has(&self) -> bool {
1431         match self.kind {
1432             FieldKind::Repeated(..) | FieldKind::Map(..) => false,
1433             FieldKind::Singular(SingularField {
1434                 flag: SingularFieldFlag::WithFlag { .. },
1435                 ..
1436             }) => true,
1437             FieldKind::Singular(SingularField {
1438                 flag: SingularFieldFlag::WithoutFlag,
1439                 ..
1440             }) => false,
1441             FieldKind::Oneof(..) => true,
1442         }
1443     }
1444 
has_mut(&self) -> bool1445     fn has_mut(&self) -> bool {
1446         match self.kind {
1447             FieldKind::Repeated(..) | FieldKind::Map(..) => true,
1448             // TODO: string should be public, and mut is not needed
1449             FieldKind::Singular(..) | FieldKind::Oneof(..) => !self.elem_type_is_copy(),
1450         }
1451     }
1452 
has_take(&self) -> bool1453     fn has_take(&self) -> bool {
1454         match self.kind {
1455             FieldKind::Repeated(..) | FieldKind::Map(..) => true,
1456             // TODO: string should be public, and mut is not needed
1457             FieldKind::Singular(..) | FieldKind::Oneof(..) => !self.elem_type_is_copy(),
1458         }
1459     }
1460 
has_name(&self) -> RustIdent1461     fn has_name(&self) -> RustIdent {
1462         RustIdent::new(&format!("has_{}", self.rust_name.get()))
1463     }
1464 
set_name(&self) -> RustIdent1465     fn set_name(&self) -> RustIdent {
1466         RustIdent::new(&format!("set_{}", self.rust_name.get()))
1467     }
1468 
mut_name(&self) -> RustIdent1469     fn mut_name(&self) -> RustIdent {
1470         RustIdent::new(&format!("mut_{}", self.rust_name.get()))
1471     }
1472 
write_message_field_has(&self, w: &mut CodeWriter)1473     fn write_message_field_has(&self, w: &mut CodeWriter) {
1474         w.pub_fn(
1475             &format!("{}(&self) -> bool", self.has_name()),
1476             |w| match self.kind {
1477                 FieldKind::Oneof(ref oneof) => {
1478                     w.match_expr(&format!("self.{}", oneof.oneof_field_name), |w| {
1479                         w.case_expr(
1480                             format!(
1481                                 "::std::option::Option::Some({}(..))",
1482                                 oneof.variant_path(
1483                                     &self.proto_field.message.scope.rust_path_to_file()
1484                                 )
1485                             ),
1486                             "true",
1487                         );
1488                         w.case_expr("_", "false");
1489                     });
1490                 }
1491                 _ => {
1492                     let self_field_is_some = self.self_field_is_some();
1493                     w.write_line(self_field_is_some);
1494                 }
1495             },
1496         );
1497     }
1498 
write_message_field_set(&self, w: &mut CodeWriter)1499     fn write_message_field_set(&self, w: &mut CodeWriter) {
1500         let set_xxx_param_type = self.set_xxx_param_type(
1501             &self
1502                 .proto_field
1503                 .message
1504                 .scope
1505                 .file_and_mod(self.customize.clone()),
1506         );
1507         w.comment("Param is passed by value, moved");
1508         w.pub_fn(
1509             &format!(
1510                 "{}(&mut self, v: {})",
1511                 self.set_name(),
1512                 set_xxx_param_type.to_code(&self.customize)
1513             ),
1514             |w| {
1515                 let value_typed = RustValueTyped {
1516                     value: "v".to_owned(),
1517                     rust_type: set_xxx_param_type.clone(),
1518                 };
1519                 match self.kind {
1520                     FieldKind::Oneof(ref oneof) => {
1521                         let v = set_xxx_param_type.into_target(
1522                             &oneof.rust_type(
1523                                 &self
1524                                     .proto_field
1525                                     .message
1526                                     .scope
1527                                     .file_and_mod(self.customize.clone()),
1528                             ),
1529                             "v",
1530                             &self.customize,
1531                         );
1532                         w.write_line(&format!(
1533                             "self.{} = ::std::option::Option::Some({}({}))",
1534                             oneof.oneof_field_name,
1535                             oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
1536                             v
1537                         ));
1538                     }
1539                     _ => {
1540                         self.write_self_field_assign_value(w, &value_typed);
1541                     }
1542                 }
1543             },
1544         );
1545     }
1546 
write_message_field_mut_singular_with_flag( &self, s: &SingularField, option_kind: OptionKind, w: &mut CodeWriter, )1547     fn write_message_field_mut_singular_with_flag(
1548         &self,
1549         s: &SingularField,
1550         option_kind: OptionKind,
1551         w: &mut CodeWriter,
1552     ) {
1553         let self_field = self.self_field();
1554         match option_kind {
1555             OptionKind::MessageField => {
1556                 w.write_line(&format!("{}.mut_or_insert_default()", self_field))
1557             }
1558             OptionKind::Option => {
1559                 self.write_if_self_field_is_none(w, |w| {
1560                     self.write_self_field_assign_default(
1561                         &SingularOrOneofField::Singular(s.clone()),
1562                         w,
1563                     );
1564                 });
1565                 w.write_line(&format!("{}.as_mut().unwrap()", self_field));
1566             }
1567         }
1568     }
1569 
write_message_field_mut_singular(&self, s: &SingularField, w: &mut CodeWriter)1570     fn write_message_field_mut_singular(&self, s: &SingularField, w: &mut CodeWriter) {
1571         match s {
1572             s @ SingularField {
1573                 flag: SingularFieldFlag::WithFlag { option_kind, .. },
1574                 ..
1575             } => self.write_message_field_mut_singular_with_flag(s, *option_kind, w),
1576             SingularField {
1577                 flag: SingularFieldFlag::WithoutFlag,
1578                 ..
1579             } => w.write_line(&format!("&mut {}", self.self_field())),
1580         }
1581     }
1582 
write_message_field_mut(&self, w: &mut CodeWriter)1583     fn write_message_field_mut(&self, w: &mut CodeWriter) {
1584         let mut_xxx_return_type = self.mut_xxx_return_type(
1585             &self
1586                 .proto_field
1587                 .message
1588                 .scope
1589                 .file_and_mod(self.customize.clone()),
1590         );
1591         w.comment("Mutable pointer to the field.");
1592         if self.is_singular() {
1593             w.comment("If field is not initialized, it is initialized with default value first.");
1594         }
1595         let fn_def = match mut_xxx_return_type {
1596             RustType::Ref(ref param) => format!(
1597                 "{}(&mut self) -> &mut {}",
1598                 self.mut_name(),
1599                 param.to_code(&self.customize)
1600             ),
1601             _ => panic!(
1602                 "not a ref: {}",
1603                 mut_xxx_return_type.to_code(&self.customize)
1604             ),
1605         };
1606         w.pub_fn(&fn_def, |w| {
1607             match self.kind {
1608                 FieldKind::Repeated(..) | FieldKind::Map(..) => {
1609                     let self_field = self.self_field();
1610                     w.write_line(&format!("&mut {}", self_field));
1611                 }
1612                 FieldKind::Singular(ref s) => {
1613                     self.write_message_field_mut_singular(s, w);
1614                 }
1615                 FieldKind::Oneof(ref o) => {
1616                     let self_field_oneof = format!("self.{}", o.oneof_field_name);
1617 
1618                     // if oneof does not contain current field
1619                     w.if_let_else_stmt(
1620                         &format!(
1621                             "::std::option::Option::Some({}(_))",
1622                             o.variant_path(&self.proto_field.message.scope.rust_path_to_file())
1623                         )[..],
1624                         &self_field_oneof[..],
1625                         |w| {
1626                             // initialize it with default value
1627                             w.write_line(&format!(
1628                                 "{} = ::std::option::Option::Some({}({}));",
1629                                 self_field_oneof,
1630                                 o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
1631                                 self.element_default_value_rust()
1632                                     .into_type(
1633                                         o.rust_type(
1634                                             &self
1635                                                 .proto_field
1636                                                 .message
1637                                                 .scope
1638                                                 .file_and_mod(self.customize.clone())
1639                                         ),
1640                                         &self.customize
1641                                     )
1642                                     .value
1643                             ));
1644                         },
1645                     );
1646 
1647                     // extract field
1648                     w.match_expr(self_field_oneof, |w| {
1649                         w.case_expr(
1650                             format!(
1651                                 "::std::option::Option::Some({}(ref mut v))",
1652                                 o.variant_path(&self.proto_field.message.scope.rust_path_to_file())
1653                             ),
1654                             "v",
1655                         );
1656                         w.case_expr("_", "panic!()");
1657                     });
1658                 }
1659             }
1660         });
1661     }
1662 
write_message_field_take_oneof(&self, o: &OneofField, w: &mut CodeWriter)1663     fn write_message_field_take_oneof(&self, o: &OneofField, w: &mut CodeWriter) {
1664         let take_xxx_return_type = self.take_xxx_return_type(
1665             &self
1666                 .proto_field
1667                 .message
1668                 .scope
1669                 .file_and_mod(self.customize.clone()),
1670         );
1671 
1672         // TODO: replace with if let
1673         w.write_line(&format!("if self.{}() {{", self.has_name()));
1674         w.indented(|w| {
1675             let self_field_oneof = format!("self.{}", o.oneof_field_name);
1676             w.match_expr(format!("{}.take()", self_field_oneof), |w| {
1677                 let value_in_some = o
1678                     .rust_type(
1679                         &self
1680                             .proto_field
1681                             .message
1682                             .scope
1683                             .file_and_mod(self.customize.clone()),
1684                     )
1685                     .value("v".to_owned());
1686                 let converted = value_in_some.into_type(
1687                     self.take_xxx_return_type(
1688                         &self
1689                             .proto_field
1690                             .message
1691                             .scope
1692                             .file_and_mod(self.customize.clone()),
1693                     ),
1694                     &self.customize,
1695                 );
1696                 w.case_expr(
1697                     format!(
1698                         "::std::option::Option::Some({}(v))",
1699                         o.variant_path(&self.proto_field.message.scope.rust_path_to_file())
1700                     ),
1701                     &converted.value,
1702                 );
1703                 w.case_expr("_", "panic!()");
1704             });
1705         });
1706         w.write_line("} else {");
1707         w.indented(|w| {
1708             w.write_line(
1709                 self.elem()
1710                     .rust_storage_elem_type(
1711                         &self
1712                             .proto_field
1713                             .message
1714                             .scope
1715                             .file_and_mod(self.customize.clone()),
1716                     )
1717                     .default_value_typed(&self.customize, false)
1718                     .into_type(take_xxx_return_type.clone(), &self.customize)
1719                     .value,
1720             );
1721         });
1722         w.write_line("}");
1723     }
1724 
write_message_field_take_singular(&self, s: &SingularField, w: &mut CodeWriter)1725     fn write_message_field_take_singular(&self, s: &SingularField, w: &mut CodeWriter) {
1726         match s {
1727             SingularField {
1728                 ref elem,
1729                 flag: SingularFieldFlag::WithFlag { option_kind, .. },
1730             } => {
1731                 if !elem.is_copy() {
1732                     w.write_line(
1733                         &option_kind.unwrap_or_else(
1734                             &format!("{}.take()", self.self_field()),
1735                             &elem
1736                                 .rust_storage_elem_type(
1737                                     &self
1738                                         .proto_field
1739                                         .message
1740                                         .scope
1741                                         .file_and_mod(self.customize.clone()),
1742                                 )
1743                                 .default_value(&self.customize, false),
1744                         ),
1745                     );
1746                 } else {
1747                     w.write_line(&format!(
1748                         "{}.take().unwrap_or({})",
1749                         self.self_field(),
1750                         self.element_default_value_rust().value
1751                     ));
1752                 }
1753             }
1754             SingularField {
1755                 flag: SingularFieldFlag::WithoutFlag,
1756                 ..
1757             } => w.write_line(&format!(
1758                 "::std::mem::replace(&mut {}, {})",
1759                 self.self_field(),
1760                 self.full_storage_type(
1761                     &self
1762                         .proto_field
1763                         .message
1764                         .scope
1765                         .file_and_mod(self.customize.clone())
1766                 )
1767                 .default_value(&self.customize, false)
1768             )),
1769         }
1770     }
1771 
write_message_field_take(&self, w: &mut CodeWriter)1772     fn write_message_field_take(&self, w: &mut CodeWriter) {
1773         let take_xxx_return_type = self.take_xxx_return_type(
1774             &self
1775                 .proto_field
1776                 .message
1777                 .scope
1778                 .file_and_mod(self.customize.clone()),
1779         );
1780         w.comment("Take field");
1781         w.pub_fn(
1782             &format!(
1783                 "take_{}(&mut self) -> {}",
1784                 self.rust_name,
1785                 take_xxx_return_type.to_code(&self.customize)
1786             ),
1787             |w| match self.kind {
1788                 FieldKind::Singular(ref s) => self.write_message_field_take_singular(&s, w),
1789                 FieldKind::Oneof(ref o) => self.write_message_field_take_oneof(o, w),
1790                 FieldKind::Repeated(..) | FieldKind::Map(..) => {
1791                     w.write_line(&format!(
1792                         "::std::mem::replace(&mut self.{}, {})",
1793                         self.rust_name,
1794                         take_xxx_return_type.default_value(&self.customize, false)
1795                     ));
1796                 }
1797             },
1798         );
1799     }
1800 
write_message_single_field_accessors(&self, w: &mut CodeWriter)1801     pub(crate) fn write_message_single_field_accessors(&self, w: &mut CodeWriter) {
1802         if self.generate_accessors || self.generate_getter {
1803             w.write_line("");
1804             let reconstruct_def = self.reconstruct_def();
1805             w.comment(&(reconstruct_def + ";"));
1806         }
1807 
1808         if self.generate_getter {
1809             w.write_line("");
1810             self.write_message_field_get(w);
1811         }
1812 
1813         if !self.generate_accessors {
1814             return;
1815         }
1816 
1817         w.write_line("");
1818         let clear_field_func = self.clear_field_func();
1819         w.pub_fn(&format!("{}(&mut self)", clear_field_func), |w| {
1820             self.write_clear(w);
1821         });
1822 
1823         if self.has_has() {
1824             w.write_line("");
1825             self.write_message_field_has(w);
1826         }
1827 
1828         w.write_line("");
1829         self.write_message_field_set(w);
1830 
1831         if self.has_mut() {
1832             w.write_line("");
1833             self.write_message_field_mut(w);
1834         }
1835 
1836         if self.has_take() {
1837             w.write_line("");
1838             self.write_message_field_take(w);
1839         }
1840     }
1841 }
1842 
rust_field_name_for_protobuf_field_name(name: &str) -> RustIdent1843 pub(crate) fn rust_field_name_for_protobuf_field_name(name: &str) -> RustIdent {
1844     RustIdent::new(name)
1845 }
1846 
rust_variant_name_for_protobuf_oneof_field_name(name: &str) -> RustIdent1847 pub(crate) fn rust_variant_name_for_protobuf_oneof_field_name(name: &str) -> RustIdent {
1848     let name = camel_case(name);
1849     RustIdent::new(&name)
1850 }
1851