• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1{%- set data_view = union|get_qualified_name_for_kind ~ "DataView" %}
2{%- set data_type = union|get_qualified_name_for_kind(internal=True) %}
3
4namespace internal {
5
6template <typename MaybeConstUserType>
7struct Serializer<{{data_view}}, MaybeConstUserType> {
8  using UserType = typename std::remove_const<MaybeConstUserType>::type;
9  using Traits = UnionTraits<{{data_view}}, UserType>;
10
11  static void Serialize(MaybeConstUserType& input,
12                        Buffer* buffer,
13                        {{data_type}}::BufferWriter* writer,
14                        bool inlined,
15                        SerializationContext* context) {
16    if (CallIsNullIfExists<Traits>(input)) {
17       if (inlined)
18         writer->data()->set_null();
19      return;
20    }
21    void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
22
23    if (!inlined)
24      writer->Allocate(buffer);
25
26    {{data_type}}::BufferWriter& result = *writer;
27    ALLOW_UNUSED_LOCAL(result);
28    // TODO(azani): Handle unknown and objects.
29    // Set the not-null flag.
30    result->size = kUnionDataSize;
31    result->tag = CallWithContext(Traits::GetTag, input, custom_context);
32    switch (result->tag) {
33{%- for field in union.fields %}
34{%-   set name = field.name %}
35{%-   set kind = field.kind %}
36{%-   set serializer_type = kind|unmapped_type_for_serializer %}
37      case {{data_view}}::Tag::{{field.name|upper}}: {
38        decltype(CallWithContext(Traits::{{name}}, input, custom_context))
39            in_{{name}} = CallWithContext(Traits::{{name}}, input,
40                                          custom_context);
41{%-   if kind|is_object_kind %}
42        typename decltype(result->data.f_{{name}})::BaseType::BufferWriter
43            value_writer;
44{%-     if kind|is_union_kind %}
45        mojo::internal::Serialize<{{serializer_type}}>(
46            in_{{name}}, buffer, &value_writer, false, context);
47{%-     elif kind|is_array_kind or kind|is_map_kind %}
48        const ContainerValidateParams {{name}}_validate_params(
49            {{kind|get_container_validate_params_ctor_args|indent(16)}});
50        mojo::internal::Serialize<{{serializer_type}}>(
51            in_{{name}}, buffer, &value_writer, &{{name}}_validate_params,
52            context);
53 {%-     else %}
54        mojo::internal::Serialize<{{serializer_type}}>(
55            in_{{name}}, buffer, &value_writer, context);
56{%-     endif %}
57{%-     if not kind|is_nullable_kind %}
58        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
59            value_writer.is_null(),
60            mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
61            "null {{name}} in {{union.name}} union");
62{%-     endif %}
63        result->data.f_{{name}}.Set(
64            value_writer.is_null() ? nullptr : value_writer.data());
65
66{%-   elif kind|is_any_handle_or_interface_kind %}
67        mojo::internal::Serialize<{{serializer_type}}>(
68            in_{{name}}, &result->data.f_{{name}}, context);
69{%-     if not kind|is_nullable_kind %}
70        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
71            !mojo::internal::IsHandleOrInterfaceValid(result->data.f_{{name}}),
72{%-       if kind|is_associated_kind %}
73            mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
74{%-       else %}
75            mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
76{%-       endif %}
77            "invalid {{name}} in {{union.name}} union");
78{%-     endif %}
79
80{%-   elif kind|is_enum_kind %}
81        mojo::internal::Serialize<{{serializer_type}}>(
82            in_{{name}}, &result->data.f_{{name}});
83
84{%-   else %}
85        result->data.f_{{name}} = in_{{name}};
86{%-   endif %}
87        break;
88      }
89{%- endfor %}
90    }
91
92    CustomContextHelper<Traits>::TearDown(input, custom_context);
93  }
94
95  static bool Deserialize({{data_type}}* input,
96                          UserType* output,
97                          SerializationContext* context) {
98    if (!input || input->is_null())
99      return CallSetToNullIfExists<Traits>(output);
100
101    {{data_view}} data_view(input, context);
102    return Traits::Read(data_view, output);
103  }
104};
105
106}  // namespace internal
107