blob: 4e39774b607cbad5ed785013f754f97239af8fe6 [file] [log] [blame]
{%- 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,
Buffer* buffer,
{{data_type}}::BufferWriter* writer,
bool inlined,
SerializationContext* context) {
if (CallIsNullIfExists<Traits>(input)) {
if (inlined)
writer->data()->set_null();
return;
}
void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
if (!inlined)
writer->Allocate(buffer);
{{data_type}}::BufferWriter& result = *writer;
ALLOW_UNUSED_LOCAL(result);
// TODO(azani): Handle unknown and objects.
// Set the not-null flag.
result->size = kUnionDataSize;
result->tag = CallWithContext(Traits::GetTag, input, custom_context);
switch (result->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::{{field.name|upper}}: {
decltype(CallWithContext(Traits::{{name}}, input, custom_context))
in_{{name}} = CallWithContext(Traits::{{name}}, input,
custom_context);
{%- if kind|is_object_kind %}
typename decltype(result->data.f_{{name}})::BaseType::BufferWriter
value_writer;
{%- if kind|is_union_kind %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, buffer, &value_writer, false, context);
{%- elif kind|is_array_kind or kind|is_map_kind %}
const ContainerValidateParams {{name}}_validate_params(
{{kind|get_container_validate_params_ctor_args|indent(16)}});
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, buffer, &value_writer, &{{name}}_validate_params,
context);
{%- else %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, buffer, &value_writer, context);
{%- endif %}
{%- if not kind|is_nullable_kind %}
MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
value_writer.is_null(),
mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
"null {{name}} in {{union.name}} union");
{%- endif %}
result->data.f_{{name}}.Set(
value_writer.is_null() ? nullptr : value_writer.data());
{%- elif kind|is_any_handle_or_interface_kind %}
mojo::internal::Serialize<{{serializer_type}}>(
in_{{name}}, &result->data.f_{{name}}, context);
{%- if not kind|is_nullable_kind %}
MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
!mojo::internal::IsHandleOrInterfaceValid(result->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}}, &result->data.f_{{name}});
{%- else %}
result->data.f_{{name}} = in_{{name}};
{%- endif %}
break;
}
{%- endfor %}
}
CustomContextHelper<Traits>::TearDown(input, custom_context);
}
static bool Deserialize({{data_type}}* input,
UserType* output,
SerializationContext* context) {
if (!input || input->is_null())
return CallSetToNullIfExists<Traits>(output);
{{data_view}} data_view(input, context);
return Traits::Read(data_view, output);
}
};
} // namespace internal