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