{%- set data_view = union|get_qualified_name_for_kind ~ "DataView" %}
{%- set data_type = union|get_qualified_name_for_kind(internal=True) %}
namespace internal {
template <typename MaybeConstUserType>
struct Serializer<{{data_view}}, MaybeConstUserType> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Traits = UnionTraits<{{data_view}}, UserType>;
static void Serialize(MaybeConstUserType& input,
MessageFragment<{{data_type}}>& fragment,
bool inlined) {
if (CallIsNullIfExists<Traits>(input)) {
if (inlined)
fragment->set_null();
return;
}
if (!inlined)
fragment.Allocate();
// TODO(azani): Handle unknown and objects.
// Set the not-null flag.
fragment->size = kUnionDataSize;
fragment->tag = Traits::GetTag(input);
switch (fragment->tag) {
{%- for field in union.fields %}
{%- set name = field.name %}
{%- set kind = field.kind %}
{%- set serializer_type = kind|unmapped_type_for_serializer %}
case {{data_view}}::Tag::k{{field.name|under_to_camel}}: {
decltype(Traits::{{name}}(input))
in_{{name}} = Traits::{{name}}(input);
{%- if kind|is_object_kind %}
mojo::internal::MessageFragment<
typename decltype(fragment->data.f_{{name}})::BaseType>
value_fragment(fragment.message());
{%- if kind|is_union_kind %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, value_fragment, false);
{%- elif kind|is_array_kind or kind|is_map_kind %}
constexpr const mojo::internal::ContainerValidateParams& {{name}}_validate_params =
{{kind|get_container_validate_params_ctor_args|indent(6)}};
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, value_fragment, &{{name}}_validate_params);
{%- else %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, value_fragment);
{%- endif %}
{%- if not kind|is_nullable_kind %}
MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
value_fragment.is_null(),
mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
"null {{name}} in {{union.name}} union");
{%- endif %}
fragment->data.f_{{name}}.Set(
value_fragment.is_null() ? nullptr : value_fragment.data());
{%- elif kind|is_any_handle_or_interface_kind %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, &fragment->data.f_{{name}}, &fragment.message());
{%- if not kind|is_nullable_kind %}
MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
!mojo::internal::IsHandleOrInterfaceValid(fragment->data.f_{{name}}),
{%- if kind|is_associated_kind %}
mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
{%- else %}
mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
{%- endif %}
"invalid {{name}} in {{union.name}} union");
{%- endif %}
{%- elif kind|is_enum_kind %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, &fragment->data.f_{{name}});
{%- else %}
fragment->data.f_{{name}} = in_{{name}};
{%- endif %}
break;
}
{%- endfor %}
}
}
static bool Deserialize({{data_type}}* input,
UserType* output,
Message* message) {
if (!input || input->is_null())
return CallSetToNullIfExists<Traits>(output);
{{data_view}} data_view(input, message);
return Traits::Read(data_view, output);
}
};
} // namespace internal