
pub struct {{ m.simple_ident }} {
    _bitfield: ::puroro::bitvec::array::BitArray<
        ::puroro::bitvec::order::Lsb0,
        [u32; ({{ m.bitfield_len }} + 31) / 32],
    >,
    {%- for f in m.fields %}
    {%- if !f.is_explicit_oneof_field %}
    {#- [optional] i32 => Bare<i32> #}
    {#- [optional] String => Bare<String> #}
    {#- [optional] MyMessage => Option<Box<MyMessage>> #}
    {#- repeated i32 => Vec<i32> #}
    {#- repeated String => Vec<String> #}
    {#- repeated MyMessage => Option<MyMessage> #}
    {{ f.ident }}: {{ f.simple_field_type }},
    {%- endif %}
    {%- endfor %}

    {%- for oneof in m.oneofs %}
    {{ oneof.field_ident }}: super::_puroro_nested::{{ m.submodule_ident }}::_puroro_private_oneofs::{{ oneof.simple_enum_ident }},
    {%- endfor %}
}
impl ::puroro::Message<{{ m.simple_ident }}> for {{ m.simple_ident }} {}

impl {{ m.simple_ident }} {
    pub fn new() -> Self {
        Self {
            _bitfield: ::std::default::Default::default(),

            {%- for f in m.fields %}
            {%- if !f.is_explicit_oneof_field %}
            {{ f.ident }}: ::std::default::Default::default(),
            {%- endif %}
            {%- endfor %}

            {%- for oneof in m.oneofs %}
            {{ oneof.field_ident }}: ::std::default::Default::default(),
            {%- endfor %}
        }
    }

    {#- Immutable getter interfaces. #}
    {%- for f in m.fields %}
    {%- if f.is_repeated %}

    {#- repeated i32 => &[i32] #}
    {#- repeated String => &[impl Deref<Target=str>] #}
    {#- repeated MyMessage => &[MyMessage] #}
    pub fn {{ f.ident }}(&self) -> {{ f.simple_getter_type }} {
        &self.{{ f.ident }}
    }

    {%- else %} {#- if f.is_repeated #}

    {%- if !f.is_explicit_oneof_field %}
    {#- [optional] i32 => Option<i32> #}
    {#- [optional] String => Option<&str> #}
    {#- [optional] MyMessage => Option<&MyMessage> #}
    pub fn {{ f.ident_unesc }}_opt(&self) -> {{ f.simple_getter_opt_type }} {
        {%- if f.is_message %}
        {#- Non-repeated message f. Field type is always `Option<Box<T>>`. #}
        self.{{ f.ident }}.as_deref()

        {%- else %} {#- if f.is_message #}

        {%- if f.has_optional_bit %}
        {#- Non-repeated, non-message, optional f. Optional bit is stored in the bitfield. #}
        if self._bitfield.get({{ f.bitfield_index }}).map_or(false, |v| *v) {
            ::std::option::Option::Some(
                {%- if f.is_length_delimited %}
                &self.{{ f.ident }}
                {%- else %} {#- if f.is_length_delimited #}
                self.{{ f.ident }}.clone().inner()
                {%- endif %} {#- if f.is_length_delimited #}
            )
        } else {
            ::std::option::Option::None
        }
        {%- else %} {#- if f.has_optional_bit #}
        {#- Non-repeated, non-message, unlabeled f. Treat as unexisting when it's default value. #}
        if !::puroro::internal::IsDefault::is_default(&*self.{{ f.ident }}) {
            ::std::option::Option::Some(
                {%- if f.is_length_delimited %}
                &self.{{ f.ident }}
                {%- else %} {#- if f.is_length_delimited #}
                self.{{ f.ident }}.inner()
                {%- endif %} {#- if f.is_length_delimited #}
            )
        } else {
            ::std::option::Option::None
        }
        {%- endif %} {#- if f.has_optional_bit #}
        {%- endif %} {#- if f.is_message #}
    }
    {%- endif %} {#- if !f.is_explicit_oneof_field #}

    pub fn has_{{ f.ident_unesc }}(&self) -> bool {
        Self::{{ f.ident_unesc }}_opt(self).is_some()
    }

    pub fn {{ f.ident }}(&self) -> {{ f.simple_getter_type }} {
        {%- if f.is_message %}
        self.{{ f.ident_unesc }}_opt()
        {%- else %} {#- if f.is_message #}
        self.{{ f.ident_unesc }}_opt().unwrap_or(
            {{ f.default_value }}
        )
        {%- endif %} {#- if f.is_message #}
    }

    {%- endif %} {#- if f.is_repeated #}
    {%- endfor %} {#- for f in m.fields #}

    {%- for oneof in m.oneofs %}
    
    pub fn {{ oneof.field_ident }}(&self) ->
        Option<
            super::_puroro_nested::{{ m.submodule_ident }}::_puroro_oneofs::
                {{ oneof.enum_ident }}{{ oneof.enum_maybe_gp_self }}
        >
    {
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_private_oneofs::{{ oneof.simple_enum_ident }} as E;
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_oneofs::{{ oneof.enum_ident }} as F;
        match &self.{{ oneof.field_ident }} {
            E::_None => ::std::option::Option::None,
            {%- for f in oneof.fields %}
            {% if f.is_length_delimited %}
            E::{{ f.ident }}(v) => ::std::option::Option::Some(F::{{ f.ident }}(v.as_ref())),
            {%- else %}
            E::{{ f.ident }}(v) => ::std::option::Option::Some(F::{{ f.ident }}(v.inner().clone())),
            {%- endif %}
            {%- endfor %}
        }
    }

    {%- for f in oneof.fields %}
    pub fn {{ f.getter_ident_unesc }}_opt(&self) -> {{ f.simple_getter_opt_type }} {
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_private_oneofs::{{ oneof.simple_enum_ident }} as E;
        if let E::{{ f.ident }}(ref v) = &self.{{ oneof.field_ident }} {
            ::std::option::Option::Some(
                {%- if f.is_length_delimited %}
                v.as_ref()
                {%- else %} {#- if f.is_length_delimited #}
                v.inner().clone()
                {%- endif %} {#- if f.is_length_delimited #}
            )
        } else {
            ::std::option::Option::None
        }
    }
    {%- endfor %} {#- for f in oneof.fields #}
    {%- endfor %} {#- for oneof in m.oneofs #}

    {#- Tentative mutable interfaces. #}
    {%- for f in m.fields %}
    {%- if !f.is_explicit_oneof_field %}

    {%- if f.is_repeated %}

    {#- repeated int32 => &mut Vec<i32> #}
    {#- repeated String => &mut Vec<String> #}
    {#- repeated MyMessage => &mut Vec<MyMessage> #}
    pub fn {{ f.ident_unesc }}_mut(&mut self) -> {{ f.simple_getter_mut_type }} {
        &mut self.{{ f.ident }}
    }

    {%- else %} {#- if f.is_repeated #}

    {#- clear scalar field #}
    pub fn clear_{{ f.ident_unesc }}(&mut self) {
        {%- if f.has_optional_bit %}
        self._bitfield.set({{ f.bitfield_index }}, false);
        {#- Skip dropping the f. No need to do that unless it's a message field, #}
        {#- and the message field will never have optional bitfield. #}
        {%- else %} {#- if f.has_optional_bit #}
        self.{{ f.ident }} = ::std::default::Default::default();
        {%- endif %} {#- if f.has_optional_bit #}
    }

    {#- always returns an option-unwrapped mut reference. The field is initialized if it's not present. #}
    {#- [optional] i32 => &mut i32 #}
    {#- [optional] String => &mut String #}
    {#- [optional] MyMessage => &mut MyMessage #}
    pub fn {{ f.ident_unesc }}_mut(&mut self) -> {{ f.simple_getter_mut_type }} {
        if !self.has_{{ f.ident_unesc }}() {
            {#- field is not set so we need to initialize / clear it. #}
            self.{{ f.ident }} = ::std::default::Default::default();

            {%- if f.has_optional_bit %}
            self._bitfield.set({{ f.bitfield_index }}, true);
            {%- endif %} {#- if f.has_optional_bit #}
        }

        {%- if f.is_message %}
        {#- Non-repeated message f. Field type is always `Optional<Box<T>>`. #}
        self.{{ f.ident }}.get_or_insert_with(::std::default::Default::default)
        {%- else %} {#- if f.is_message #}
        {#- Otherwise, just return the mut reference of the field. #}
        &mut self.{{ f.ident }}
        {%- endif %} {#- if f.is_message #}
    }

    {%- endif %} {#- if f.is_repeated #}

    {%- endif %} {#- if !f.is_explicit_oneof_field #}
    {%- endfor %} {#- for f in m.fields #}

    {%- for oneof in m.oneofs %}
    pub fn clear_{{ oneof.field_ident }}(&mut self) {
        self.{{ oneof.field_ident }} = ::std::default::Default::default();
    }

    {%- for f in oneof.fields %}
    pub fn {{ f.getter_ident_unesc }}_mut(&mut self) -> {{ f.simple_getter_mut_type }}
    {
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_private_oneofs::{{ oneof.simple_enum_ident }} as E;
        if !matches!(&self.{{ oneof.field_ident }}, E::{{ f.ident }}(_)) {
            self.{{ oneof.field_ident }} = E::{{ f.ident }}(
                ::std::default::Default::default()
            );
        }
        match &mut self.{{ oneof.field_ident }} {
            E::{{ f.ident }}(ref mut v) => v,
            _ => unreachable!(),
        }
    }
    {%- endfor %} {#- for f in oneof.fields #}
    {%- endfor %} {#- for oneof in m.oneofs #}
}

impl super::_puroro_traits::{{ m.trait_ident }} for {{ m.simple_ident }} {
    {%- for f in m.fields %}
    {%- call simple_trait_impl_field(f) %}
    {%- endfor %}

    {%- for oneof in m.oneofs %}
    fn {{ oneof.field_ident }}(&self) ->
        Option<
            super::_puroro_nested::{{ m.submodule_ident }}::_puroro_oneofs::
                {{ oneof.enum_ident }}{{ oneof.enum_maybe_gp_self }}
        >
    {
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_private_oneofs::{{ oneof.simple_enum_ident }} as E;
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_oneofs::{{ oneof.enum_ident }} as F;
        match &self.{{ oneof.field_ident }} {
            E::_None => ::std::option::Option::None,
            {%- for f in oneof.fields %}
            {% if f.is_length_delimited %}
            E::{{ f.ident }}(v) => ::std::option::Option::Some(F::{{ f.ident }}(v.as_ref())),
            {%- else %}
            E::{{ f.ident }}(v) => ::std::option::Option::Some(F::{{ f.ident }}(v.inner().clone())),
            {%- endif %}
            {%- endfor %}
        }
    }
    {%- endfor %}
}

impl ::puroro::MessageRepresentativeImpl for {{ m.simple_ident }} {}

impl ::puroro::internal::de::DeserMessageFromBytesIter for {{ m.simple_ident }} {
    fn deser_field<I>(
        &mut self,
        field_number: i32,
        data: ::puroro::internal::types::FieldData<&mut ::puroro::internal::de::from_iter::ScopedIter<I>>,
    ) -> ::puroro::Result<()>
    where
        I: ::std::iter::Iterator<Item = ::std::io::Result<u8>>
    {
        use ::puroro::internal::impls::simple::de::DeserFieldFromBytesIter;
        match field_number {
            {%- for f in m.fields %}
            {%- if !f.is_explicit_oneof_field %}
            {{ f.number }} => {
                {%- if f.has_optional_bit %}
                self._bitfield.set({{ f.bitfield_index }}, true);
                {%- endif %}
                DeserFieldFromBytesIter::<
                    {{ f.simple_label_and_type_tags }}
                >::deser_field(&mut self.{{ f.ident }}, data)
            }
            {%- endif %}
            {%- endfor %}

            {%- for oneof in m.oneofs %}
            {%- for f in oneof.fields %}
            {{ f.number }} => {
                use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_private_oneofs::{{ oneof.simple_enum_ident }} as E;
                if !matches!(
                    &self.{{ oneof.field_ident }},
                    E::{{ f.ident }}(_))
                {
                    self.{{ oneof.field_ident }} = E::{{ f.ident }}(
                        ::std::default::Default::default()
                    );
                }
                let field_value_mut_ref = match &mut self.{{ oneof.field_ident }} {
                    E::{{ f.ident }}(v) => v,
                    _ => unreachable!(),
                };
                DeserFieldFromBytesIter::<
                    ::puroro::tags::OneofField, {{ f.simple_field_type_tag }}
                >::deser_field(field_value_mut_ref, data)
            }
            {%- endfor %}
            {%- endfor %}

            _ => unimplemented!("TODO: This case should be handled properly..."),
        }
    }
}

impl ::puroro::internal::se::SerMessageToIoWrite for {{ m.simple_ident }}
where
    Self: super::_puroro_traits::{{ m.ident }}Trait,
{
    fn ser<W>(&self, out: &mut W) -> ::puroro::Result<()>
    where
        W: ::std::io::Write,
    {
        {%- for f in m.fields %}
        ::puroro::internal::se::SerFieldToIoWrite::<
            {{ f.trait_label_and_type_tags }}
        >::ser_field(
            {%- if f.is_repeated %}
            <Self as super::_puroro_traits::{{ m.ident }}Trait>::{{ f.ident }}(self),
            {%- else %}
            <Self as super::_puroro_traits::{{ m.ident }}Trait>::{{ f.ident_unesc }}_opt(self),
            {%- endif %}
            {{ f.number }},
            out
        )?;
        {%- endfor %} {#- for f in m.fields #}
        ::std::result::Result::Ok(())
    }
}

impl ::std::default::Default for {{ m.simple_ident }} {
    fn default() -> Self {
        Self::new()
    }
}

impl ::std::fmt::Debug for {{ m.simple_ident }} 
where
    Self: super::_puroro_traits::{{ m.trait_ident }}
{
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        f.debug_struct("{{ m.simple_ident }}")
            {%- for f in m.fields %}
            {%- if !f.is_repeated && (f.has_optional_bit || f.is_explicit_oneof_field) %}
            .field("{{ f.ident }}", &self.{{ f.ident_unesc }}_opt())
            {%- else %} {#- if !f.is_repeated && (f.has_optional_bit || f.is_explicit_oneof_field) #}
            .field("{{ f.ident }}", &self.{{ f.ident }}())
            {%- endif %} {#- if !f.is_repeated && (f.has_optional_bit || f.is_explicit_oneof_field) #}
            {%- endfor %} {#- for f in m.fields #}
            .finish()
    }
}

impl ::std::clone::Clone for {{ m.simple_ident }} {
    fn clone(&self) -> Self {
        Self {
            _bitfield: ::std::clone::Clone::clone(&self._bitfield),
            {%- for f in m.fields %}
            {%- if !f.is_explicit_oneof_field %}
            {{ f.ident }}: ::std::clone::Clone::clone(&self.{{ f.ident }}),
            {%- endif %} {#- if !f.is_explicit_oneof_field #}
            {%- endfor %} {#- for f in m.fields #}
            {%- for oneof in m.oneofs %}
            {{ oneof.field_ident }}: ::std::clone::Clone::clone(&self.{{ oneof.field_ident }}),
            {%- endfor %} {#- for oneof in m.oneofs #}
        }
    }
}

impl ::std::cmp::PartialEq for {{ m.simple_ident }} {
    fn eq(&self, rhs: &Self) -> bool {
        self._bitfield == rhs._bitfield &&
        {%- for f in m.fields %}
        {%- if !f.is_explicit_oneof_field %}
        {%- if f.has_optional_bit %}
        {#- if the optional bit is not set (== the field is not set), #}
        {#- then we can (must) skip the actual field value check. #}
        (self._bitfield.get({{ f.bitfield_index }}).as_deref() != Some(&true) ||
            self.{{ f.ident }} == rhs.{{ f.ident }}) &&
        {%- else %} {#- if f.has_optional_bit #}
        self.{{ f.ident }} == rhs.{{ f.ident }} &&
        {%- endif %} {#- if f.has_optional_bit #}
        {%- endif %} {#- if !f.is_explicit_oneof_field #}
        {%- endfor %} {#- for f in m.fields #}
        {%- for oneof in m.oneofs %}
        self.{{ oneof.field_ident }} == rhs.{{ oneof.field_ident }} &&
        {%- endfor %} {#- for oneof in m.oneofs #}
        true
    }
}
