{%- if f.is_message %}
type {{ f.ident_camel_unesc }}MessageType<'this> where Self: 'this = &'this ScalarType;
{%- endif %} {#- if f.is_message #}

{%- if f.is_repeated %}

type {{ f.ident_camel_unesc }}RepeatedType<'this> where Self: 'this =
    {%- if f.is_message %}
    &'this RepeatedType;
    {%- endif %} {#- if f.is_message #}
    {%- if f.is_string || f.is_bytes %}
    ::puroro::AsRefRepeatedField<
        'this,
        RepeatedType,
        ScalarType,
        {%- if f.is_bytes %}[u8],{%- endif %}
        {%- if f.is_string %}str,{%- endif %}
    >;
    {%- endif %} {#- if f.is_string || f.is_bytes #}
    {%- if f.is_numerical %}
    ::puroro::CloneThenIntoRepeatedField<
        'this,
        RepeatedType,
        ScalarType,
        {{ f.single_numerical_rust_type }}
    >;
    {%- endif %} {#- if f.is_numerical #}

fn {{ f.ident }}<'this>(&'this self) -> Self::{{ f.ident_camel_unesc }}RepeatedType<'this> {
    {%- if f.is_message %}
    &self.{{ f.ident }}
    {%- endif %} {#- if f.is_message #}
    {%- if f.is_string || f.is_bytes %}
    ::puroro::AsRefRepeatedField::new(&self.{{ f.ident }})
    {%- endif %} {#- if f.is_string || f.is_bytes #}
    {%- if f.is_numerical %}
    ::puroro::CloneThenIntoRepeatedField::new(
        &self.{{ f.ident }}
    )
    {%- endif %} {#- if f.is_numerical #}
}

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

fn {{ f.ident_unesc }}_opt<'this>(&'this self) -> ::std::option::Option<{{ f.trait_scalar_getter_type }}> {
    {%- if f.is_message %}
    ::std::option::Option::Some(&self.{{ f.ident }})
    {%- endif %} {#- if f.is_message #}
    {%- if f.is_string || f.is_bytes %}
    ::std::option::Option::Some(self.{{ f.ident }}.as_ref())
    {%- endif %} {#- if f.is_string || f.is_bytes #}
    {%- if f.is_numerical %}
    ::std::option::Option::Some(
        ::std::convert::Into::into(::std::clone::Clone::clone(&self.{{ f.ident }}))
    )
    {%- endif %} {#- if f.is_numerical #}
}

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