<NME> mod.rs
<BEF> mod accessor;
pub(crate) mod elem;
mod option_kind;
mod repeated;
mod singular;
mod tag;
pub(crate) mod type_ext;

use protobuf::descriptor::field_descriptor_proto::Type;
use protobuf::descriptor::*;
use protobuf::reflect::ReflectValueRef;
use protobuf::reflect::RuntimeFieldType;
use protobuf::reflect::Syntax;
use protobuf::rt;
use protobuf::rt::WireType;
use protobuf_parse::camel_case;
use protobuf_parse::ProtobufAbsPath;

use crate::customize::ctx::CustomizeElemCtx;
use crate::customize::rustproto_proto::customize_from_rustproto_for_field;
use crate::customize::Customize;
use crate::gen::code_writer::CodeWriter;
use crate::gen::code_writer::Visibility;
use crate::gen::field::elem::field_elem;
use crate::gen::field::elem::FieldElem;
use crate::gen::field::elem::FieldElemEnum;
use crate::gen::field::elem::HowToGetMessageSize;
use crate::gen::field::option_kind::OptionKind;
use crate::gen::field::repeated::RepeatedField;
use crate::gen::field::singular::SingularField;
use crate::gen::field::singular::SingularFieldFlag;
use crate::gen::field::tag::make_tag;
use crate::gen::field::type_ext::TypeExt;
use crate::gen::file_and_mod::FileAndMod;
use crate::gen::inside::protobuf_crate_path;
use crate::gen::map::map_entry;
use crate::gen::oneof::OneofField;
use crate::gen::protoc_insertion_point::write_protoc_insertion_point_for_field;
use crate::gen::rust::ident::RustIdent;
use crate::gen::rust::quote::quote_escape_bytes;
use crate::gen::rust::quote::quote_escape_str;
use crate::gen::rust::snippets::EXPR_NONE;
use crate::gen::rust_types_values::PrimitiveTypeVariant;
use crate::gen::rust_types_values::RustType;
use crate::gen::rust_types_values::RustValueTyped;
use crate::gen::scope::FieldWithContext;
use crate::gen::scope::MessageWithScope;
use crate::gen::scope::RootScope;

fn field_type_protobuf_name<'a>(field: &'a FieldDescriptorProto) -> &'a str {
    if field.has_type_name() {
        field.type_name()
    } else {
        field.type_().protobuf_name()
    }
}

#[derive(Clone)]
pub struct MapField<'a> {
    _message: MessageWithScope<'a>,
    key: FieldElem<'a>,
    value: FieldElem<'a>,
}

#[derive(Clone)]
pub(crate) enum FieldKind<'a> {
    // optional or required
    Singular(SingularField<'a>),
    // repeated except map
    Repeated(RepeatedField<'a>),
    // map
    Map(MapField<'a>),
    // part of oneof
    Oneof(OneofField<'a>),
}

impl<'a> FieldKind<'a> {
    pub(crate) fn default(
        &self,
        customize: &Customize,
        reference: &FileAndMod,
        const_expr: bool,
    ) -> String {
        match self {
            FieldKind::Singular(s) => s.default_value(customize, reference, const_expr),
            FieldKind::Repeated(r) => r.default(),
            FieldKind::Oneof(..) => EXPR_NONE.to_owned(),
            FieldKind::Map(..) => panic!("map fields cannot have field value"),
        }
    }
}

#[derive(Clone)]
pub(crate) enum SingularOrOneofField<'a> {
    Singular(SingularField<'a>),
    Oneof(OneofField<'a>),
}

impl<'a> SingularOrOneofField<'a> {
    fn elem(&self) -> &FieldElem {
        match self {
            SingularOrOneofField::Singular(SingularField { ref elem, .. }) => elem,
            SingularOrOneofField::Oneof(OneofField { ref elem, .. }) => elem,
        }
    }

    // Type of `xxx` function for singular type.
    pub(crate) fn getter_return_type(&self, reference: &FileAndMod) -> RustType {
        let elem = self.elem();
        if let FieldElem::Enum(ref en) = elem {
            en.enum_rust_type(reference)
        } else if elem.is_copy() {
            elem.rust_storage_elem_type(reference)
        } else {
            elem.rust_storage_elem_type(reference).ref_type()
        }
    }
}

// Representation of map entry: key type and value type
#[derive(Clone, Debug)]
pub struct EntryKeyValue<'a>(FieldElem<'a>, FieldElem<'a>);

#[derive(Clone)]
pub(crate) struct FieldGen<'a> {
    syntax: Syntax,
    pub proto_field: FieldWithContext<'a>,
    // field name in generated code
    pub rust_name: RustIdent,
    pub proto_type: Type,
    wire_type: WireType,
    pub kind: FieldKind<'a>,
    pub generate_accessors: bool,
    pub generate_getter: bool,
    customize: Customize,
    path: Vec<i32>,
    info: Option<&'a SourceCodeInfo>,
}

impl<'a> FieldGen<'a> {
    pub(crate) fn parse(
        field: FieldWithContext<'a>,
        root_scope: &'a RootScope<'a>,
        parent_customize: &CustomizeElemCtx<'a>,
        path: Vec<i32>,
        info: Option<&'a SourceCodeInfo>,
    ) -> anyhow::Result<FieldGen<'a>> {
        let customize = parent_customize
            .child(
                &customize_from_rustproto_for_field(field.field.proto().options.get_or_default()),
                &field.field,
            )
            .for_elem;

        let syntax = field.message.scope.file_scope.syntax();

        let field_may_have_custom_default_value = syntax == Syntax::Proto2
            && field.field.proto().label() != field_descriptor_proto::Label::LABEL_REPEATED
            && field.field.proto().type_() != Type::TYPE_MESSAGE;

        let generate_accessors = customize
            .generate_accessors
            .unwrap_or(field_may_have_custom_default_value)
            || field.is_oneof();

        let default_generate_getter = generate_accessors || field_may_have_custom_default_value;
        let generate_getter =
            customize.generate_getter.unwrap_or(default_generate_getter) || field.is_oneof();

        let kind = match field.field.runtime_field_type() {
            RuntimeFieldType::Map(..) => {
                let message = root_scope
                    .find_message(&ProtobufAbsPath::from(field.field.proto().type_name()));

                let (key, value) = map_entry(&message).unwrap();

                let key = field_elem(&key, root_scope, &customize);
                let value = field_elem(&value, root_scope, &customize);

                FieldKind::Map(MapField {
                    _message: message,
                    key,
                    value,
                })
            }
            RuntimeFieldType::Repeated(..) => {
                let elem = field_elem(&field, root_scope, &customize);

                FieldKind::Repeated(RepeatedField {
                    elem,
                    packed: field.field.proto().options.get_or_default().packed(),
                })
            }
            RuntimeFieldType::Singular(..) => {
                let elem = field_elem(&field, root_scope, &customize);

                if let Some(oneof) = field.oneof() {
                    FieldKind::Oneof(OneofField::parse(&oneof, &field.field, elem, root_scope))
                } else {
                    let flag = if field.message.scope.file_scope.syntax() == Syntax::Proto3
                        && field.field.proto().type_() != field_descriptor_proto::Type::TYPE_MESSAGE
                        && !field.field.proto().proto3_optional()
                    {
                        SingularFieldFlag::WithoutFlag
                    } else {
                        let required = field.field.proto().label()
                            == field_descriptor_proto::Label::LABEL_REQUIRED;
                        let option_kind = match field.field.proto().type_() {
                            field_descriptor_proto::Type::TYPE_MESSAGE => OptionKind::MessageField,
                            _ => OptionKind::Option,
                        };

                        SingularFieldFlag::WithFlag {
                            required,
                            option_kind,
                        }
                    };
                    FieldKind::Singular(SingularField { elem, flag })
                }
            }
        };

        Ok(FieldGen {
            syntax: field.message.message.file_descriptor().syntax(),
            rust_name: rust_field_name_for_protobuf_field_name(&field.field.name()),
            proto_type: field.field.proto().type_(),
            wire_type: WireType::for_type(field.field.proto().type_()),
            proto_field: field,
            kind,
            generate_accessors,
            generate_getter,
            customize,
            path,
            info,
        })
    }

    // for message level
    fn file_and_mod(&self) -> FileAndMod {
        self.proto_field
            .message
            .scope
            .file_and_mod(self.customize.clone())
    }

    fn tag_size(&self) -> u32 {
        rt::tag_size(self.proto_field.number() as u32) as u32
    }

    fn is_singular(&self) -> bool {
        match self.kind {
            FieldKind::Singular(..) => true,
            _ => false,
        }
    }

    fn is_repeated_packed(&self) -> bool {
        match self.kind {
            FieldKind::Repeated(RepeatedField { packed: true, .. }) => true,
            _ => false,
        }
    }

    pub(crate) fn elem(&self) -> &FieldElem {
        match self.kind {
            FieldKind::Singular(SingularField { ref elem, .. }) => &elem,
            FieldKind::Repeated(RepeatedField { ref elem, .. }) => &elem,
            FieldKind::Oneof(OneofField { ref elem, .. }) => &elem,
            FieldKind::Map(..) => unreachable!(),
        }
    }

    // type of field in struct
    pub(crate) fn full_storage_type(&self, reference: &FileAndMod) -> RustType {
        match self.kind {
            FieldKind::Repeated(ref repeated) => repeated.rust_type(reference),
            FieldKind::Map(MapField {
                ref key, ref value, ..
            }) => RustType::HashMap(
                Box::new(key.rust_storage_elem_type(reference)),
                Box::new(value.rust_storage_elem_type(reference)),
            ),
            FieldKind::Singular(ref singular) => singular.rust_storage_type(reference),
            FieldKind::Oneof(..) => unreachable!(),
        }
    }

    // type of `v` in `for v in field`
    fn full_storage_iter_elem_type(&self, reference: &FileAndMod) -> RustType {
        if let FieldKind::Oneof(ref oneof) = self.kind {
            oneof.elem.rust_storage_elem_type(reference)
        } else {
            self.full_storage_type(reference).iter_elem_type()
        }
    }

    // suffix `xxx` as in `os.write_xxx_no_tag(..)`
    fn os_write_fn_suffix(&self) -> &str {
        self.proto_type.protobuf_name()
    }

    fn os_write_fn_suffix_with_unknown_for_enum(&self) -> &str {
        if self.proto_type == field_descriptor_proto::Type::TYPE_ENUM {
            "enum_or_unknown"
        } else {
            self.os_write_fn_suffix()
        }
    }

    // for field `foo`, type of param of `fn set_foo(..)`
    fn set_xxx_param_type(&self, reference: &FileAndMod) -> RustType {
        match self.kind {
            FieldKind::Singular(SingularField { ref elem, .. })
            | FieldKind::Oneof(OneofField { ref elem, .. }) => {
                elem.rust_set_xxx_param_type(reference)
            }
            FieldKind::Repeated(..) | FieldKind::Map(..) => self.full_storage_type(reference),
        }
    }

    // for field `foo`, return type if `fn take_foo(..)`
    fn take_xxx_return_type(&self, reference: &FileAndMod) -> RustType {
        self.set_xxx_param_type(reference)
    }

    // for field `foo`, return type of `fn mut_foo(..)`
    fn mut_xxx_return_type(&self, reference: &FileAndMod) -> RustType {
        RustType::Ref(Box::new(match self.kind {
            FieldKind::Singular(SingularField { ref elem, .. })
            | FieldKind::Oneof(OneofField { ref elem, .. }) => {
                elem.rust_storage_elem_type(reference)
            }
            FieldKind::Repeated(..) | FieldKind::Map(..) => self.full_storage_type(reference),
        }))
    }

    // for field `foo`, return type of `fn foo(..)`
    fn getter_return_type(&self) -> RustType {
        let reference = self
            .proto_field
            .message
            .scope
            .file_and_mod(self.customize.clone());
        match &self.kind {
            FieldKind::Singular(s) => {
                SingularOrOneofField::Singular(s.clone()).getter_return_type(&reference)
            }
            FieldKind::Oneof(o) => {
                SingularOrOneofField::Oneof(o.clone()).getter_return_type(&reference)
            }
            FieldKind::Repeated(RepeatedField { ref elem, .. }) => RustType::Ref(Box::new(
                RustType::Slice(Box::new(elem.rust_storage_elem_type(&reference))),
            )),
            FieldKind::Map(..) => RustType::Ref(Box::new(self.full_storage_type(&reference))),
        }
    }

    // elem data is not stored in heap
    pub(crate) fn elem_type_is_copy(&self) -> bool {
        self.proto_type.is_copy()
    }

    fn defaut_value_from_proto_float(f: f64, type_name: &str) -> String {
        if f.is_nan() {
            format!("::std::{}::NAN", type_name)
        } else if f.is_infinite() {
            if f > 0.0 {
                format!("::std::{}::INFINITY", type_name)
            } else {
                format!("::std::{}::NEG_INFINITY", type_name)
            }
        } else {
            format!("{:?}{}", f, type_name)
        }
    }

    fn singular_or_oneof_default_value_from_proto(&self, elem: &FieldElem) -> Option<String> {
        if !self.proto_field.field.proto().has_default_value() {
            return None;
        }

        let default_value = self.proto_field.field.singular_default_value();
        Some(match default_value {
            ReflectValueRef::Bool(b) => format!("{}", b),
            ReflectValueRef::I32(v) => format!("{}i32", v),
            ReflectValueRef::I64(v) => format!("{}i64", v),
            ReflectValueRef::U32(v) => format!("{}u32", v),
            ReflectValueRef::U64(v) => format!("{}u64", v),
            ReflectValueRef::String(v) => quote_escape_str(v),
            ReflectValueRef::Bytes(v) => quote_escape_bytes(v),
            ReflectValueRef::F32(v) => Self::defaut_value_from_proto_float(v as f64, "f32"),
            ReflectValueRef::F64(v) => Self::defaut_value_from_proto_float(v as f64, "f64"),
            ReflectValueRef::Enum(_e, _v) => {
                if let &FieldElem::Enum(ref e) = elem {
                    format!("{}", e.default_value_rust_expr(&self.file_and_mod()))
                } else {
                    unreachable!()
                }
            }
            t => panic!("default value is not implemented for type: {:?}", t),
        })
    }

    fn default_value_from_proto(&self) -> Option<String> {
        match self.kind {
            FieldKind::Oneof(OneofField { ref elem, .. })
            | FieldKind::Singular(SingularField { ref elem, .. }) => {
                self.singular_or_oneof_default_value_from_proto(elem)
            }
            _ => unreachable!(),
        }
    }

    fn default_value_from_proto_typed(&self) -> Option<RustValueTyped> {
        self.default_value_from_proto().map(|v| {
            let default_value_type = match self.proto_type {
                field_descriptor_proto::Type::TYPE_STRING => RustType::Ref(Box::new(RustType::Str)),
                field_descriptor_proto::Type::TYPE_BYTES => {
                    RustType::Ref(Box::new(RustType::Slice(Box::new(RustType::u8()))))
                }
                _ => self.full_storage_iter_elem_type(
                    &self
                        .proto_field
                        .message
                        .scope
                        .file_and_mod(self.customize.clone()),
                ),
            };

            RustValueTyped {
                value: v,
                rust_type: default_value_type,
            }
        })
    }

    // default value to be returned from `fn xxx` for field `xxx`.
    fn xxx_default_value_rust(&self) -> String {
        match self.kind {
            FieldKind::Singular(..) | FieldKind::Oneof(..) => {
                self.default_value_from_proto().unwrap_or_else(|| {
                    self.getter_return_type()
                        .default_value(&self.customize, false)
                })
            }
            _ => unreachable!(),
        }
    }

    // default to be assigned to field
    fn element_default_value_rust(&self) -> RustValueTyped {
        match self.kind {
            FieldKind::Singular(..) | FieldKind::Oneof(..) => {
                self.default_value_from_proto_typed().unwrap_or_else(|| {
                    self.elem()
                        .rust_storage_elem_type(
                            &self
                                .proto_field
                                .message
                                .scope
                                .file_and_mod(self.customize.clone()),
                        )
                        .default_value_typed(&self.customize, false)
                })
            }
            _ => unreachable!(),
        }
    }

    pub(crate) fn reconstruct_def(&self) -> String {
        let prefix = match (self.proto_field.field.proto().label(), self.syntax) {
            (field_descriptor_proto::Label::LABEL_REPEATED, _) => "repeated ",
            (_, Syntax::Proto3) => "",
            (field_descriptor_proto::Label::LABEL_OPTIONAL, _) => "optional ",
            (field_descriptor_proto::Label::LABEL_REQUIRED, _) => "required ",
        };
        format!(
            "{}{} {} = {}",
            prefix,
            field_type_protobuf_name(self.proto_field.field.proto()),
            self.proto_field.name(),
            self.proto_field.number()
        )
    }

    pub(crate) fn write_clear(&self, w: &mut CodeWriter) {
        match self.kind {
            FieldKind::Oneof(ref o) => {
                w.write_line(&format!(
                    "self.{} = ::std::option::Option::None;",
                    o.oneof_field_name
                ));
            }
            _ => {
                let clear_expr = self
                    .full_storage_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    )
                    .clear(&self.self_field(), &self.customize);
                w.write_line(&format!("{};", clear_expr));
            }
        }
    }

    // output code that writes single element to stream
    pub(crate) fn write_write_element(
        &self,
        elem: &FieldElem,
        w: &mut CodeWriter,
        os: &str,
        v: &RustValueTyped,
    ) {
        assert!(!self.is_repeated_packed());

        elem.write_write_element(
            self.proto_field.number() as u32,
            v,
            &self.file_and_mod(),
            &self.customize,
            os,
            w,
        );
    }

    fn self_field(&self) -> String {
        format!("self.{}", self.rust_name)
    }

    fn self_field_is_some(&self) -> String {
        assert!(self.is_singular());
        format!("{}.is_some()", self.self_field())
    }

    fn self_field_is_none(&self) -> String {
        assert!(self.is_singular());
        format!("{}.is_none()", self.self_field())
    }

    // field data viewed as Option
    fn self_field_as_option(&self, elem: &FieldElem, option_kind: OptionKind) -> RustValueTyped {
        match self.full_storage_type(
            &self
                .proto_field
                .message
                .scope
                .file_and_mod(self.customize.clone()),
        ) {
            RustType::Option(ref e) if e.is_copy() => {
                return RustType::Option(e.clone()).value(self.self_field());
            }
            _ => {}
        };

        let as_option_type = option_kind.as_ref_type(
            elem.rust_storage_elem_type(
                &self
                    .proto_field
                    .message
                    .scope
                    .file_and_mod(self.customize.clone()),
            ),
        );

        as_option_type.value(format!("{}.as_ref()", self.self_field()))
    }

    pub(crate) fn write_struct_field(&self, w: &mut CodeWriter) {
        if self.proto_type == field_descriptor_proto::Type::TYPE_GROUP {
            w.comment(&format!("{}: <group>", &self.rust_name));
        } else {
            w.all_documentation(self.info, &self.path);

            write_protoc_insertion_point_for_field(w, &self.customize, &self.proto_field.field);
            w.field_decl_vis(
                Visibility::Public,
                &self.rust_name.to_string(),
                &self
                    .full_storage_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    )
                    .to_code(&self.customize),
            );
        }
    }

    fn write_if_let_self_field_is_some<F>(&self, s: &SingularField, w: &mut CodeWriter, cb: F)
    where
        F: Fn(&RustValueTyped, &mut CodeWriter),
    {
        match s {
            SingularField {
                flag: SingularFieldFlag::WithFlag { option_kind, .. },
                ref elem,
            } => {
                let var = "v";
                let ref_prefix = match elem
                    .rust_storage_elem_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    )
                    .is_copy()
                {
                    true => "",
                    false => "",
                };
                let as_option = self.self_field_as_option(elem, *option_kind);
                w.if_let_stmt(
                    &format!("Some({}{})", ref_prefix, var),
                    &as_option.value,
                    |w| {
                        let v = RustValueTyped {
                            value: var.to_owned(),
                            rust_type: as_option.rust_type.elem_type(),
                        };
                        cb(&v, w);
                    },
                );
            }
            SingularField {
                flag: SingularFieldFlag::WithoutFlag,
                ref elem,
            } => match *elem {
                FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)
                | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => {
                    w.if_stmt(format!("!{}.is_empty()", self.self_field()), |w| {
                        let v = RustValueTyped {
                            value: self.self_field(),
                            rust_type: self.full_storage_type(
                                &self
                                    .proto_field
                                    .message
                                    .scope
                                    .file_and_mod(self.customize.clone()),
                            ),
                        };
                        cb(&v, w);
                    });
                }
                _ => {
                    w.if_stmt(
                        format!(
                            "{} != {}",
                            self.self_field(),
                            self.full_storage_type(
                                &self
                                    .proto_field
                                    .message
                                    .scope
                                    .file_and_mod(self.customize.clone())
                            )
                            .default_value(&self.customize, false)
                        ),
                        |w| {
                            let v = RustValueTyped {
                                value: self.self_field(),
                                rust_type: self.full_storage_type(
                                    &self
                                        .proto_field
                                        .message
                                        .scope
                                        .file_and_mod(self.customize.clone()),
                                ),
                            };
                            cb(&v, w);
                        },
                    );
                }
            },
        }
    }

    pub(crate) fn write_if_self_field_is_none<F>(&self, w: &mut CodeWriter, cb: F)
    where
        F: Fn(&mut CodeWriter),
    {
        let self_field_is_none = self.self_field_is_none();
        w.if_stmt(self_field_is_none, cb)
    }

    // repeated or singular
    pub(crate) fn write_for_self_field<F>(&self, w: &mut CodeWriter, varn: &str, cb: F)
    where
        F: Fn(&mut CodeWriter, &RustType),
    {
        let file_and_mod = self
            .proto_field
            .message
            .scope
            .file_and_mod(self.customize.clone());

        match &self.kind {
            FieldKind::Oneof(oneof_field) => {
                let cond = format!(
                    "Some({}(ref {}))",
                    oneof_field.variant_path(&file_and_mod.relative_mod),
                    varn
                );
                w.if_let_stmt(
                    &cond,
                    &format!("self.{}", oneof_field.oneof_field_name),
                    |w| cb(w, &oneof_field.elem.rust_storage_elem_type(&file_and_mod)),
                )
            }
            _ => {
                let v_type = self.full_storage_iter_elem_type(&file_and_mod);
                let self_field = self.self_field();
                w.for_stmt(&format!("&{}", self_field), varn, |w| cb(w, &v_type));
            }
        }
    }

    fn write_self_field_assign(&self, w: &mut CodeWriter, value: &str) {
        let self_field = self.self_field();
        w.write_line(&format!("{} = {};", self_field, value));
    }

    fn write_self_field_assign_some(&self, w: &mut CodeWriter, s: &SingularField, value: &str) {
        match s {
            &SingularField {
                flag: SingularFieldFlag::WithFlag { option_kind, .. },
                ..
            } => {
                self.write_self_field_assign(w, &option_kind.wrap_value(value, &self.customize));
            }
            &SingularField {
                flag: SingularFieldFlag::WithoutFlag,
                ..
            } => {
                self.write_self_field_assign(w, value);
            }
        }
    }

    fn write_self_field_assign_value_singular(
        &self,
        w: &mut CodeWriter,
        s: &SingularField,
        value: &RustValueTyped,
    ) {
        let SingularField { ref elem, ref flag } = s;
        let converted = value.into_type(
            elem.rust_storage_elem_type(
                &self
                    .proto_field
                    .message
                    .scope
                    .file_and_mod(self.customize.clone()),
            )
            .clone(),
            &self.customize,
        );
        let wrapped = match flag {
            SingularFieldFlag::WithoutFlag => converted.value,
            SingularFieldFlag::WithFlag { option_kind, .. } => {
                option_kind.wrap_value(&converted.value, &self.customize)
            }
        };
        self.write_self_field_assign(w, &wrapped);
    }

    fn write_self_field_assign_value(&self, w: &mut CodeWriter, value: &RustValueTyped) {
        match self.kind {
            FieldKind::Repeated(..) | FieldKind::Map(..) => {
                let converted = value.into_type(
                    self.full_storage_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    ),
                    &self.customize,
                );
                self.write_self_field_assign(w, &converted.value);
            }
            FieldKind::Singular(ref s) => {
                self.write_self_field_assign_value_singular(w, s, value);
            }
            FieldKind::Oneof(..) => unreachable!(),
        }
    }

    fn write_self_field_assign_default(
        &self,
        field_kind: &SingularOrOneofField,
        w: &mut CodeWriter,
    ) {
        match field_kind {
            SingularOrOneofField::Oneof(oneof) => {
                w.write_line(format!(
                    "self.{} = ::std::option::Option::Some({}({}))",
                    oneof.oneof_field_name,
                    oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
                    // TODO: default from .proto is not needed here (?)
                    self.element_default_value_rust()
                        .into_type(
                            self.full_storage_iter_elem_type(
                                &self
                                    .proto_field
                                    .message
                                    .scope
                                    .file_and_mod(self.customize.clone())
                            ),
                            &self.customize
                        )
                        .value
                ));
            }
            SingularOrOneofField::Singular(singular) => {
                // Note it is different from C++ protobuf, where field is initialized
                // with default value
                match singular.flag {
                    SingularFieldFlag::WithFlag { option_kind, .. } => match option_kind {
                        OptionKind::MessageField => {
                            let self_field = self.self_field();
                            w.write_line(&format!("{}.set_default();", self_field));
                        }
                        _ => {
                            self.write_self_field_assign_some(
                                w,
                                singular,
                                &self
                                    .elem()
                                    .rust_storage_elem_type(
                                        &self
                                            .proto_field
                                            .message
                                            .scope
                                            .file_and_mod(self.customize.clone()),
                                    )
                                    .default_value_typed(&self.customize, false)
                                    .into_type(
                                        singular.elem.rust_storage_elem_type(
                                            &self
                                                .proto_field
                                                .message
                                                .scope
                                                .file_and_mod(self.customize.clone()),
                                        ),
                                        &self.customize,
                                    )
                                    .value,
                            );
                        }
                    },
                    SingularFieldFlag::WithoutFlag => unimplemented!(),
                }
            }
        }
    }

    fn self_field_vec_packed_size(&self) -> String {
        let fn_name = match self.proto_type {
            Type::TYPE_ENUM => "vec_packed_enum_or_unknown_size",
            Type::TYPE_SINT32 => "vec_packed_sint32_size",
            Type::TYPE_SINT64 => "vec_packed_sint64_size",
            Type::TYPE_INT32 => "vec_packed_int32_size",
            Type::TYPE_INT64 => "vec_packed_int64_size",
            Type::TYPE_UINT32 => "vec_packed_uint32_size",
            Type::TYPE_UINT64 => "vec_packed_uint64_size",
            Type::TYPE_BOOL => "vec_packed_bool_size",
            Type::TYPE_FIXED32 => "vec_packed_fixed32_size",
            Type::TYPE_FIXED64 => "vec_packed_fixed64_size",
            Type::TYPE_SFIXED32 => "vec_packed_sfixed32_size",
            Type::TYPE_SFIXED64 => "vec_packed_sfixed64_size",
            Type::TYPE_FLOAT => "vec_packed_float_size",
            Type::TYPE_DOUBLE => "vec_packed_double_size",
            t => unreachable!("{:?}", t),
        };
        format!(
            "{}::rt::{fn_name}({}, &{})",
            protobuf_crate_path(&self.customize),
            self.proto_field.number(),
            self.self_field()
        )
    }

    pub(crate) fn clear_field_func(&self) -> String {
        format!("clear_{}", self.rust_name)
    }

    fn write_merge_from_field_message_string_bytes_repeated(
        &self,
        r: &RepeatedField,
        w: &mut CodeWriter,
    ) {
        let read_fn = match &r.elem {
            FieldElem::Message(..) => "read_message",
            FieldElem::Primitive(Type::TYPE_STRING, PrimitiveTypeVariant::Default) => "read_string",
            FieldElem::Primitive(Type::TYPE_STRING, PrimitiveTypeVariant::TokioBytes) => {
                "read_tokio_chars"
            }
            FieldElem::Primitive(Type::TYPE_BYTES, PrimitiveTypeVariant::Default) => "read_bytes",
            FieldElem::Primitive(Type::TYPE_BYTES, PrimitiveTypeVariant::TokioBytes) => {
                "read_tokio_bytes"
            }
            _ => unreachable!("for field {}", self.proto_field.field),
        };
        w.write_line(&format!("self.{}.push(is.{}()?);", self.rust_name, read_fn,));
    }

    fn tag_with_wire_type(&self, wire_type: WireType) -> u32 {
        make_tag(self.proto_field.number() as u32, wire_type)
    }

    fn tag(&self) -> u32 {
        self.tag_with_wire_type(self.wire_type)
    }

    // Write `merge_from` part for this oneof field
    fn write_merge_from_oneof_case_block(&self, o: &OneofField, w: &mut CodeWriter) {
        w.case_block(&format!("{}", self.tag()), |w| {
            let typed = RustValueTyped {
                value: format!(
                    "{}?",
                    self.proto_type.read("is", o.elem.primitive_type_variant())
                ),
                rust_type: self.full_storage_iter_elem_type(
                    &self
                        .proto_field
                        .message
                        .scope
                        .file_and_mod(self.customize.clone()),
                ),
            };

            let maybe_boxed = if o.boxed {
                typed.boxed(&self.customize)
            } else {
                typed
            };

            w.write_line(&format!(
                "self.{} = ::std::option::Option::Some({}({}));",
                o.oneof_field_name,
                o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
                maybe_boxed.value
            ));
        })
    }

    // Write `merge_from` part for this map field
    fn write_merge_from_map_case_block(&self, map: &MapField, w: &mut CodeWriter) {
        let MapField { key, value, .. } = map;
        w.case_block(&format!("{}", self.tag()), |w| {
            w.write_line(&format!("let len = is.read_raw_varint32()?;",));
            w.write_line(&format!("let old_limit = is.push_limit(len as u64)?;"));
            w.write_line(&format!(
                "let mut key = ::std::default::Default::default();"
            ));
            w.write_line(&format!(
                "let mut value = ::std::default::Default::default();"
            ));
            w.while_block("let Some(tag) = is.read_raw_tag_or_eof()?", |w| {
                w.match_block("tag", |w| {
                    let key_tag = make_tag(1, WireType::for_type(key.proto_type()));
                    let value_tag = make_tag(2, WireType::for_type(value.proto_type()));
                    w.case_expr(
                        &format!("{key_tag}"),
                        &format!("key = {read}", read = key.read_one_liner()),
                    );
                    w.case_expr(
                        &format!("{value_tag}"),
                        &format!("value = {read}", read = value.read_one_liner()),
                    );
                    w.case_expr(
                        "_",
                        &format!(
                            "{protobuf_crate}::rt::skip_field_for_tag(tag, is)?",
                            protobuf_crate = protobuf_crate_path(&self.customize)
                        ),
                    );
                });
            });
            w.write_line(&format!("is.pop_limit(old_limit);"));
            w.write_line(&format!(
                "{field}.insert(key, value);",
                field = self.self_field()
            ));
        });
    }

    // Write `merge_from` part for this singular field
    fn write_merge_from_singular_case_block(&self, s: &SingularField, w: &mut CodeWriter) {
        w.case_block(&format!("{}", self.tag()), |w| match s.elem {
            FieldElem::Message(..) => {
                w.write_line(&format!(
                    "{}::rt::read_singular_message_into_field(is, &mut self.{})?;",
                    protobuf_crate_path(&self.customize),
                    self.rust_name,
                ));
            }
            _ => {
                let read_proc = s.elem.read_one_liner();
                self.write_self_field_assign_some(w, s, &read_proc);
            }
        })
    }

    // Write `merge_from` part for this repeated field
    fn write_merge_from_repeated_case_block(&self, w: &mut CodeWriter) {
        let field = match self.kind {
            FieldKind::Repeated(ref field) => field,
            _ => panic!(),
        };

        match field.elem {
            FieldElem::Message(..)
            | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)
            | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => {
                w.case_block(&format!("{}", self.tag()), |w| {
                    self.write_merge_from_field_message_string_bytes_repeated(field, w);
                })
            }
            FieldElem::Enum(..) => {
                w.case_block(
                    &format!("{}", self.tag_with_wire_type(WireType::Varint)),
                    |w| {
                        w.write_line(&format!(
                            "self.{}.push(is.read_enum_or_unknown()?);",
                            self.rust_name,
                        ));
                    },
                );
                w.case_block(
                    &format!("{}", self.tag_with_wire_type(WireType::LengthDelimited)),
                    |w| {
                        w.write_line(&format!(
                            "{}::rt::read_repeated_packed_enum_or_unknown_into(is, &mut self.{})?",
                            protobuf_crate_path(&self.customize),
                            self.rust_name,
                        ));
                    },
                );
            }
            _ => {
                assert_ne!(self.wire_type, WireType::LengthDelimited);
                w.case_block(
                    &format!("{}", self.tag_with_wire_type(WireType::LengthDelimited)),
                    |w| {
                        w.write_line(&format!(
                            "is.read_repeated_packed_{}_into(&mut self.{})?;",
                            self.proto_type.protobuf_name(),
                            self.rust_name
                        ));
                    },
                );
                w.case_block(&format!("{}", self.tag()), |w| {
                    w.write_line(&format!(
                        "self.{}.push(is.read_{}()?);",
                        self.rust_name,
                        self.proto_type.protobuf_name(),
                    ));
                });
            }
        }
    }

    /// Write `merge_from` part for this field
    pub(crate) fn write_merge_from_field_case_block(&self, w: &mut CodeWriter) {
        match &self.kind {
            FieldKind::Oneof(oneof) => self.write_merge_from_oneof_case_block(oneof, w),
            FieldKind::Map(map) => self.write_merge_from_map_case_block(map, w),
            FieldKind::Singular(ref s) => self.write_merge_from_singular_case_block(s, w),
            FieldKind::Repeated(..) => self.write_merge_from_repeated_case_block(w),
        }
    }

    pub(crate) fn write_element_size(
        &self,
        elem: &FieldElem,
        w: &mut CodeWriter,
        item_var: &RustValueTyped,
        sum_var: &str,
    ) {
        assert!(!self.is_repeated_packed());

        elem.write_element_size(
            self.proto_field.number() as u32,
            item_var,
            HowToGetMessageSize::Compute,
            sum_var,
            &self.customize,
            w,
        );
    }

    fn write_write_map_field(
        &self,
        key: &FieldElem,
        value: &FieldElem,
        os: &str,
        w: &mut CodeWriter,
    ) {
        self.for_each_map_entry(key, value, w, |k, v, w| {
            w.write_line("let mut entry_size = 0;");
            key.write_element_size(
                1,
                k,
                HowToGetMessageSize::GetCached,
                "entry_size",
                &self.customize,
                w,
            );
            value.write_element_size(
                2,
                v,
                HowToGetMessageSize::GetCached,
                "entry_size",
                &self.customize,
                w,
            );
            w.write_line(&format!(
                "{os}.write_raw_varint32({tag})?; // Tag.",
                tag = make_tag(self.proto_field.number() as u32, WireType::LengthDelimited),
            ));
            w.write_line(&format!("{os}.write_raw_varint32(entry_size as u32)?;",));
            key.write_write_element(1, k, &self.file_and_mod(), &self.customize, os, w);
            value.write_write_element(2, v, &self.file_and_mod(), &self.customize, os, w);
        });
    }

    pub(crate) fn write_message_write_field(&self, os: &str, w: &mut CodeWriter) {
        match &self.kind {
            FieldKind::Singular(s @ SingularField { elem, .. }) => {
                self.write_if_let_self_field_is_some(s, w, |v, w| {
                    self.write_write_element(&elem, w, os, &v);
                });
            }
            FieldKind::Repeated(RepeatedField {
                packed: false,
                elem,
                ..
            }) => {
                self.write_for_self_field(w, "v", |w, v_type| {
                    let v = RustValueTyped {
                        value: "v".to_owned(),
                        rust_type: v_type.clone(),
                    };
                    self.write_write_element(elem, w, "os", &v);
                });
            }
            FieldKind::Repeated(RepeatedField { packed: true, .. }) => {
                w.write_line(&format!(
                    "os.write_repeated_packed_{}({}, &{})?;",
                    self.os_write_fn_suffix_with_unknown_for_enum(),
                    self.proto_field.number(),
                    self.self_field()
                ));
            }
            FieldKind::Map(MapField { key, value, .. }) => {
                self.write_write_map_field(key, value, os, w)
            }
            FieldKind::Oneof(..) => unreachable!(),
        };
    }

    fn for_each_map_entry(
        &self,
        key: &FieldElem,
        value: &FieldElem,
        w: &mut CodeWriter,
        cb: impl FnOnce(&RustValueTyped, &RustValueTyped, &mut CodeWriter),
    ) {
        w.for_stmt(&format!("&{}", self.self_field()), "(k, v)", move |w| {
            let k = RustValueTyped {
                value: "k".to_owned(),
                rust_type: key.rust_storage_elem_type(&self.file_and_mod()).wrap_ref(),
            };
            let v = RustValueTyped {
                value: "v".to_owned(),
                rust_type: value
                    .rust_storage_elem_type(&self.file_and_mod())
                    .wrap_ref(),
            };
            cb(&k, &v, w)
        });
    }

    fn write_compute_map_field_size(
        &self,
        sum_var: &str,
        key: &FieldElem<'a>,
        value: &FieldElem<'a>,
        w: &mut CodeWriter,
    ) {
        self.for_each_map_entry(key, value, w, |k, v, w| {
                w.write_line("let mut entry_size = 0;");
                key.write_element_size(1, k, HowToGetMessageSize::Compute, "entry_size", &self.customize, w);
                value.write_element_size(2, v, HowToGetMessageSize::Compute, "entry_size", &self.customize, w);
                w.write_line(&format!("{sum_var} += {tag_size} + {protobuf_crate}::rt::compute_raw_varint64_size(entry_size) + entry_size",
                    tag_size = self.tag_size(),
                    protobuf_crate = protobuf_crate_path(&self.customize),
                ));
        });
    }

    pub(crate) fn write_message_compute_field_size(&self, sum_var: &str, w: &mut CodeWriter) {
        match &self.kind {
            FieldKind::Singular(s @ SingularField { elem, .. }) => {
                self.write_if_let_self_field_is_some(s, w, |v, w| {
                    self.write_element_size(&elem, w, v, sum_var)
                });
            }
            FieldKind::Repeated(RepeatedField {
                packed: false,
                elem,
                ..
            }) => {
                match elem.proto_type().encoded_size() {
                    Some(s) => {
                        let tag_size = self.tag_size();
                        let self_field = self.self_field();
                        w.write_line(&format!(
                            "{} += {} * {}.len() as u64;",
                            sum_var,
                            (s + tag_size) as isize,
                            self_field
                        ));
                    }
                    None => {
                        self.write_for_self_field(w, "value", |w, value_type| {
                            self.write_element_size(
                                elem,
                                w,
                                &RustValueTyped {
                                    value: "value".to_owned(),
                                    rust_type: value_type.clone(),
                                },
                                sum_var,
                            );
                        });
                    }
                };
            }
            FieldKind::Repeated(RepeatedField { packed: true, .. }) => {
                let size_expr = self.self_field_vec_packed_size();
                w.write_line(&format!("{} += {};", sum_var, size_expr));
            }
            FieldKind::Map(MapField { key, value, .. }) => {
                self.write_compute_map_field_size(sum_var, key, value, w)
            }
            FieldKind::Oneof(..) => unreachable!(),
        }
    }

    fn write_message_field_get_singular_message(&self, s: &SingularField, w: &mut CodeWriter) {
        match s.flag {
            SingularFieldFlag::WithoutFlag => unimplemented!(),
            SingularFieldFlag::WithFlag { option_kind, .. } => {
                let self_field = self.self_field();
                let ref field_type_name = self.elem().rust_storage_elem_type(
                    &self
                        .proto_field
                        .message
                        .scope
                        .file_and_mod(self.customize.clone()),
                );
                w.write_line(option_kind.unwrap_ref_or_else(
                    &format!("{}.as_ref()", self_field),
                    &format!(
                        "<{} as {}::Message>::default_instance()",
                        field_type_name.to_code(&self.customize),
                        protobuf_crate_path(&self.customize),
                    ),
                ));
            }
        }
    }

    fn write_message_field_get_singular_enum(
        &self,
        flag: SingularFieldFlag,
        _elem: &FieldElemEnum,
        w: &mut CodeWriter,
    ) {
        match flag {
            SingularFieldFlag::WithoutFlag => {
                w.write_line(&format!("self.{}.enum_value_or_default()", self.rust_name));
            }
            SingularFieldFlag::WithFlag { .. } => {
                w.match_expr(&self.self_field(), |w| {
                    let default_value = self.xxx_default_value_rust();
                    w.case_expr("Some(e)", &format!("e.enum_value_or({})", default_value));
                    w.case_expr("None", &format!("{}", default_value));
                });
            }
        }
    }

    fn write_message_field_get_singular(&self, singular: &SingularField, w: &mut CodeWriter) {
        let get_xxx_return_type = self.getter_return_type();

        match singular.elem {
            FieldElem::Message(..) => self.write_message_field_get_singular_message(singular, w),
            FieldElem::Enum(ref en) => {
                self.write_message_field_get_singular_enum(singular.flag, en, w)
            }
            _ => {
                let get_xxx_default_value_rust = self.xxx_default_value_rust();
                let self_field = self.self_field();
                match singular {
                    &SingularField {
                        ref elem,
                        flag: SingularFieldFlag::WithFlag { option_kind, .. },
                        ..
                    } => {
                        if get_xxx_return_type.is_ref().is_some() {
                            let as_option = self.self_field_as_option(elem, option_kind);
                            w.match_expr(&as_option.value, |w| {
                                let v_type = as_option.rust_type.elem_type();
                                let r_type = self.getter_return_type();
                                w.case_expr(
                                    "Some(v)",
                                    v_type.into_target(&r_type, "v", &self.customize),
                                );
                                let get_xxx_default_value_rust = self.xxx_default_value_rust();
                                w.case_expr("None", get_xxx_default_value_rust);
                            });
                        } else {
                            w.write_line(&format!(
                                "{}.unwrap_or({})",
                                self_field, get_xxx_default_value_rust
                            ));
                        }
                    }
                    &SingularField {
                        flag: SingularFieldFlag::WithoutFlag,
                        ..
                    } => {
                        w.write_line(
                            self.full_storage_type(
                                &self
                                    .proto_field
                                    .message
                                    .scope
                                    .file_and_mod(self.customize.clone()),
                            )
                            .into_target(
                                &get_xxx_return_type,
                                &self_field,
                                &self.customize,
                            ),
                        );
                    }
                }
            }
        }
    }

    fn write_message_field_get_oneof(&self, o: &OneofField, w: &mut CodeWriter) {
        let get_xxx_return_type = SingularOrOneofField::Oneof(o.clone()).getter_return_type(
            &self
                .proto_field
                .message
                .scope
                .file_and_mod(self.customize.clone()),
        );
        let OneofField { ref elem, .. } = o;
        w.match_expr(&format!("self.{}", o.oneof_field_name), |w| {
            let (refv, vtype) = if !elem.is_copy() {
                (
                    "ref v",
                    elem.rust_storage_elem_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    )
                    .ref_type(),
                )
            } else {
                (
                    "v",
                    elem.rust_storage_elem_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    ),
                )
            };
            w.case_expr(
                format!(
                    "::std::option::Option::Some({}({}))",
                    o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
                    refv
                ),
                vtype.into_target(&get_xxx_return_type, "v", &self.customize),
            );
            w.case_expr("_", self.xxx_default_value_rust());
        });
    }

    fn write_message_field_get(&self, w: &mut CodeWriter) {
        let get_xxx_return_type = self.getter_return_type();
        let fn_def = format!(
            "{}(&self) -> {}",
            self.rust_name,
            get_xxx_return_type.to_code(&self.customize)
        );

        w.pub_fn(&fn_def, |w| match self.kind {
            FieldKind::Oneof(ref o) => {
                self.write_message_field_get_oneof(o, w);
            }
            FieldKind::Singular(ref s) => {
                self.write_message_field_get_singular(s, w);
            }
            FieldKind::Repeated(..) | FieldKind::Map(..) => {
                let self_field = self.self_field();
                w.write_line(&format!("&{}", self_field));
            }
        });
    }

    fn has_has(&self) -> bool {
        match self.kind {
            FieldKind::Repeated(..) | FieldKind::Map(..) => false,
            FieldKind::Singular(SingularField {
                flag: SingularFieldFlag::WithFlag { .. },
                ..
            }) => true,
            FieldKind::Singular(SingularField {
                flag: SingularFieldFlag::WithoutFlag,
                ..
            }) => false,
            FieldKind::Oneof(..) => true,
        }
    }

    fn has_mut(&self) -> bool {
        match self.kind {
            FieldKind::Repeated(..) | FieldKind::Map(..) => true,
            // TODO: string should be public, and mut is not needed
            FieldKind::Singular(..) | FieldKind::Oneof(..) => !self.elem_type_is_copy(),
        }
    }

    fn has_take(&self) -> bool {
        match self.kind {
            FieldKind::Repeated(..) | FieldKind::Map(..) => true,
            // TODO: string should be public, and mut is not needed
            FieldKind::Singular(..) | FieldKind::Oneof(..) => !self.elem_type_is_copy(),
        }
    }

    fn has_name(&self) -> RustIdent {
        RustIdent::new(&format!("has_{}", self.rust_name.get()))
    }

    fn set_name(&self) -> RustIdent {
        RustIdent::new(&format!("set_{}", self.rust_name.get()))
    }

    fn mut_name(&self) -> RustIdent {
        RustIdent::new(&format!("mut_{}", self.rust_name.get()))
    }

    fn write_message_field_has(&self, w: &mut CodeWriter) {
        w.pub_fn(
            &format!("{}(&self) -> bool", self.has_name()),
            |w| match self.kind {
                FieldKind::Oneof(ref oneof) => {
                    w.match_expr(&format!("self.{}", oneof.oneof_field_name), |w| {
                        w.case_expr(
                            format!(
                                "::std::option::Option::Some({}(..))",
                                oneof.variant_path(
                                    &self.proto_field.message.scope.rust_path_to_file()
                                )
                            ),
                            "true",
                        );
                        w.case_expr("_", "false");
                    });
                }
                _ => {
                    let self_field_is_some = self.self_field_is_some();
                    w.write_line(self_field_is_some);
                }
            },
        );
    }

    fn write_message_field_set(&self, w: &mut CodeWriter) {
        let set_xxx_param_type = self.set_xxx_param_type(
            &self
                .proto_field
                .message
                .scope
                .file_and_mod(self.customize.clone()),
        );
        w.comment("Param is passed by value, moved");
        w.pub_fn(
            &format!(
                "{}(&mut self, v: {})",
                self.set_name(),
                set_xxx_param_type.to_code(&self.customize)
            ),
            |w| {
                let value_typed = RustValueTyped {
                    value: "v".to_owned(),
                    rust_type: set_xxx_param_type.clone(),
                };
                match self.kind {
                    FieldKind::Oneof(ref oneof) => {
                        let v = set_xxx_param_type.into_target(
                            &oneof.rust_type(
                                &self
                                    .proto_field
                                    .message
                                    .scope
                                    .file_and_mod(self.customize.clone()),
                            ),
                            "v",
                            &self.customize,
                        );
                        w.write_line(&format!(
                            "self.{} = ::std::option::Option::Some({}({}))",
                            oneof.oneof_field_name,
                            oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
                            v
                        ));
                    }
                    _ => {
                        self.write_self_field_assign_value(w, &value_typed);
                    }
                }
            },
        );
    }

    fn write_message_field_mut_singular_with_flag(
        &self,
        s: &SingularField,
        option_kind: OptionKind,
        w: &mut CodeWriter,
    ) {
        let self_field = self.self_field();
        match option_kind {
            OptionKind::MessageField => {
                w.write_line(&format!("{}.mut_or_insert_default()", self_field))
            }
            OptionKind::Option => {
                self.write_if_self_field_is_none(w, |w| {
                    self.write_self_field_assign_default(
                        &SingularOrOneofField::Singular(s.clone()),
                        w,
                    );
                });
                w.write_line(&format!("{}.as_mut().unwrap()", self_field));
            }
        }
    }

    fn write_message_field_mut_singular(&self, s: &SingularField, w: &mut CodeWriter) {
        match s {
            s @ SingularField {
                flag: SingularFieldFlag::WithFlag { option_kind, .. },
                ..
            } => self.write_message_field_mut_singular_with_flag(s, *option_kind, w),
            SingularField {
                flag: SingularFieldFlag::WithoutFlag,
                ..
            } => w.write_line(&format!("&mut {}", self.self_field())),
        }
    }

    fn write_message_field_mut(&self, w: &mut CodeWriter) {
        let mut_xxx_return_type = self.mut_xxx_return_type(
            &self
                .proto_field
                .message
                .scope
                .file_and_mod(self.customize.clone()),
        );
        w.comment("Mutable pointer to the field.");
        if self.is_singular() {
            w.comment("If field is not initialized, it is initialized with default value first.");
        }
        let fn_def = match mut_xxx_return_type {
            RustType::Ref(ref param) => format!(
                "{}(&mut self) -> &mut {}",
                self.mut_name(),
                param.to_code(&self.customize)
            ),
            _ => panic!(
                "not a ref: {}",
                mut_xxx_return_type.to_code(&self.customize)
            ),
        };
        w.pub_fn(&fn_def, |w| {
            match self.kind {
                FieldKind::Repeated(..) | FieldKind::Map(..) => {
                    let self_field = self.self_field();
                    w.write_line(&format!("&mut {}", self_field));
                }
                FieldKind::Singular(ref s) => {
                    self.write_message_field_mut_singular(s, w);
                }
                FieldKind::Oneof(ref o) => {
                    let self_field_oneof = format!("self.{}", o.oneof_field_name);

                    // if oneof does not contain current field
                    w.if_let_else_stmt(
                        &format!(
                            "::std::option::Option::Some({}(_))",
                            o.variant_path(&self.proto_field.message.scope.rust_path_to_file())
                        )[..],
                        &self_field_oneof[..],
                        |w| {
                            // initialize it with default value
                            w.write_line(&format!(
                                "{} = ::std::option::Option::Some({}({}));",
                                self_field_oneof,
                                o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),
                                self.element_default_value_rust()
                                    .into_type(
                                        o.rust_type(
                                            &self
                                                .proto_field
                                                .message
                                                .scope
                                                .file_and_mod(self.customize.clone())
                                        ),
                                        &self.customize
                                    )
                                    .value
                            ));
                        },
                    );

                    // extract field
                    w.match_expr(self_field_oneof, |w| {
                        w.case_expr(
                            format!(
                                "::std::option::Option::Some({}(ref mut v))",
                                o.variant_path(&self.proto_field.message.scope.rust_path_to_file())
                            ),
                            "v",
                        );
                        w.case_expr("_", "panic!()");
                    });
                }
            }
        });
    }

    fn write_message_field_take_oneof(&self, o: &OneofField, w: &mut CodeWriter) {
        let take_xxx_return_type = self.take_xxx_return_type(
            &self
                .proto_field
                .message
                .scope
                .file_and_mod(self.customize.clone()),
        );

        // TODO: replace with if let
        }
    }

    // Write `merge_from` part for this field
    fn write_merge_from_field(&self, wire_type_var: &str, w: &mut CodeWriter) {
        match self.kind {
            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),
            FieldKind::Map(..) => self.write_merge_from_map(w),
            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),
            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),
        }
    }

    pub(crate) fn write_merge_from_field_case_block(
        &self,
        wire_type_var: &str,
        w: &mut CodeWriter,
    ) {
        let number = self.proto_field.number();
        w.case_block(number.to_string(), |w| {
            self.write_merge_from_field(wire_type_var, w);
        });
    }

                            .scope
                            .file_and_mod(self.customize.clone()),
                    ),
                    &self.customize,
                );
                w.case_expr(
                    format!(
                        "::std::option::Option::Some({}(v))",
                        o.variant_path(&self.proto_field.message.scope.rust_path_to_file())
                    ),
                    &converted.value,
                );
                w.case_expr("_", "panic!()");
            });
        });
        w.write_line("} else {");
        w.indented(|w| {
            w.write_line(
                self.elem()
                    .rust_storage_elem_type(
                        &self
                            .proto_field
                            .message
                            .scope
                            .file_and_mod(self.customize.clone()),
                    )
                    .default_value_typed(&self.customize, false)
                    .into_type(take_xxx_return_type.clone(), &self.customize)
                    .value,
            );
        });
        w.write_line("}");
    }

    fn write_message_field_take_singular(&self, s: &SingularField, w: &mut CodeWriter) {
        match s {
            SingularField {
                ref elem,
                flag: SingularFieldFlag::WithFlag { option_kind, .. },
            } => {
                if !elem.is_copy() {
                    w.write_line(
                        &option_kind.unwrap_or_else(
                            &format!("{}.take()", self.self_field()),
                            &elem
                                .rust_storage_elem_type(
                                    &self
                                        .proto_field
                                        .message
                                        .scope
                                        .file_and_mod(self.customize.clone()),
                                )
                                .default_value(&self.customize, false),
                        ),
                    );
                } else {
                    w.write_line(&format!(
                        "{}.take().unwrap_or({})",
                        self.self_field(),
                        self.element_default_value_rust().value
                    ));
                }
            }
            SingularField {
                flag: SingularFieldFlag::WithoutFlag,
                ..
            } => w.write_line(&format!(
                "::std::mem::replace(&mut {}, {})",
                self.self_field(),
                self.full_storage_type(
                    &self
                        .proto_field
                        .message
                        .scope
                        .file_and_mod(self.customize.clone())
                )
                .default_value(&self.customize, false)
            )),
        }
    }

    fn write_message_field_take(&self, w: &mut CodeWriter) {
        let take_xxx_return_type = self.take_xxx_return_type(
            &self
                .proto_field
                .message
                .scope
                .file_and_mod(self.customize.clone()),
        );
        w.comment("Take field");
        w.pub_fn(
            &format!(
                "take_{}(&mut self) -> {}",
                self.rust_name,
                take_xxx_return_type.to_code(&self.customize)
            ),
            |w| match self.kind {
                FieldKind::Singular(ref s) => self.write_message_field_take_singular(&s, w),
                FieldKind::Oneof(ref o) => self.write_message_field_take_oneof(o, w),
                FieldKind::Repeated(..) | FieldKind::Map(..) => {
                    w.write_line(&format!(
                        "::std::mem::replace(&mut self.{}, {})",
                        self.rust_name,
                        take_xxx_return_type.default_value(&self.customize, false)
                    ));
                }
            },
        );
    }

    pub(crate) fn write_message_single_field_accessors(&self, w: &mut CodeWriter) {
        if self.generate_accessors || self.generate_getter {
            w.write_line("");
            let reconstruct_def = self.reconstruct_def();
            w.comment(&(reconstruct_def + ";"));
        }

        if self.generate_getter {
            w.write_line("");
            self.write_message_field_get(w);
        }

        if !self.generate_accessors {
            return;
        }

        w.write_line("");
        let clear_field_func = self.clear_field_func();
        w.pub_fn(&format!("{}(&mut self)", clear_field_func), |w| {
            self.write_clear(w);
        });

        if self.has_has() {
            w.write_line("");
            self.write_message_field_has(w);
        }

        w.write_line("");
        self.write_message_field_set(w);

        if self.has_mut() {
            w.write_line("");
            self.write_message_field_mut(w);
        }

        if self.has_take() {
            w.write_line("");
            self.write_message_field_take(w);
        }
    }
}

pub(crate) fn rust_field_name_for_protobuf_field_name(name: &str) -> RustIdent {
    RustIdent::new(name)
}

pub(crate) fn rust_variant_name_for_protobuf_oneof_field_name(name: &str) -> RustIdent {
    let name = camel_case(name);
    RustIdent::new(&name)
}

<MSG> Code cleanup

<DFF> @@ -1673,24 +1673,18 @@ impl<'a> FieldGen<'a> {
         }
     }
 
-    // Write `merge_from` part for this field
-    fn write_merge_from_field(&self, wire_type_var: &str, w: &mut CodeWriter) {
-        match self.kind {
-            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),
-            FieldKind::Map(..) => self.write_merge_from_map(w),
-            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),
-            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),
-        }
-    }
-
+    /// Write `merge_from` part for this field
     pub(crate) fn write_merge_from_field_case_block(
         &self,
         wire_type_var: &str,
         w: &mut CodeWriter,
     ) {
         let number = self.proto_field.number();
-        w.case_block(number.to_string(), |w| {
-            self.write_merge_from_field(wire_type_var, w);
+        w.case_block(number.to_string(), |w| match self.kind {
+            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),
+            FieldKind::Map(..) => self.write_merge_from_map(w),
+            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),
+            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),
         });
     }
 

{'commit': "diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs\nindex beb7739b..6b245225 100644\n--- a/protobuf-codegen/src/gen/field/mod.rs\n+++ b/protobuf-codegen/src/gen/field/mod.rs\n@@ -1673,24 +1673,18 @@ impl<'a> FieldGen<'a> {\n         }\n     }\n \n-    // Write `merge_from` part for this field\n-    fn write_merge_from_field(&self, wire_type_var: &str, w: &mut CodeWriter) {\n-        match self.kind {\n-            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),\n-            FieldKind::Map(..) => self.write_merge_from_map(w),\n-            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),\n-            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),\n-        }\n-    }\n-\n+    /// Write `merge_from` part for this field\n     pub(crate) fn write_merge_from_field_case_block(\n         &self,\n         wire_type_var: &str,\n         w: &mut CodeWriter,\n     ) {\n         let number = self.proto_field.number();\n-        w.case_block(number.to_string(), |w| {\n-            self.write_merge_from_field(wire_type_var, w);\n+        w.case_block(number.to_string(), |w| match self.kind {\n+            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),\n+            FieldKind::Map(..) => self.write_merge_from_map(w),\n+            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),\n+            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),\n         });\n     }\n \ndiff --git a/protobuf/src/rt.rs b/protobuf/src/rt.rs\nindex ca7b73c8..77aa657f 100644\n--- a/protobuf/src/rt.rs\n+++ b/protobuf/src/rt.rs\n@@ -24,6 +24,7 @@ use crate::reflect::types::*;\n use crate::reflect::ProtobufValue;\n use crate::unknown::UnknownFields;\n use crate::varint::encoded_varint64_len;\n+use crate::wire_format::Tag;\n pub use crate::wire_format::WireType;\n use crate::zigzag::*;\n use crate::EnumOrUnknown;\n@@ -890,7 +891,7 @@ pub fn read_unknown_or_skip_group(\n     wire_type: WireType,\n     is: &mut CodedInputStream,\n     unknown_fields: &mut UnknownFields,\n-) -> Result<()> {\n+) -> crate::Result<()> {\n     match wire_type {\n         WireType::StartGroup => skip_group(is),\n         _ => {\n@@ -901,6 +902,18 @@ pub fn read_unknown_or_skip_group(\n     }\n }\n \n+/// Handle unknown field in generated code.\n+/// Either store a value in unknown, or skip a group.\n+/// Return error if tag is incorrect.\n+pub fn read_unknown_or_skip_group_new(\n+    tag: u32,\n+    is: &mut CodedInputStream,\n+    unknown_fields: &mut UnknownFields,\n+) -> crate::Result<()> {\n+    let (field_humber, wire_type) = Tag::new(tag)?.unpack();\n+    read_unknown_or_skip_group(field_humber, wire_type, is, unknown_fields)\n+}\n+\n /// Create an error for unexpected wire type.\n ///\n /// Function is used in generated code, so error types can be changed,\n", 'commit_subject': 'Code cleanup', 'repo_name': 'stepancheg/rust-protobuf', 'committer': {'name': 'Stiopa Koltsov', 'email': 'e150b500682c3c55bd53434656d52cd8d6051776@gmail.com', 'time_sec': '1645339598', 'tz_offset': '0', 'date': {'seconds': '1645339598'}}, 'commit_tree': 'f472ef1ace2db40219884607dbdaa325c7100c72', 'commit_message': 'Code cleanup\n', 'language_name': 'C++', 'license': 'mit', 'hunks': "@@ -1673,24 +1673,18 @@ impl<'a> FieldGen<'a> {\n         }\n     }\n \n-    // Write `merge_from` part for this field\n-    fn write_merge_from_field(&self, wire_type_var: &str, w: &mut CodeWriter) {\n-        match self.kind {\n-            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),\n-            FieldKind::Map(..) => self.write_merge_from_map(w),\n-            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),\n-            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),\n-        }\n-    }\n-\n+    /// Write `merge_from` part for this field\n     pub(crate) fn write_merge_from_field_case_block(\n         &self,\n         wire_type_var: &str,\n         w: &mut CodeWriter,\n     ) {\n         let number = self.proto_field.number();\n-        w.case_block(number.to_string(), |w| {\n-            self.write_merge_from_field(wire_type_var, w);\n+        w.case_block(number.to_string(), |w| match self.kind {\n+            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),\n+            FieldKind::Map(..) => self.write_merge_from_map(w),\n+            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),\n+            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),\n         });\n     }\n \n", 'addition_count': 6, 'deletion_count': 12, 'src_file': 'a/protobuf-codegen/src/gen/field/mod.rs', 'tgt_file': 'b/protobuf-codegen/src/gen/field/mod.rs', 'file_extension': '.rs', 'before_file': 'mod accessor;\npub(crate) mod elem;\nmod option_kind;\nmod repeated;\nmod singular;\nmod tag;\npub(crate) mod type_ext;\n\nuse protobuf::descriptor::field_descriptor_proto::Type;\nuse protobuf::descriptor::*;\nuse protobuf::reflect::ReflectValueRef;\nuse protobuf::reflect::RuntimeFieldType;\nuse protobuf::reflect::Syntax;\nuse protobuf::rt;\nuse protobuf::rt::WireType;\nuse protobuf_parse::camel_case;\nuse protobuf_parse::ProtobufAbsPath;\n\nuse crate::customize::ctx::CustomizeElemCtx;\nuse crate::customize::rustproto_proto::customize_from_rustproto_for_field;\nuse crate::customize::Customize;\nuse crate::gen::code_writer::CodeWriter;\nuse crate::gen::code_writer::Visibility;\nuse crate::gen::field::elem::field_elem;\nuse crate::gen::field::elem::FieldElem;\nuse crate::gen::field::elem::FieldElemEnum;\nuse crate::gen::field::elem::HowToGetMessageSize;\nuse crate::gen::field::option_kind::OptionKind;\nuse crate::gen::field::repeated::RepeatedField;\nuse crate::gen::field::singular::SingularField;\nuse crate::gen::field::singular::SingularFieldFlag;\nuse crate::gen::field::tag::make_tag;\nuse crate::gen::field::type_ext::TypeExt;\nuse crate::gen::file_and_mod::FileAndMod;\nuse crate::gen::inside::protobuf_crate_path;\nuse crate::gen::map::map_entry;\nuse crate::gen::oneof::OneofField;\nuse crate::gen::protoc_insertion_point::write_protoc_insertion_point_for_field;\nuse crate::gen::rust::ident::RustIdent;\nuse crate::gen::rust::quote::quote_escape_bytes;\nuse crate::gen::rust::quote::quote_escape_str;\nuse crate::gen::rust::snippets::EXPR_NONE;\nuse crate::gen::rust_types_values::PrimitiveTypeVariant;\nuse crate::gen::rust_types_values::RustType;\nuse crate::gen::rust_types_values::RustValueTyped;\nuse crate::gen::scope::FieldWithContext;\nuse crate::gen::scope::MessageWithScope;\nuse crate::gen::scope::RootScope;\n\nfn field_type_protobuf_name<\'a>(field: &\'a FieldDescriptorProto) -> &\'a str {\n    if field.has_type_name() {\n        field.type_name()\n    } else {\n        field.type_().protobuf_name()\n    }\n}\n\n#[derive(Clone)]\npub struct MapField<\'a> {\n    _message: MessageWithScope<\'a>,\n    key: FieldElem<\'a>,\n    value: FieldElem<\'a>,\n}\n\n#[derive(Clone)]\npub(crate) enum FieldKind<\'a> {\n    // optional or required\n    Singular(SingularField<\'a>),\n    // repeated except map\n    Repeated(RepeatedField<\'a>),\n    // map\n    Map(MapField<\'a>),\n    // part of oneof\n    Oneof(OneofField<\'a>),\n}\n\nimpl<\'a> FieldKind<\'a> {\n    pub(crate) fn default(\n        &self,\n        customize: &Customize,\n        reference: &FileAndMod,\n        const_expr: bool,\n    ) -> String {\n        match self {\n            FieldKind::Singular(s) => s.default_value(customize, reference, const_expr),\n            FieldKind::Repeated(r) => r.default(),\n            FieldKind::Oneof(..) => EXPR_NONE.to_owned(),\n            FieldKind::Map(..) => panic!("map fields cannot have field value"),\n        }\n    }\n}\n\n#[derive(Clone)]\npub(crate) enum SingularOrOneofField<\'a> {\n    Singular(SingularField<\'a>),\n    Oneof(OneofField<\'a>),\n}\n\nimpl<\'a> SingularOrOneofField<\'a> {\n    fn elem(&self) -> &FieldElem {\n        match self {\n            SingularOrOneofField::Singular(SingularField { ref elem, .. }) => elem,\n            SingularOrOneofField::Oneof(OneofField { ref elem, .. }) => elem,\n        }\n    }\n\n    // Type of `xxx` function for singular type.\n    pub(crate) fn getter_return_type(&self, reference: &FileAndMod) -> RustType {\n        let elem = self.elem();\n        if let FieldElem::Enum(ref en) = elem {\n            en.enum_rust_type(reference)\n        } else if elem.is_copy() {\n            elem.rust_storage_elem_type(reference)\n        } else {\n            elem.rust_storage_elem_type(reference).ref_type()\n        }\n    }\n}\n\n// Representation of map entry: key type and value type\n#[derive(Clone, Debug)]\npub struct EntryKeyValue<\'a>(FieldElem<\'a>, FieldElem<\'a>);\n\n#[derive(Clone)]\npub(crate) struct FieldGen<\'a> {\n    syntax: Syntax,\n    pub proto_field: FieldWithContext<\'a>,\n    // field name in generated code\n    pub rust_name: RustIdent,\n    pub proto_type: Type,\n    wire_type: WireType,\n    pub kind: FieldKind<\'a>,\n    pub generate_accessors: bool,\n    pub generate_getter: bool,\n    customize: Customize,\n    path: Vec<i32>,\n    info: Option<&\'a SourceCodeInfo>,\n}\n\nimpl<\'a> FieldGen<\'a> {\n    pub(crate) fn parse(\n        field: FieldWithContext<\'a>,\n        root_scope: &\'a RootScope<\'a>,\n        parent_customize: &CustomizeElemCtx<\'a>,\n        path: Vec<i32>,\n        info: Option<&\'a SourceCodeInfo>,\n    ) -> anyhow::Result<FieldGen<\'a>> {\n        let customize = parent_customize\n            .child(\n                &customize_from_rustproto_for_field(field.field.proto().options.get_or_default()),\n                &field.field,\n            )\n            .for_elem;\n\n        let syntax = field.message.scope.file_scope.syntax();\n\n        let field_may_have_custom_default_value = syntax == Syntax::Proto2\n            && field.field.proto().label() != field_descriptor_proto::Label::LABEL_REPEATED\n            && field.field.proto().type_() != Type::TYPE_MESSAGE;\n\n        let generate_accessors = customize\n            .generate_accessors\n            .unwrap_or(field_may_have_custom_default_value)\n            || field.is_oneof();\n\n        let default_generate_getter = generate_accessors || field_may_have_custom_default_value;\n        let generate_getter =\n            customize.generate_getter.unwrap_or(default_generate_getter) || field.is_oneof();\n\n        let kind = match field.field.runtime_field_type() {\n            RuntimeFieldType::Map(..) => {\n                let message = root_scope\n                    .find_message(&ProtobufAbsPath::from(field.field.proto().type_name()));\n\n                let (key, value) = map_entry(&message).unwrap();\n\n                let key = field_elem(&key, root_scope, &customize);\n                let value = field_elem(&value, root_scope, &customize);\n\n                FieldKind::Map(MapField {\n                    _message: message,\n                    key,\n                    value,\n                })\n            }\n            RuntimeFieldType::Repeated(..) => {\n                let elem = field_elem(&field, root_scope, &customize);\n\n                FieldKind::Repeated(RepeatedField {\n                    elem,\n                    packed: field.field.proto().options.get_or_default().packed(),\n                })\n            }\n            RuntimeFieldType::Singular(..) => {\n                let elem = field_elem(&field, root_scope, &customize);\n\n                if let Some(oneof) = field.oneof() {\n                    FieldKind::Oneof(OneofField::parse(&oneof, &field.field, elem, root_scope))\n                } else {\n                    let flag = if field.message.scope.file_scope.syntax() == Syntax::Proto3\n                        && field.field.proto().type_() != field_descriptor_proto::Type::TYPE_MESSAGE\n                        && !field.field.proto().proto3_optional()\n                    {\n                        SingularFieldFlag::WithoutFlag\n                    } else {\n                        let required = field.field.proto().label()\n                            == field_descriptor_proto::Label::LABEL_REQUIRED;\n                        let option_kind = match field.field.proto().type_() {\n                            field_descriptor_proto::Type::TYPE_MESSAGE => OptionKind::MessageField,\n                            _ => OptionKind::Option,\n                        };\n\n                        SingularFieldFlag::WithFlag {\n                            required,\n                            option_kind,\n                        }\n                    };\n                    FieldKind::Singular(SingularField { elem, flag })\n                }\n            }\n        };\n\n        Ok(FieldGen {\n            syntax: field.message.message.file_descriptor().syntax(),\n            rust_name: rust_field_name_for_protobuf_field_name(&field.field.name()),\n            proto_type: field.field.proto().type_(),\n            wire_type: WireType::for_type(field.field.proto().type_()),\n            proto_field: field,\n            kind,\n            generate_accessors,\n            generate_getter,\n            customize,\n            path,\n            info,\n        })\n    }\n\n    // for message level\n    fn file_and_mod(&self) -> FileAndMod {\n        self.proto_field\n            .message\n            .scope\n            .file_and_mod(self.customize.clone())\n    }\n\n    fn tag_size(&self) -> u32 {\n        rt::tag_size(self.proto_field.number() as u32) as u32\n    }\n\n    fn is_singular(&self) -> bool {\n        match self.kind {\n            FieldKind::Singular(..) => true,\n            _ => false,\n        }\n    }\n\n    fn is_repeated_packed(&self) -> bool {\n        match self.kind {\n            FieldKind::Repeated(RepeatedField { packed: true, .. }) => true,\n            _ => false,\n        }\n    }\n\n    pub(crate) fn elem(&self) -> &FieldElem {\n        match self.kind {\n            FieldKind::Singular(SingularField { ref elem, .. }) => &elem,\n            FieldKind::Repeated(RepeatedField { ref elem, .. }) => &elem,\n            FieldKind::Oneof(OneofField { ref elem, .. }) => &elem,\n            FieldKind::Map(..) => unreachable!(),\n        }\n    }\n\n    // type of field in struct\n    pub(crate) fn full_storage_type(&self, reference: &FileAndMod) -> RustType {\n        match self.kind {\n            FieldKind::Repeated(ref repeated) => repeated.rust_type(reference),\n            FieldKind::Map(MapField {\n                ref key, ref value, ..\n            }) => RustType::HashMap(\n                Box::new(key.rust_storage_elem_type(reference)),\n                Box::new(value.rust_storage_elem_type(reference)),\n            ),\n            FieldKind::Singular(ref singular) => singular.rust_storage_type(reference),\n            FieldKind::Oneof(..) => unreachable!(),\n        }\n    }\n\n    // type of `v` in `for v in field`\n    fn full_storage_iter_elem_type(&self, reference: &FileAndMod) -> RustType {\n        if let FieldKind::Oneof(ref oneof) = self.kind {\n            oneof.elem.rust_storage_elem_type(reference)\n        } else {\n            self.full_storage_type(reference).iter_elem_type()\n        }\n    }\n\n    // suffix `xxx` as in `os.write_xxx_no_tag(..)`\n    fn os_write_fn_suffix(&self) -> &str {\n        self.proto_type.protobuf_name()\n    }\n\n    fn os_write_fn_suffix_with_unknown_for_enum(&self) -> &str {\n        if self.proto_type == field_descriptor_proto::Type::TYPE_ENUM {\n            "enum_or_unknown"\n        } else {\n            self.os_write_fn_suffix()\n        }\n    }\n\n    // for field `foo`, type of param of `fn set_foo(..)`\n    fn set_xxx_param_type(&self, reference: &FileAndMod) -> RustType {\n        match self.kind {\n            FieldKind::Singular(SingularField { ref elem, .. })\n            | FieldKind::Oneof(OneofField { ref elem, .. }) => {\n                elem.rust_set_xxx_param_type(reference)\n            }\n            FieldKind::Repeated(..) | FieldKind::Map(..) => self.full_storage_type(reference),\n        }\n    }\n\n    // for field `foo`, return type if `fn take_foo(..)`\n    fn take_xxx_return_type(&self, reference: &FileAndMod) -> RustType {\n        self.set_xxx_param_type(reference)\n    }\n\n    // for field `foo`, return type of `fn mut_foo(..)`\n    fn mut_xxx_return_type(&self, reference: &FileAndMod) -> RustType {\n        RustType::Ref(Box::new(match self.kind {\n            FieldKind::Singular(SingularField { ref elem, .. })\n            | FieldKind::Oneof(OneofField { ref elem, .. }) => {\n                elem.rust_storage_elem_type(reference)\n            }\n            FieldKind::Repeated(..) | FieldKind::Map(..) => self.full_storage_type(reference),\n        }))\n    }\n\n    // for field `foo`, return type of `fn foo(..)`\n    fn getter_return_type(&self) -> RustType {\n        let reference = self\n            .proto_field\n            .message\n            .scope\n            .file_and_mod(self.customize.clone());\n        match &self.kind {\n            FieldKind::Singular(s) => {\n                SingularOrOneofField::Singular(s.clone()).getter_return_type(&reference)\n            }\n            FieldKind::Oneof(o) => {\n                SingularOrOneofField::Oneof(o.clone()).getter_return_type(&reference)\n            }\n            FieldKind::Repeated(RepeatedField { ref elem, .. }) => RustType::Ref(Box::new(\n                RustType::Slice(Box::new(elem.rust_storage_elem_type(&reference))),\n            )),\n            FieldKind::Map(..) => RustType::Ref(Box::new(self.full_storage_type(&reference))),\n        }\n    }\n\n    // elem data is not stored in heap\n    pub(crate) fn elem_type_is_copy(&self) -> bool {\n        self.proto_type.is_copy()\n    }\n\n    fn defaut_value_from_proto_float(f: f64, type_name: &str) -> String {\n        if f.is_nan() {\n            format!("::std::{}::NAN", type_name)\n        } else if f.is_infinite() {\n            if f > 0.0 {\n                format!("::std::{}::INFINITY", type_name)\n            } else {\n                format!("::std::{}::NEG_INFINITY", type_name)\n            }\n        } else {\n            format!("{:?}{}", f, type_name)\n        }\n    }\n\n    fn singular_or_oneof_default_value_from_proto(&self, elem: &FieldElem) -> Option<String> {\n        if !self.proto_field.field.proto().has_default_value() {\n            return None;\n        }\n\n        let default_value = self.proto_field.field.singular_default_value();\n        Some(match default_value {\n            ReflectValueRef::Bool(b) => format!("{}", b),\n            ReflectValueRef::I32(v) => format!("{}i32", v),\n            ReflectValueRef::I64(v) => format!("{}i64", v),\n            ReflectValueRef::U32(v) => format!("{}u32", v),\n            ReflectValueRef::U64(v) => format!("{}u64", v),\n            ReflectValueRef::String(v) => quote_escape_str(v),\n            ReflectValueRef::Bytes(v) => quote_escape_bytes(v),\n            ReflectValueRef::F32(v) => Self::defaut_value_from_proto_float(v as f64, "f32"),\n            ReflectValueRef::F64(v) => Self::defaut_value_from_proto_float(v as f64, "f64"),\n            ReflectValueRef::Enum(_e, _v) => {\n                if let &FieldElem::Enum(ref e) = elem {\n                    format!("{}", e.default_value_rust_expr(&self.file_and_mod()))\n                } else {\n                    unreachable!()\n                }\n            }\n            t => panic!("default value is not implemented for type: {:?}", t),\n        })\n    }\n\n    fn default_value_from_proto(&self) -> Option<String> {\n        match self.kind {\n            FieldKind::Oneof(OneofField { ref elem, .. })\n            | FieldKind::Singular(SingularField { ref elem, .. }) => {\n                self.singular_or_oneof_default_value_from_proto(elem)\n            }\n            _ => unreachable!(),\n        }\n    }\n\n    fn default_value_from_proto_typed(&self) -> Option<RustValueTyped> {\n        self.default_value_from_proto().map(|v| {\n            let default_value_type = match self.proto_type {\n                field_descriptor_proto::Type::TYPE_STRING => RustType::Ref(Box::new(RustType::Str)),\n                field_descriptor_proto::Type::TYPE_BYTES => {\n                    RustType::Ref(Box::new(RustType::Slice(Box::new(RustType::u8()))))\n                }\n                _ => self.full_storage_iter_elem_type(\n                    &self\n                        .proto_field\n                        .message\n                        .scope\n                        .file_and_mod(self.customize.clone()),\n                ),\n            };\n\n            RustValueTyped {\n                value: v,\n                rust_type: default_value_type,\n            }\n        })\n    }\n\n    // default value to be returned from `fn xxx` for field `xxx`.\n    fn xxx_default_value_rust(&self) -> String {\n        match self.kind {\n            FieldKind::Singular(..) | FieldKind::Oneof(..) => {\n                self.default_value_from_proto().unwrap_or_else(|| {\n                    self.getter_return_type()\n                        .default_value(&self.customize, false)\n                })\n            }\n            _ => unreachable!(),\n        }\n    }\n\n    // default to be assigned to field\n    fn element_default_value_rust(&self) -> RustValueTyped {\n        match self.kind {\n            FieldKind::Singular(..) | FieldKind::Oneof(..) => {\n                self.default_value_from_proto_typed().unwrap_or_else(|| {\n                    self.elem()\n                        .rust_storage_elem_type(\n                            &self\n                                .proto_field\n                                .message\n                                .scope\n                                .file_and_mod(self.customize.clone()),\n                        )\n                        .default_value_typed(&self.customize, false)\n                })\n            }\n            _ => unreachable!(),\n        }\n    }\n\n    pub(crate) fn reconstruct_def(&self) -> String {\n        let prefix = match (self.proto_field.field.proto().label(), self.syntax) {\n            (field_descriptor_proto::Label::LABEL_REPEATED, _) => "repeated ",\n            (_, Syntax::Proto3) => "",\n            (field_descriptor_proto::Label::LABEL_OPTIONAL, _) => "optional ",\n            (field_descriptor_proto::Label::LABEL_REQUIRED, _) => "required ",\n        };\n        format!(\n            "{}{} {} = {}",\n            prefix,\n            field_type_protobuf_name(self.proto_field.field.proto()),\n            self.proto_field.name(),\n            self.proto_field.number()\n        )\n    }\n\n    pub(crate) fn write_clear(&self, w: &mut CodeWriter) {\n        match self.kind {\n            FieldKind::Oneof(ref o) => {\n                w.write_line(&format!(\n                    "self.{} = ::std::option::Option::None;",\n                    o.oneof_field_name\n                ));\n            }\n            _ => {\n                let clear_expr = self\n                    .full_storage_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    )\n                    .clear(&self.self_field(), &self.customize);\n                w.write_line(&format!("{};", clear_expr));\n            }\n        }\n    }\n\n    // output code that writes single element to stream\n    pub(crate) fn write_write_element(\n        &self,\n        elem: &FieldElem,\n        w: &mut CodeWriter,\n        os: &str,\n        v: &RustValueTyped,\n    ) {\n        assert!(!self.is_repeated_packed());\n\n        elem.write_write_element(\n            self.proto_field.number() as u32,\n            v,\n            &self.file_and_mod(),\n            &self.customize,\n            os,\n            w,\n        );\n    }\n\n    fn self_field(&self) -> String {\n        format!("self.{}", self.rust_name)\n    }\n\n    fn self_field_is_some(&self) -> String {\n        assert!(self.is_singular());\n        format!("{}.is_some()", self.self_field())\n    }\n\n    fn self_field_is_none(&self) -> String {\n        assert!(self.is_singular());\n        format!("{}.is_none()", self.self_field())\n    }\n\n    // field data viewed as Option\n    fn self_field_as_option(&self, elem: &FieldElem, option_kind: OptionKind) -> RustValueTyped {\n        match self.full_storage_type(\n            &self\n                .proto_field\n                .message\n                .scope\n                .file_and_mod(self.customize.clone()),\n        ) {\n            RustType::Option(ref e) if e.is_copy() => {\n                return RustType::Option(e.clone()).value(self.self_field());\n            }\n            _ => {}\n        };\n\n        let as_option_type = option_kind.as_ref_type(\n            elem.rust_storage_elem_type(\n                &self\n                    .proto_field\n                    .message\n                    .scope\n                    .file_and_mod(self.customize.clone()),\n            ),\n        );\n\n        as_option_type.value(format!("{}.as_ref()", self.self_field()))\n    }\n\n    pub(crate) fn write_struct_field(&self, w: &mut CodeWriter) {\n        if self.proto_type == field_descriptor_proto::Type::TYPE_GROUP {\n            w.comment(&format!("{}: <group>", &self.rust_name));\n        } else {\n            w.all_documentation(self.info, &self.path);\n\n            write_protoc_insertion_point_for_field(w, &self.customize, &self.proto_field.field);\n            w.field_decl_vis(\n                Visibility::Public,\n                &self.rust_name.to_string(),\n                &self\n                    .full_storage_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    )\n                    .to_code(&self.customize),\n            );\n        }\n    }\n\n    fn write_if_let_self_field_is_some<F>(&self, s: &SingularField, w: &mut CodeWriter, cb: F)\n    where\n        F: Fn(&RustValueTyped, &mut CodeWriter),\n    {\n        match s {\n            SingularField {\n                flag: SingularFieldFlag::WithFlag { option_kind, .. },\n                ref elem,\n            } => {\n                let var = "v";\n                let ref_prefix = match elem\n                    .rust_storage_elem_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    )\n                    .is_copy()\n                {\n                    true => "",\n                    false => "",\n                };\n                let as_option = self.self_field_as_option(elem, *option_kind);\n                w.if_let_stmt(\n                    &format!("Some({}{})", ref_prefix, var),\n                    &as_option.value,\n                    |w| {\n                        let v = RustValueTyped {\n                            value: var.to_owned(),\n                            rust_type: as_option.rust_type.elem_type(),\n                        };\n                        cb(&v, w);\n                    },\n                );\n            }\n            SingularField {\n                flag: SingularFieldFlag::WithoutFlag,\n                ref elem,\n            } => match *elem {\n                FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)\n                | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => {\n                    w.if_stmt(format!("!{}.is_empty()", self.self_field()), |w| {\n                        let v = RustValueTyped {\n                            value: self.self_field(),\n                            rust_type: self.full_storage_type(\n                                &self\n                                    .proto_field\n                                    .message\n                                    .scope\n                                    .file_and_mod(self.customize.clone()),\n                            ),\n                        };\n                        cb(&v, w);\n                    });\n                }\n                _ => {\n                    w.if_stmt(\n                        format!(\n                            "{} != {}",\n                            self.self_field(),\n                            self.full_storage_type(\n                                &self\n                                    .proto_field\n                                    .message\n                                    .scope\n                                    .file_and_mod(self.customize.clone())\n                            )\n                            .default_value(&self.customize, false)\n                        ),\n                        |w| {\n                            let v = RustValueTyped {\n                                value: self.self_field(),\n                                rust_type: self.full_storage_type(\n                                    &self\n                                        .proto_field\n                                        .message\n                                        .scope\n                                        .file_and_mod(self.customize.clone()),\n                                ),\n                            };\n                            cb(&v, w);\n                        },\n                    );\n                }\n            },\n        }\n    }\n\n    pub(crate) fn write_if_self_field_is_none<F>(&self, w: &mut CodeWriter, cb: F)\n    where\n        F: Fn(&mut CodeWriter),\n    {\n        let self_field_is_none = self.self_field_is_none();\n        w.if_stmt(self_field_is_none, cb)\n    }\n\n    // repeated or singular\n    pub(crate) fn write_for_self_field<F>(&self, w: &mut CodeWriter, varn: &str, cb: F)\n    where\n        F: Fn(&mut CodeWriter, &RustType),\n    {\n        let file_and_mod = self\n            .proto_field\n            .message\n            .scope\n            .file_and_mod(self.customize.clone());\n\n        match &self.kind {\n            FieldKind::Oneof(oneof_field) => {\n                let cond = format!(\n                    "Some({}(ref {}))",\n                    oneof_field.variant_path(&file_and_mod.relative_mod),\n                    varn\n                );\n                w.if_let_stmt(\n                    &cond,\n                    &format!("self.{}", oneof_field.oneof_field_name),\n                    |w| cb(w, &oneof_field.elem.rust_storage_elem_type(&file_and_mod)),\n                )\n            }\n            _ => {\n                let v_type = self.full_storage_iter_elem_type(&file_and_mod);\n                let self_field = self.self_field();\n                w.for_stmt(&format!("&{}", self_field), varn, |w| cb(w, &v_type));\n            }\n        }\n    }\n\n    fn write_self_field_assign(&self, w: &mut CodeWriter, value: &str) {\n        let self_field = self.self_field();\n        w.write_line(&format!("{} = {};", self_field, value));\n    }\n\n    fn write_self_field_assign_some(&self, w: &mut CodeWriter, s: &SingularField, value: &str) {\n        match s {\n            &SingularField {\n                flag: SingularFieldFlag::WithFlag { option_kind, .. },\n                ..\n            } => {\n                self.write_self_field_assign(w, &option_kind.wrap_value(value, &self.customize));\n            }\n            &SingularField {\n                flag: SingularFieldFlag::WithoutFlag,\n                ..\n            } => {\n                self.write_self_field_assign(w, value);\n            }\n        }\n    }\n\n    fn write_self_field_assign_value_singular(\n        &self,\n        w: &mut CodeWriter,\n        s: &SingularField,\n        value: &RustValueTyped,\n    ) {\n        let SingularField { ref elem, ref flag } = s;\n        let converted = value.into_type(\n            elem.rust_storage_elem_type(\n                &self\n                    .proto_field\n                    .message\n                    .scope\n                    .file_and_mod(self.customize.clone()),\n            )\n            .clone(),\n            &self.customize,\n        );\n        let wrapped = match flag {\n            SingularFieldFlag::WithoutFlag => converted.value,\n            SingularFieldFlag::WithFlag { option_kind, .. } => {\n                option_kind.wrap_value(&converted.value, &self.customize)\n            }\n        };\n        self.write_self_field_assign(w, &wrapped);\n    }\n\n    fn write_self_field_assign_value(&self, w: &mut CodeWriter, value: &RustValueTyped) {\n        match self.kind {\n            FieldKind::Repeated(..) | FieldKind::Map(..) => {\n                let converted = value.into_type(\n                    self.full_storage_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    ),\n                    &self.customize,\n                );\n                self.write_self_field_assign(w, &converted.value);\n            }\n            FieldKind::Singular(ref s) => {\n                self.write_self_field_assign_value_singular(w, s, value);\n            }\n            FieldKind::Oneof(..) => unreachable!(),\n        }\n    }\n\n    fn write_self_field_assign_default(\n        &self,\n        field_kind: &SingularOrOneofField,\n        w: &mut CodeWriter,\n    ) {\n        match field_kind {\n            SingularOrOneofField::Oneof(oneof) => {\n                w.write_line(format!(\n                    "self.{} = ::std::option::Option::Some({}({}))",\n                    oneof.oneof_field_name,\n                    oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file()),\n                    // TODO: default from .proto is not needed here (?)\n                    self.element_default_value_rust()\n                        .into_type(\n                            self.full_storage_iter_elem_type(\n                                &self\n                                    .proto_field\n                                    .message\n                                    .scope\n                                    .file_and_mod(self.customize.clone())\n                            ),\n                            &self.customize\n                        )\n                        .value\n                ));\n            }\n            SingularOrOneofField::Singular(singular) => {\n                // Note it is different from C++ protobuf, where field is initialized\n                // with default value\n                match singular.flag {\n                    SingularFieldFlag::WithFlag { option_kind, .. } => match option_kind {\n                        OptionKind::MessageField => {\n                            let self_field = self.self_field();\n                            w.write_line(&format!("{}.set_default();", self_field));\n                        }\n                        _ => {\n                            self.write_self_field_assign_some(\n                                w,\n                                singular,\n                                &self\n                                    .elem()\n                                    .rust_storage_elem_type(\n                                        &self\n                                            .proto_field\n                                            .message\n                                            .scope\n                                            .file_and_mod(self.customize.clone()),\n                                    )\n                                    .default_value_typed(&self.customize, false)\n                                    .into_type(\n                                        singular.elem.rust_storage_elem_type(\n                                            &self\n                                                .proto_field\n                                                .message\n                                                .scope\n                                                .file_and_mod(self.customize.clone()),\n                                        ),\n                                        &self.customize,\n                                    )\n                                    .value,\n                            );\n                        }\n                    },\n                    SingularFieldFlag::WithoutFlag => unimplemented!(),\n                }\n            }\n        }\n    }\n\n    fn self_field_vec_packed_size(&self) -> String {\n        let fn_name = match self.proto_type {\n            Type::TYPE_ENUM => "vec_packed_enum_or_unknown_size",\n            Type::TYPE_SINT32 => "vec_packed_sint32_size",\n            Type::TYPE_SINT64 => "vec_packed_sint64_size",\n            Type::TYPE_INT32 => "vec_packed_int32_size",\n            Type::TYPE_INT64 => "vec_packed_int64_size",\n            Type::TYPE_UINT32 => "vec_packed_uint32_size",\n            Type::TYPE_UINT64 => "vec_packed_uint64_size",\n            Type::TYPE_BOOL => "vec_packed_bool_size",\n            Type::TYPE_FIXED32 => "vec_packed_fixed32_size",\n            Type::TYPE_FIXED64 => "vec_packed_fixed64_size",\n            Type::TYPE_SFIXED32 => "vec_packed_sfixed32_size",\n            Type::TYPE_SFIXED64 => "vec_packed_sfixed64_size",\n            Type::TYPE_FLOAT => "vec_packed_float_size",\n            Type::TYPE_DOUBLE => "vec_packed_double_size",\n            t => unreachable!("{:?}", t),\n        };\n        format!(\n            "{}::rt::{fn_name}({}, &{})",\n            protobuf_crate_path(&self.customize),\n            self.proto_field.number(),\n            self.self_field()\n        )\n    }\n\n    pub(crate) fn clear_field_func(&self) -> String {\n        format!("clear_{}", self.rust_name)\n    }\n\n    fn write_merge_from_field_message_string_bytes_repeated(\n        &self,\n        r: &RepeatedField,\n        w: &mut CodeWriter,\n    ) {\n        let read_fn = match &r.elem {\n            FieldElem::Message(..) => "read_message",\n            FieldElem::Primitive(Type::TYPE_STRING, PrimitiveTypeVariant::Default) => "read_string",\n            FieldElem::Primitive(Type::TYPE_STRING, PrimitiveTypeVariant::TokioBytes) => {\n                "read_tokio_chars"\n            }\n            FieldElem::Primitive(Type::TYPE_BYTES, PrimitiveTypeVariant::Default) => "read_bytes",\n            FieldElem::Primitive(Type::TYPE_BYTES, PrimitiveTypeVariant::TokioBytes) => {\n                "read_tokio_bytes"\n            }\n            _ => unreachable!("for field {}", self.proto_field.field),\n        };\n        w.write_line(&format!("self.{}.push(is.{}()?);", self.rust_name, read_fn,));\n    }\n\n    fn tag_with_wire_type(&self, wire_type: WireType) -> u32 {\n        make_tag(self.proto_field.number() as u32, wire_type)\n    }\n\n    fn tag(&self) -> u32 {\n        self.tag_with_wire_type(self.wire_type)\n    }\n\n    // Write `merge_from` part for this oneof field\n    fn write_merge_from_oneof_case_block(&self, o: &OneofField, w: &mut CodeWriter) {\n        w.case_block(&format!("{}", self.tag()), |w| {\n            let typed = RustValueTyped {\n                value: format!(\n                    "{}?",\n                    self.proto_type.read("is", o.elem.primitive_type_variant())\n                ),\n                rust_type: self.full_storage_iter_elem_type(\n                    &self\n                        .proto_field\n                        .message\n                        .scope\n                        .file_and_mod(self.customize.clone()),\n                ),\n            };\n\n            let maybe_boxed = if o.boxed {\n                typed.boxed(&self.customize)\n            } else {\n                typed\n            };\n\n            w.write_line(&format!(\n                "self.{} = ::std::option::Option::Some({}({}));",\n                o.oneof_field_name,\n                o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),\n                maybe_boxed.value\n            ));\n        })\n    }\n\n    // Write `merge_from` part for this map field\n    fn write_merge_from_map_case_block(&self, map: &MapField, w: &mut CodeWriter) {\n        let MapField { key, value, .. } = map;\n        w.case_block(&format!("{}", self.tag()), |w| {\n            w.write_line(&format!("let len = is.read_raw_varint32()?;",));\n            w.write_line(&format!("let old_limit = is.push_limit(len as u64)?;"));\n            w.write_line(&format!(\n                "let mut key = ::std::default::Default::default();"\n            ));\n            w.write_line(&format!(\n                "let mut value = ::std::default::Default::default();"\n            ));\n            w.while_block("let Some(tag) = is.read_raw_tag_or_eof()?", |w| {\n                w.match_block("tag", |w| {\n                    let key_tag = make_tag(1, WireType::for_type(key.proto_type()));\n                    let value_tag = make_tag(2, WireType::for_type(value.proto_type()));\n                    w.case_expr(\n                        &format!("{key_tag}"),\n                        &format!("key = {read}", read = key.read_one_liner()),\n                    );\n                    w.case_expr(\n                        &format!("{value_tag}"),\n                        &format!("value = {read}", read = value.read_one_liner()),\n                    );\n                    w.case_expr(\n                        "_",\n                        &format!(\n                            "{protobuf_crate}::rt::skip_field_for_tag(tag, is)?",\n                            protobuf_crate = protobuf_crate_path(&self.customize)\n                        ),\n                    );\n                });\n            });\n            w.write_line(&format!("is.pop_limit(old_limit);"));\n            w.write_line(&format!(\n                "{field}.insert(key, value);",\n                field = self.self_field()\n            ));\n        });\n    }\n\n    // Write `merge_from` part for this singular field\n    fn write_merge_from_singular_case_block(&self, s: &SingularField, w: &mut CodeWriter) {\n        w.case_block(&format!("{}", self.tag()), |w| match s.elem {\n            FieldElem::Message(..) => {\n                w.write_line(&format!(\n                    "{}::rt::read_singular_message_into_field(is, &mut self.{})?;",\n                    protobuf_crate_path(&self.customize),\n                    self.rust_name,\n                ));\n            }\n            _ => {\n                let read_proc = s.elem.read_one_liner();\n                self.write_self_field_assign_some(w, s, &read_proc);\n            }\n        })\n    }\n\n    // Write `merge_from` part for this repeated field\n    fn write_merge_from_repeated_case_block(&self, w: &mut CodeWriter) {\n        let field = match self.kind {\n            FieldKind::Repeated(ref field) => field,\n            _ => panic!(),\n        };\n\n        match field.elem {\n            FieldElem::Message(..)\n            | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_STRING, ..)\n            | FieldElem::Primitive(field_descriptor_proto::Type::TYPE_BYTES, ..) => {\n                w.case_block(&format!("{}", self.tag()), |w| {\n                    self.write_merge_from_field_message_string_bytes_repeated(field, w);\n                })\n            }\n            FieldElem::Enum(..) => {\n                w.case_block(\n                    &format!("{}", self.tag_with_wire_type(WireType::Varint)),\n                    |w| {\n                        w.write_line(&format!(\n                            "self.{}.push(is.read_enum_or_unknown()?);",\n                            self.rust_name,\n                        ));\n                    },\n                );\n                w.case_block(\n                    &format!("{}", self.tag_with_wire_type(WireType::LengthDelimited)),\n                    |w| {\n                        w.write_line(&format!(\n                            "{}::rt::read_repeated_packed_enum_or_unknown_into(is, &mut self.{})?",\n                            protobuf_crate_path(&self.customize),\n                            self.rust_name,\n                        ));\n                    },\n                );\n            }\n            _ => {\n                assert_ne!(self.wire_type, WireType::LengthDelimited);\n                w.case_block(\n                    &format!("{}", self.tag_with_wire_type(WireType::LengthDelimited)),\n                    |w| {\n                        w.write_line(&format!(\n                            "is.read_repeated_packed_{}_into(&mut self.{})?;",\n                            self.proto_type.protobuf_name(),\n                            self.rust_name\n                        ));\n                    },\n                );\n                w.case_block(&format!("{}", self.tag()), |w| {\n                    w.write_line(&format!(\n                        "self.{}.push(is.read_{}()?);",\n                        self.rust_name,\n                        self.proto_type.protobuf_name(),\n                    ));\n                });\n            }\n        }\n    }\n\n    /// Write `merge_from` part for this field\n    pub(crate) fn write_merge_from_field_case_block(&self, w: &mut CodeWriter) {\n        match &self.kind {\n            FieldKind::Oneof(oneof) => self.write_merge_from_oneof_case_block(oneof, w),\n            FieldKind::Map(map) => self.write_merge_from_map_case_block(map, w),\n            FieldKind::Singular(ref s) => self.write_merge_from_singular_case_block(s, w),\n            FieldKind::Repeated(..) => self.write_merge_from_repeated_case_block(w),\n        }\n    }\n\n    pub(crate) fn write_element_size(\n        &self,\n        elem: &FieldElem,\n        w: &mut CodeWriter,\n        item_var: &RustValueTyped,\n        sum_var: &str,\n    ) {\n        assert!(!self.is_repeated_packed());\n\n        elem.write_element_size(\n            self.proto_field.number() as u32,\n            item_var,\n            HowToGetMessageSize::Compute,\n            sum_var,\n            &self.customize,\n            w,\n        );\n    }\n\n    fn write_write_map_field(\n        &self,\n        key: &FieldElem,\n        value: &FieldElem,\n        os: &str,\n        w: &mut CodeWriter,\n    ) {\n        self.for_each_map_entry(key, value, w, |k, v, w| {\n            w.write_line("let mut entry_size = 0;");\n            key.write_element_size(\n                1,\n                k,\n                HowToGetMessageSize::GetCached,\n                "entry_size",\n                &self.customize,\n                w,\n            );\n            value.write_element_size(\n                2,\n                v,\n                HowToGetMessageSize::GetCached,\n                "entry_size",\n                &self.customize,\n                w,\n            );\n            w.write_line(&format!(\n                "{os}.write_raw_varint32({tag})?; // Tag.",\n                tag = make_tag(self.proto_field.number() as u32, WireType::LengthDelimited),\n            ));\n            w.write_line(&format!("{os}.write_raw_varint32(entry_size as u32)?;",));\n            key.write_write_element(1, k, &self.file_and_mod(), &self.customize, os, w);\n            value.write_write_element(2, v, &self.file_and_mod(), &self.customize, os, w);\n        });\n    }\n\n    pub(crate) fn write_message_write_field(&self, os: &str, w: &mut CodeWriter) {\n        match &self.kind {\n            FieldKind::Singular(s @ SingularField { elem, .. }) => {\n                self.write_if_let_self_field_is_some(s, w, |v, w| {\n                    self.write_write_element(&elem, w, os, &v);\n                });\n            }\n            FieldKind::Repeated(RepeatedField {\n                packed: false,\n                elem,\n                ..\n            }) => {\n                self.write_for_self_field(w, "v", |w, v_type| {\n                    let v = RustValueTyped {\n                        value: "v".to_owned(),\n                        rust_type: v_type.clone(),\n                    };\n                    self.write_write_element(elem, w, "os", &v);\n                });\n            }\n            FieldKind::Repeated(RepeatedField { packed: true, .. }) => {\n                w.write_line(&format!(\n                    "os.write_repeated_packed_{}({}, &{})?;",\n                    self.os_write_fn_suffix_with_unknown_for_enum(),\n                    self.proto_field.number(),\n                    self.self_field()\n                ));\n            }\n            FieldKind::Map(MapField { key, value, .. }) => {\n                self.write_write_map_field(key, value, os, w)\n            }\n            FieldKind::Oneof(..) => unreachable!(),\n        };\n    }\n\n    fn for_each_map_entry(\n        &self,\n        key: &FieldElem,\n        value: &FieldElem,\n        w: &mut CodeWriter,\n        cb: impl FnOnce(&RustValueTyped, &RustValueTyped, &mut CodeWriter),\n    ) {\n        w.for_stmt(&format!("&{}", self.self_field()), "(k, v)", move |w| {\n            let k = RustValueTyped {\n                value: "k".to_owned(),\n                rust_type: key.rust_storage_elem_type(&self.file_and_mod()).wrap_ref(),\n            };\n            let v = RustValueTyped {\n                value: "v".to_owned(),\n                rust_type: value\n                    .rust_storage_elem_type(&self.file_and_mod())\n                    .wrap_ref(),\n            };\n            cb(&k, &v, w)\n        });\n    }\n\n    fn write_compute_map_field_size(\n        &self,\n        sum_var: &str,\n        key: &FieldElem<\'a>,\n        value: &FieldElem<\'a>,\n        w: &mut CodeWriter,\n    ) {\n        self.for_each_map_entry(key, value, w, |k, v, w| {\n                w.write_line("let mut entry_size = 0;");\n                key.write_element_size(1, k, HowToGetMessageSize::Compute, "entry_size", &self.customize, w);\n                value.write_element_size(2, v, HowToGetMessageSize::Compute, "entry_size", &self.customize, w);\n                w.write_line(&format!("{sum_var} += {tag_size} + {protobuf_crate}::rt::compute_raw_varint64_size(entry_size) + entry_size",\n                    tag_size = self.tag_size(),\n                    protobuf_crate = protobuf_crate_path(&self.customize),\n                ));\n        });\n    }\n\n    pub(crate) fn write_message_compute_field_size(&self, sum_var: &str, w: &mut CodeWriter) {\n        match &self.kind {\n            FieldKind::Singular(s @ SingularField { elem, .. }) => {\n                self.write_if_let_self_field_is_some(s, w, |v, w| {\n                    self.write_element_size(&elem, w, v, sum_var)\n                });\n            }\n            FieldKind::Repeated(RepeatedField {\n                packed: false,\n                elem,\n                ..\n            }) => {\n                match elem.proto_type().encoded_size() {\n                    Some(s) => {\n                        let tag_size = self.tag_size();\n                        let self_field = self.self_field();\n                        w.write_line(&format!(\n                            "{} += {} * {}.len() as u64;",\n                            sum_var,\n                            (s + tag_size) as isize,\n                            self_field\n                        ));\n                    }\n                    None => {\n                        self.write_for_self_field(w, "value", |w, value_type| {\n                            self.write_element_size(\n                                elem,\n                                w,\n                                &RustValueTyped {\n                                    value: "value".to_owned(),\n                                    rust_type: value_type.clone(),\n                                },\n                                sum_var,\n                            );\n                        });\n                    }\n                };\n            }\n            FieldKind::Repeated(RepeatedField { packed: true, .. }) => {\n                let size_expr = self.self_field_vec_packed_size();\n                w.write_line(&format!("{} += {};", sum_var, size_expr));\n            }\n            FieldKind::Map(MapField { key, value, .. }) => {\n                self.write_compute_map_field_size(sum_var, key, value, w)\n            }\n            FieldKind::Oneof(..) => unreachable!(),\n        }\n    }\n\n    fn write_message_field_get_singular_message(&self, s: &SingularField, w: &mut CodeWriter) {\n        match s.flag {\n            SingularFieldFlag::WithoutFlag => unimplemented!(),\n            SingularFieldFlag::WithFlag { option_kind, .. } => {\n                let self_field = self.self_field();\n                let ref field_type_name = self.elem().rust_storage_elem_type(\n                    &self\n                        .proto_field\n                        .message\n                        .scope\n                        .file_and_mod(self.customize.clone()),\n                );\n                w.write_line(option_kind.unwrap_ref_or_else(\n                    &format!("{}.as_ref()", self_field),\n                    &format!(\n                        "<{} as {}::Message>::default_instance()",\n                        field_type_name.to_code(&self.customize),\n                        protobuf_crate_path(&self.customize),\n                    ),\n                ));\n            }\n        }\n    }\n\n    fn write_message_field_get_singular_enum(\n        &self,\n        flag: SingularFieldFlag,\n        _elem: &FieldElemEnum,\n        w: &mut CodeWriter,\n    ) {\n        match flag {\n            SingularFieldFlag::WithoutFlag => {\n                w.write_line(&format!("self.{}.enum_value_or_default()", self.rust_name));\n            }\n            SingularFieldFlag::WithFlag { .. } => {\n                w.match_expr(&self.self_field(), |w| {\n                    let default_value = self.xxx_default_value_rust();\n                    w.case_expr("Some(e)", &format!("e.enum_value_or({})", default_value));\n                    w.case_expr("None", &format!("{}", default_value));\n                });\n            }\n        }\n    }\n\n    fn write_message_field_get_singular(&self, singular: &SingularField, w: &mut CodeWriter) {\n        let get_xxx_return_type = self.getter_return_type();\n\n        match singular.elem {\n            FieldElem::Message(..) => self.write_message_field_get_singular_message(singular, w),\n            FieldElem::Enum(ref en) => {\n                self.write_message_field_get_singular_enum(singular.flag, en, w)\n            }\n            _ => {\n                let get_xxx_default_value_rust = self.xxx_default_value_rust();\n                let self_field = self.self_field();\n                match singular {\n                    &SingularField {\n                        ref elem,\n                        flag: SingularFieldFlag::WithFlag { option_kind, .. },\n                        ..\n                    } => {\n                        if get_xxx_return_type.is_ref().is_some() {\n                            let as_option = self.self_field_as_option(elem, option_kind);\n                            w.match_expr(&as_option.value, |w| {\n                                let v_type = as_option.rust_type.elem_type();\n                                let r_type = self.getter_return_type();\n                                w.case_expr(\n                                    "Some(v)",\n                                    v_type.into_target(&r_type, "v", &self.customize),\n                                );\n                                let get_xxx_default_value_rust = self.xxx_default_value_rust();\n                                w.case_expr("None", get_xxx_default_value_rust);\n                            });\n                        } else {\n                            w.write_line(&format!(\n                                "{}.unwrap_or({})",\n                                self_field, get_xxx_default_value_rust\n                            ));\n                        }\n                    }\n                    &SingularField {\n                        flag: SingularFieldFlag::WithoutFlag,\n                        ..\n                    } => {\n                        w.write_line(\n                            self.full_storage_type(\n                                &self\n                                    .proto_field\n                                    .message\n                                    .scope\n                                    .file_and_mod(self.customize.clone()),\n                            )\n                            .into_target(\n                                &get_xxx_return_type,\n                                &self_field,\n                                &self.customize,\n                            ),\n                        );\n                    }\n                }\n            }\n        }\n    }\n\n    fn write_message_field_get_oneof(&self, o: &OneofField, w: &mut CodeWriter) {\n        let get_xxx_return_type = SingularOrOneofField::Oneof(o.clone()).getter_return_type(\n            &self\n                .proto_field\n                .message\n                .scope\n                .file_and_mod(self.customize.clone()),\n        );\n        let OneofField { ref elem, .. } = o;\n        w.match_expr(&format!("self.{}", o.oneof_field_name), |w| {\n            let (refv, vtype) = if !elem.is_copy() {\n                (\n                    "ref v",\n                    elem.rust_storage_elem_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    )\n                    .ref_type(),\n                )\n            } else {\n                (\n                    "v",\n                    elem.rust_storage_elem_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    ),\n                )\n            };\n            w.case_expr(\n                format!(\n                    "::std::option::Option::Some({}({}))",\n                    o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),\n                    refv\n                ),\n                vtype.into_target(&get_xxx_return_type, "v", &self.customize),\n            );\n            w.case_expr("_", self.xxx_default_value_rust());\n        });\n    }\n\n    fn write_message_field_get(&self, w: &mut CodeWriter) {\n        let get_xxx_return_type = self.getter_return_type();\n        let fn_def = format!(\n            "{}(&self) -> {}",\n            self.rust_name,\n            get_xxx_return_type.to_code(&self.customize)\n        );\n\n        w.pub_fn(&fn_def, |w| match self.kind {\n            FieldKind::Oneof(ref o) => {\n                self.write_message_field_get_oneof(o, w);\n            }\n            FieldKind::Singular(ref s) => {\n                self.write_message_field_get_singular(s, w);\n            }\n            FieldKind::Repeated(..) | FieldKind::Map(..) => {\n                let self_field = self.self_field();\n                w.write_line(&format!("&{}", self_field));\n            }\n        });\n    }\n\n    fn has_has(&self) -> bool {\n        match self.kind {\n            FieldKind::Repeated(..) | FieldKind::Map(..) => false,\n            FieldKind::Singular(SingularField {\n                flag: SingularFieldFlag::WithFlag { .. },\n                ..\n            }) => true,\n            FieldKind::Singular(SingularField {\n                flag: SingularFieldFlag::WithoutFlag,\n                ..\n            }) => false,\n            FieldKind::Oneof(..) => true,\n        }\n    }\n\n    fn has_mut(&self) -> bool {\n        match self.kind {\n            FieldKind::Repeated(..) | FieldKind::Map(..) => true,\n            // TODO: string should be public, and mut is not needed\n            FieldKind::Singular(..) | FieldKind::Oneof(..) => !self.elem_type_is_copy(),\n        }\n    }\n\n    fn has_take(&self) -> bool {\n        match self.kind {\n            FieldKind::Repeated(..) | FieldKind::Map(..) => true,\n            // TODO: string should be public, and mut is not needed\n            FieldKind::Singular(..) | FieldKind::Oneof(..) => !self.elem_type_is_copy(),\n        }\n    }\n\n    fn has_name(&self) -> RustIdent {\n        RustIdent::new(&format!("has_{}", self.rust_name.get()))\n    }\n\n    fn set_name(&self) -> RustIdent {\n        RustIdent::new(&format!("set_{}", self.rust_name.get()))\n    }\n\n    fn mut_name(&self) -> RustIdent {\n        RustIdent::new(&format!("mut_{}", self.rust_name.get()))\n    }\n\n    fn write_message_field_has(&self, w: &mut CodeWriter) {\n        w.pub_fn(\n            &format!("{}(&self) -> bool", self.has_name()),\n            |w| match self.kind {\n                FieldKind::Oneof(ref oneof) => {\n                    w.match_expr(&format!("self.{}", oneof.oneof_field_name), |w| {\n                        w.case_expr(\n                            format!(\n                                "::std::option::Option::Some({}(..))",\n                                oneof.variant_path(\n                                    &self.proto_field.message.scope.rust_path_to_file()\n                                )\n                            ),\n                            "true",\n                        );\n                        w.case_expr("_", "false");\n                    });\n                }\n                _ => {\n                    let self_field_is_some = self.self_field_is_some();\n                    w.write_line(self_field_is_some);\n                }\n            },\n        );\n    }\n\n    fn write_message_field_set(&self, w: &mut CodeWriter) {\n        let set_xxx_param_type = self.set_xxx_param_type(\n            &self\n                .proto_field\n                .message\n                .scope\n                .file_and_mod(self.customize.clone()),\n        );\n        w.comment("Param is passed by value, moved");\n        w.pub_fn(\n            &format!(\n                "{}(&mut self, v: {})",\n                self.set_name(),\n                set_xxx_param_type.to_code(&self.customize)\n            ),\n            |w| {\n                let value_typed = RustValueTyped {\n                    value: "v".to_owned(),\n                    rust_type: set_xxx_param_type.clone(),\n                };\n                match self.kind {\n                    FieldKind::Oneof(ref oneof) => {\n                        let v = set_xxx_param_type.into_target(\n                            &oneof.rust_type(\n                                &self\n                                    .proto_field\n                                    .message\n                                    .scope\n                                    .file_and_mod(self.customize.clone()),\n                            ),\n                            "v",\n                            &self.customize,\n                        );\n                        w.write_line(&format!(\n                            "self.{} = ::std::option::Option::Some({}({}))",\n                            oneof.oneof_field_name,\n                            oneof.variant_path(&self.proto_field.message.scope.rust_path_to_file()),\n                            v\n                        ));\n                    }\n                    _ => {\n                        self.write_self_field_assign_value(w, &value_typed);\n                    }\n                }\n            },\n        );\n    }\n\n    fn write_message_field_mut_singular_with_flag(\n        &self,\n        s: &SingularField,\n        option_kind: OptionKind,\n        w: &mut CodeWriter,\n    ) {\n        let self_field = self.self_field();\n        match option_kind {\n            OptionKind::MessageField => {\n                w.write_line(&format!("{}.mut_or_insert_default()", self_field))\n            }\n            OptionKind::Option => {\n                self.write_if_self_field_is_none(w, |w| {\n                    self.write_self_field_assign_default(\n                        &SingularOrOneofField::Singular(s.clone()),\n                        w,\n                    );\n                });\n                w.write_line(&format!("{}.as_mut().unwrap()", self_field));\n            }\n        }\n    }\n\n    fn write_message_field_mut_singular(&self, s: &SingularField, w: &mut CodeWriter) {\n        match s {\n            s @ SingularField {\n                flag: SingularFieldFlag::WithFlag { option_kind, .. },\n                ..\n            } => self.write_message_field_mut_singular_with_flag(s, *option_kind, w),\n            SingularField {\n                flag: SingularFieldFlag::WithoutFlag,\n                ..\n            } => w.write_line(&format!("&mut {}", self.self_field())),\n        }\n    }\n\n    fn write_message_field_mut(&self, w: &mut CodeWriter) {\n        let mut_xxx_return_type = self.mut_xxx_return_type(\n            &self\n                .proto_field\n                .message\n                .scope\n                .file_and_mod(self.customize.clone()),\n        );\n        w.comment("Mutable pointer to the field.");\n        if self.is_singular() {\n            w.comment("If field is not initialized, it is initialized with default value first.");\n        }\n        let fn_def = match mut_xxx_return_type {\n            RustType::Ref(ref param) => format!(\n                "{}(&mut self) -> &mut {}",\n                self.mut_name(),\n                param.to_code(&self.customize)\n            ),\n            _ => panic!(\n                "not a ref: {}",\n                mut_xxx_return_type.to_code(&self.customize)\n            ),\n        };\n        w.pub_fn(&fn_def, |w| {\n            match self.kind {\n                FieldKind::Repeated(..) | FieldKind::Map(..) => {\n                    let self_field = self.self_field();\n                    w.write_line(&format!("&mut {}", self_field));\n                }\n                FieldKind::Singular(ref s) => {\n                    self.write_message_field_mut_singular(s, w);\n                }\n                FieldKind::Oneof(ref o) => {\n                    let self_field_oneof = format!("self.{}", o.oneof_field_name);\n\n                    // if oneof does not contain current field\n                    w.if_let_else_stmt(\n                        &format!(\n                            "::std::option::Option::Some({}(_))",\n                            o.variant_path(&self.proto_field.message.scope.rust_path_to_file())\n                        )[..],\n                        &self_field_oneof[..],\n                        |w| {\n                            // initialize it with default value\n                            w.write_line(&format!(\n                                "{} = ::std::option::Option::Some({}({}));",\n                                self_field_oneof,\n                                o.variant_path(&self.proto_field.message.scope.rust_path_to_file()),\n                                self.element_default_value_rust()\n                                    .into_type(\n                                        o.rust_type(\n                                            &self\n                                                .proto_field\n                                                .message\n                                                .scope\n                                                .file_and_mod(self.customize.clone())\n                                        ),\n                                        &self.customize\n                                    )\n                                    .value\n                            ));\n                        },\n                    );\n\n                    // extract field\n                    w.match_expr(self_field_oneof, |w| {\n                        w.case_expr(\n                            format!(\n                                "::std::option::Option::Some({}(ref mut v))",\n                                o.variant_path(&self.proto_field.message.scope.rust_path_to_file())\n                            ),\n                            "v",\n                        );\n                        w.case_expr("_", "panic!()");\n                    });\n                }\n            }\n        });\n    }\n\n    fn write_message_field_take_oneof(&self, o: &OneofField, w: &mut CodeWriter) {\n        let take_xxx_return_type = self.take_xxx_return_type(\n            &self\n                .proto_field\n                .message\n                .scope\n                .file_and_mod(self.customize.clone()),\n        );\n\n        // TODO: replace with if let\n        }\n    }\n\n    // Write `merge_from` part for this field\n    fn write_merge_from_field(&self, wire_type_var: &str, w: &mut CodeWriter) {\n        match self.kind {\n            FieldKind::Oneof(ref f) => self.write_merge_from_oneof(&f, wire_type_var, w),\n            FieldKind::Map(..) => self.write_merge_from_map(w),\n            FieldKind::Singular(ref s) => self.write_merge_from_singular(s, wire_type_var, w),\n            FieldKind::Repeated(..) => self.write_merge_from_repeated(wire_type_var, w),\n        }\n    }\n\n    pub(crate) fn write_merge_from_field_case_block(\n        &self,\n        wire_type_var: &str,\n        w: &mut CodeWriter,\n    ) {\n        let number = self.proto_field.number();\n        w.case_block(number.to_string(), |w| {\n            self.write_merge_from_field(wire_type_var, w);\n        });\n    }\n\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    ),\n                    &self.customize,\n                );\n                w.case_expr(\n                    format!(\n                        "::std::option::Option::Some({}(v))",\n                        o.variant_path(&self.proto_field.message.scope.rust_path_to_file())\n                    ),\n                    &converted.value,\n                );\n                w.case_expr("_", "panic!()");\n            });\n        });\n        w.write_line("} else {");\n        w.indented(|w| {\n            w.write_line(\n                self.elem()\n                    .rust_storage_elem_type(\n                        &self\n                            .proto_field\n                            .message\n                            .scope\n                            .file_and_mod(self.customize.clone()),\n                    )\n                    .default_value_typed(&self.customize, false)\n                    .into_type(take_xxx_return_type.clone(), &self.customize)\n                    .value,\n            );\n        });\n        w.write_line("}");\n    }\n\n    fn write_message_field_take_singular(&self, s: &SingularField, w: &mut CodeWriter) {\n        match s {\n            SingularField {\n                ref elem,\n                flag: SingularFieldFlag::WithFlag { option_kind, .. },\n            } => {\n                if !elem.is_copy() {\n                    w.write_line(\n                        &option_kind.unwrap_or_else(\n                            &format!("{}.take()", self.self_field()),\n                            &elem\n                                .rust_storage_elem_type(\n                                    &self\n                                        .proto_field\n                                        .message\n                                        .scope\n                                        .file_and_mod(self.customize.clone()),\n                                )\n                                .default_value(&self.customize, false),\n                        ),\n                    );\n                } else {\n                    w.write_line(&format!(\n                        "{}.take().unwrap_or({})",\n                        self.self_field(),\n                        self.element_default_value_rust().value\n                    ));\n                }\n            }\n            SingularField {\n                flag: SingularFieldFlag::WithoutFlag,\n                ..\n            } => w.write_line(&format!(\n                "::std::mem::replace(&mut {}, {})",\n                self.self_field(),\n                self.full_storage_type(\n                    &self\n                        .proto_field\n                        .message\n                        .scope\n                        .file_and_mod(self.customize.clone())\n                )\n                .default_value(&self.customize, false)\n            )),\n        }\n    }\n\n    fn write_message_field_take(&self, w: &mut CodeWriter) {\n        let take_xxx_return_type = self.take_xxx_return_type(\n            &self\n                .proto_field\n                .message\n                .scope\n                .file_and_mod(self.customize.clone()),\n        );\n        w.comment("Take field");\n        w.pub_fn(\n            &format!(\n                "take_{}(&mut self) -> {}",\n                self.rust_name,\n                take_xxx_return_type.to_code(&self.customize)\n            ),\n            |w| match self.kind {\n                FieldKind::Singular(ref s) => self.write_message_field_take_singular(&s, w),\n                FieldKind::Oneof(ref o) => self.write_message_field_take_oneof(o, w),\n                FieldKind::Repeated(..) | FieldKind::Map(..) => {\n                    w.write_line(&format!(\n                        "::std::mem::replace(&mut self.{}, {})",\n                        self.rust_name,\n                        take_xxx_return_type.default_value(&self.customize, false)\n                    ));\n                }\n            },\n        );\n    }\n\n    pub(crate) fn write_message_single_field_accessors(&self, w: &mut CodeWriter) {\n        if self.generate_accessors || self.generate_getter {\n            w.write_line("");\n            let reconstruct_def = self.reconstruct_def();\n            w.comment(&(reconstruct_def + ";"));\n        }\n\n        if self.generate_getter {\n            w.write_line("");\n            self.write_message_field_get(w);\n        }\n\n        if !self.generate_accessors {\n            return;\n        }\n\n        w.write_line("");\n        let clear_field_func = self.clear_field_func();\n        w.pub_fn(&format!("{}(&mut self)", clear_field_func), |w| {\n            self.write_clear(w);\n        });\n\n        if self.has_has() {\n            w.write_line("");\n            self.write_message_field_has(w);\n        }\n\n        w.write_line("");\n        self.write_message_field_set(w);\n\n        if self.has_mut() {\n            w.write_line("");\n            self.write_message_field_mut(w);\n        }\n\n        if self.has_take() {\n            w.write_line("");\n            self.write_message_field_take(w);\n        }\n    }\n}\n\npub(crate) fn rust_field_name_for_protobuf_field_name(name: &str) -> RustIdent {\n    RustIdent::new(name)\n}\n\npub(crate) fn rust_variant_name_for_protobuf_oneof_field_name(name: &str) -> RustIdent {\n    let name = camel_case(name);\n    RustIdent::new(&name)\n}\n', 'message': 'Code cleanup\n', 'author_name': 'Stiopa Koltsov', 'lang': 'rs'}