impl<T> {{ m.trait_ident }} for ::std::option::Option<T>
where
    T: {{ m.trait_ident }},
{
    {%- for f in m.fields %}
    {%- if f.is_message %}
    type {{ f.ident_camel_unesc }}MessageType<'this> where Self: 'this = T::{{ f.ident_camel_unesc }}MessageType<'this>;
    {%- endif %}

    {%- if f.is_repeated %}

    type {{ f.ident_camel_unesc }}RepeatedType<'this> where Self: 'this =
        ::puroro::internal::impls::option::OptionRepeatedField<T::{{ f.ident_camel_unesc }}RepeatedType<'this>>;
    fn {{ f.ident }}<'this>(&'this self) -> Self::{{ f.ident_camel_unesc }}RepeatedType<'this> {
        ::puroro::internal::impls::option::OptionRepeatedField::new(self.as_ref().map(|msg| msg.{{ f.ident }}()))
    }

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

    {%- if !f.is_explicit_oneof_field %}
    fn {{ f.ident_unesc }}_opt<'this>(&'this self) -> ::std::option::Option<{{ f.trait_scalar_getter_type }}> {
        self.as_ref().and_then(|msg| msg.{{ f.ident_unesc }}_opt())
    }
    {%- endif %}

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

    {%- 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_oneofs::{{ oneof.enum_ident }} as E;
        self.as_ref().and_then(|msg| msg.{{ oneof.field_ident }}().map(|oneof| {
            match oneof {
                {%- for f in oneof.fields %}
                E::{{ f.ident }}(v) => E::{{ f.ident }}(v),
                {%- endfor %}
            }
        }))
    }
    {%- endfor %}
}