{%- set data_view = union|get_qualified_name_for_kind ~ "DataView" %} {%- set data_type = union|get_qualified_name_for_kind(internal=True) %} namespace internal { template struct Serializer<{{data_view}}, MaybeConstUserType> { using UserType = typename std::remove_const::type; using Traits = UnionTraits<{{data_view}}, UserType>; static void Serialize(MaybeConstUserType& input, Buffer* buffer, {{data_type}}::BufferWriter* writer, bool inlined, SerializationContext* context) { if (CallIsNullIfExists(input)) { if (inlined) writer->data()->set_null(); return; } void* custom_context = CustomContextHelper::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::TearDown(input, custom_context); } static bool Deserialize({{data_type}}* input, UserType* output, SerializationContext* context) { if (!input || input->is_null()) return CallSetToNullIfExists(output); {{data_view}} data_view(input, context); return Traits::Read(data_view, output); } }; } // namespace internal