Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2217)

Unified Diff: mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl

Issue 2226853002: Mojo C++ bindings: add support for UnionTraits. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@85_10_inline_more
Patch Set: . Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698