| Index: mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
|
| diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
|
| index f04e16bd4f7db68856cd11d5487a461d1918e85b..606eda465e4371780d72b306cc2b07bd1c155f91 100644
|
| --- a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
|
| +++ b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
|
| @@ -1,37 +1,169 @@
|
| {%- set mojom_type = union|get_qualified_name_for_kind %}
|
| {%- set data_type = union|get_qualified_name_for_kind(internal=True) %}
|
|
|
| +template <>
|
| +struct {{export_attribute}} UnionTraits<{{mojom_type}}, {{mojom_type}}Ptr> {
|
| + static bool IsNull(const {{mojom_type}}Ptr& input) { return !input; }
|
| + static void SetToNull({{mojom_type}}Ptr* output) { output->reset(); }
|
| +
|
| + static {{mojom_type}}::Tag GetTag(const {{mojom_type}}Ptr& input) {
|
| + return input->which();
|
| + }
|
| +
|
| +{%- for field in union.fields %}
|
| +{%- set return_ref = field.kind|is_object_kind or
|
| + field.kind|is_any_handle_or_interface_kind %}
|
| +{%- if return_ref %}
|
| + static decltype(std::declval<{{mojom_type}}>().get_{{field.name}}())
|
| + {{field.name}}({{mojom_type}}Ptr& input) {
|
| + return input->get_{{field.name}}();
|
| + }
|
| +{%- else %}
|
| + static decltype(std::declval<{{mojom_type}}>().get_{{field.name}}())
|
| + {{field.name}}(const {{mojom_type}}Ptr& input) {
|
| + return input->get_{{field.name}}();
|
| + }
|
| +{%- endif %}
|
| +{%- endfor %}
|
| +
|
| + static bool Read({{mojom_type}}DataView input, {{mojom_type}}Ptr* output);
|
| +};
|
| +
|
| namespace internal {
|
|
|
| -template <typename MojomType>
|
| -struct UnionSerializerImpl;
|
| +template <typename MaybeConstUserType>
|
| +struct Serializer<{{mojom_type}}Ptr, MaybeConstUserType> {
|
| + using UserType = typename std::remove_const<MaybeConstUserType>::type;
|
| + using Traits = UnionTraits<{{mojom_type}}, UserType>;
|
|
|
| -template <>
|
| -struct {{export_attribute}} UnionSerializerImpl<{{mojom_type}}Ptr> {
|
| - static size_t PrepareToSerialize({{mojom_type}}Ptr& input,
|
| + static size_t PrepareToSerialize(MaybeConstUserType& input,
|
| bool inlined,
|
| - SerializationContext* context);
|
| + SerializationContext* context) {
|
| + size_t size = inlined ? 0 : sizeof({{data_type}});
|
| +
|
| + if (CallIsNullIfExists<Traits>(input))
|
| + return size;
|
| +
|
| + void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
|
| + ALLOW_UNUSED_LOCAL(custom_context);
|
| +
|
| + switch (CallWithContext(Traits::GetTag, input, custom_context)) {
|
| +{%- for field in union.fields %}
|
| +{%- set name = field.name %}
|
| + case {{mojom_type}}::Tag::{{name|upper}}: {
|
| +{%- if field.kind|is_object_kind %}
|
| +{%- set kind = field.kind %}
|
| +{%- set serializer_type = kind|unmapped_type_for_serializer %}
|
| + decltype(CallWithContext(Traits::{{name}}, input, custom_context))
|
| + in_{{name}} = CallWithContext(Traits::{{name}}, input,
|
| + custom_context);
|
| +{%- if kind|is_union_kind %}
|
| + size += mojo::internal::PrepareToSerialize<{{serializer_type}}>(
|
| + in_{{name}}, false, context);
|
| +{%- else %}
|
| + size += mojo::internal::PrepareToSerialize<{{serializer_type}}>(
|
| + in_{{name}}, context);
|
| +{%- endif %}
|
| +{%- endif %}
|
| + break;
|
| + }
|
| +{%- endfor %}
|
| + }
|
| + return size;
|
| + }
|
|
|
| static void Serialize({{mojom_type}}Ptr& input,
|
| Buffer* buffer,
|
| {{data_type}}** output,
|
| bool inlined,
|
| - SerializationContext* context);
|
| + SerializationContext* context) {
|
| + if (CallIsNullIfExists<Traits>(input)) {
|
| + if (inlined)
|
| + (*output)->set_null();
|
| + else
|
| + *output = nullptr;
|
| + return;
|
| + }
|
| +
|
| + void* custom_context = CustomContextHelper<Traits>::GetNext(context);
|
| +
|
| + if (!inlined)
|
| + *output = {{data_type}}::New(buffer);
|
| +
|
| + {{data_type}}* result = *output;
|
| + 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 {{mojom_type}}::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* ptr;
|
| +{%- if kind|is_union_kind %}
|
| + mojo::internal::Serialize<{{serializer_type}}>(
|
| + in_{{name}}, buffer, &ptr, 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, &ptr, &{{name}}_validate_params, context);
|
| +{%- else %}
|
| + mojo::internal::Serialize<{{serializer_type}}>(
|
| + in_{{name}}, buffer, &ptr, context);
|
| +{%- endif %}
|
| + result->data.f_{{name}}.Set(ptr);
|
| +{%- if not kind|is_nullable_kind %}
|
| + MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
|
| + !ptr, mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
|
| + "null {{name}} in {{union.name}} union");
|
| +{%- endif %}
|
| +
|
| +{%- 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,
|
| {{mojom_type}}Ptr* output,
|
| - SerializationContext* context);
|
| -};
|
| -
|
| -template <typename MaybeConstUserType>
|
| -struct {{export_attribute}} Serializer<{{mojom_type}}Ptr, MaybeConstUserType>
|
| - : public UnionSerializerImpl<{{mojom_type}}Ptr> {
|
| - using UserType = typename std::remove_const<MaybeConstUserType>::type;
|
| + SerializationContext* context) {
|
| + if (!input || input->is_null())
|
| + return CallSetToNullIfExists<Traits>(output);
|
|
|
| - static_assert(std::is_same<MaybeConstUserType, UserType>::value,
|
| - "Only support serialization of non-const Unions.");
|
| - static_assert(std::is_same<UserType, {{mojom_type}}Ptr>::value,
|
| - "Custom mapping of mojom union is not supported.");
|
| + {{mojom_type}}DataView data_view(input, context);
|
| + return Traits::Read(data_view, output);
|
| + }
|
| };
|
|
|
| } // namespace internal
|
|
|