protobuf_codegen/gen/field/
mod.rs

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