chromium/mojo/public/tools/bindings/generators/cpp_templates/union_traits_definition.tmpl

{%- set mojom_type = union|get_qualified_name_for_kind %}

// static
bool UnionTraits<{{mojom_type}}::DataView, {{mojom_type}}Ptr>::Read(
    {{mojom_type}}::DataView input,
    {{mojom_type}}Ptr* output) {
  using UnionType = {{mojom_type}};
  using Tag = UnionType::Tag;

  switch (input.tag()) {
{%- for field in union.fields %}
    case Tag::k{{field.name|under_to_camel}}: {
{%-   set name = field.name %}
{%-   set kind = field.kind %}
{%-   set serializer_type = kind|unmapped_type_for_serializer %}
{%-   if kind|is_object_kind %}
      {{kind|cpp_wrapper_type(True)}} result_{{name}};
      if (!input.Read{{name|under_to_camel}}(&result_{{name}}))
        return false;

      *output = UnionType::New{{field.name|under_to_camel}}(
          std::move(result_{{name}}));
{%-   elif kind|is_any_handle_kind %}
      *output = UnionType::New{{field.name|under_to_camel}}(
          input.Take{{name|under_to_camel}}());

{%-   elif kind|is_any_interface_kind %}
      *output = UnionType::New{{field.name|under_to_camel}}(
          input.Take{{name|under_to_camel}}<{{kind|cpp_wrapper_type(True)}}>());

{%-   elif kind|is_enum_kind %}
      {{kind|cpp_wrapper_type(True)}} result_{{name}};
      if (!input.Read{{name|under_to_camel}}(&result_{{name}}))
        return false;

      *output = UnionType::New{{field.name|under_to_camel}}(result_{{name}});
{%-   else %}
      *output = UnionType::New{{field.name|under_to_camel}}(input.{{name}}());
{%-   endif %}
      break;
    }
{%- endfor %}
    default:
{%  if union.extensible %}
      *output = UnionType::New{{union.default_field.name|under_to_camel}}({});
      return true;
{%- else %}
      return false;
{%- endif %}
  }
  return true;
}