{%- match f.trait_maybe_field_message_trait_path %}
{%- when Some with (field_msg_path) %}
{%- if f.is_repeated %}
{#- For repeated message field, each message has either `T` or `U` type, never be merged. -#}
type Field{{ f.number }}MessageType<'this> where Self: 'this = ::puroro::Either<
    <T as {{ m.trait_ident }}>::Field{{ f.number }}MessageType<'this>,
    <U as {{ m.trait_ident }}>::Field{{ f.number }}MessageType<'this>,
>;
{%- else %}
{#- For non-repeated message field, the message is `T` and `U` merged type. -#}
{#- There are 3+1 cases: `T` and `U` both exist, only `T`, only `U`, (and none of them). -#}
type Field{{ f.number }}MessageType<'this> where Self: 'this = (
    ::std::option::Option<<T as {{ m.trait_ident }}>::Field{{ f.number }}MessageType<'this>>,
    ::std::option::Option<<U as {{ m.trait_ident }}>::Field{{ f.number }}MessageType<'this>>,
);
{%- endif %}
{%- else %}
{%- endmatch %}

{%- if f.is_bytes %}
type Field{{ f.number }}BytesType<'this> where Self: 'this = ::puroro::Either<
    <T as {{ m.trait_ident }}>::Field{{ f.number }}BytesType<'this>,
    <U as {{ m.trait_ident }}>::Field{{ f.number }}BytesType<'this>,
>;
{%- endif %}
{%- if f.is_string %}
type Field{{ f.number }}StringType<'this> where Self: 'this = ::puroro::Either<
    <T as {{ m.trait_ident }}>::Field{{ f.number }}StringType<'this>,
    <U as {{ m.trait_ident }}>::Field{{ f.number }}StringType<'this>,
>;
{%- endif %}

{%- if f.trait_has_scalar_getter %}
fn {{ f.ident }}<'this>(&'this self) -> {{ f.trait_scalar_getter_type }}
{
    {%- if f.is_length_delimited %}
    let right = <U as {{ m.trait_ident }}>::{{ f.ident }}(&self.1);
    if !right.is_empty() {
        ::puroro::Either::Right(right)
    } else {
        ::puroro::Either::Left(<T as {{ m.trait_ident }}>::{{ f.ident }}(&self.0))
    }
    {%- else %}
    let right = <U as {{ m.trait_ident }}>::{{ f.ident }}(&self.1);
    if right != ::std::default::Default::default() {
        right
    } else {
        <T as {{ m.trait_ident }}>::{{ f.ident }}(&self.0)
    }
    {%- endif %}
}
{%- endif %}

{%- if f.trait_has_optional_getter && !f.is_explicit_oneof_field %}
fn {{ f.ident }}<'this>(&'this self) -> Option<{{ f.trait_scalar_getter_type }}>
{
    {%- if f.is_length_delimited %}
    {%- if f.is_message %}
    match (
        <T as {{ m.trait_ident }}>::{{ f.ident }}(&self.0),
        <U as {{ m.trait_ident }}>::{{ f.ident }}(&self.1)
    ) {
        (None, None) => None,
        (Some(t), None) => Some((Some(t), None)),
        (None, Some(u)) => Some((None, Some(u))),
        (Some(t), Some(u)) => Some((Some(t), Some(u))),
    }
    {%- else %}
    if let Some(right) = <U as {{ m.trait_ident }}>::{{ f.ident }}(&self.1) {
        Some(::puroro::Either::Right(right))
    } else if let Some(left) = <T as {{ m.trait_ident }}>::{{ f.ident }}(&self.0) {
        Some(::puroro::Either::Left(left))
    } else {
        None
    }
    {%- endif %}
    {%- else %}
    <U as {{ m.trait_ident }}>::{{ f.ident }}(&self.1)
        .or_else(|| <T as {{ m.trait_ident }}>::{{ f.ident }}(&self.0))
    {%- endif %}
}
{%- endif %}

{%- if f.trait_has_repeated_getter %}
{%- let merged_repeated_field_type %}
{%- if f.is_length_delimited %}
{%- if f.is_message %}
{%- let merged_repeated_field_type = "MergedRepeatedMessageField" %}
{%- else %}
{%- let merged_repeated_field_type = "MergedRepeatedLDField" %}
{%- endif %}
{%- else %}
{%- let merged_repeated_field_type = "MergedRepeatedField" %}
{%- endif %}
type Field{{ f.number }}RepeatedType<'this> where Self: 'this
    = ::puroro::internal::impls::merged::{{ merged_repeated_field_type }}<
        <T as {{ m.trait_ident }}>::Field{{ f.number }}RepeatedType<'this>,
        <U as {{ m.trait_ident }}>::Field{{ f.number }}RepeatedType<'this>,
    >;

fn {{ f.ident }}<'this>(&'this self) -> Self::Field{{ f.number }}RepeatedType<'this>
{
    ::puroro::internal::impls::merged::{{ merged_repeated_field_type }}::new(
        <T as {{ m.trait_ident }}>::{{ f.ident }}(&self.0),
        <U as {{ m.trait_ident }}>::{{ f.ident }}(&self.1),
    )
}
{%- endif %}