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

{%- import "struct_macros.tmpl" as struct_macros %}

class {{union.name}}DataView {
 public:
  using Tag = internal::{{union.name}}_Data::{{union.name}}_Tag;

  {{union.name}}DataView() = default;

  {{union.name}}DataView(
      internal::{{union.name}}_Data* data,
      mojo::Message* message)
{%- if union|requires_context_for_data_view %}
      : data_(data), message_(message) {}
{%- else %}
      : data_(data) {}
{%- endif %}

  bool is_null() const {
    // For inlined unions, |data_| is always non-null. In that case we need to
    // check |data_->is_null()|.
    return !data_ || data_->is_null();
  }

  Tag tag() const { return data_->tag; }

{%- for field in union.fields %}
{%-   set kind = field.kind %}
{%-   set name = field.name %}
  bool is_{{name}}() const { return data_->tag == Tag::k{{name|under_to_camel}}; }

{%-   if kind|is_object_kind %}
  inline void Get{{name|under_to_camel}}DataView(
      {{kind|cpp_data_view_type}}* output) const;

  template <typename UserType>
  [[nodiscard]] bool Read{{name|under_to_camel}}(UserType* output) const {
    {{struct_macros.assert_nullable_output_type_if_necessary(kind, name)}}
    CHECK(is_{{name}}());
    return mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
        data_->data.f_{{name}}.Get(), output, message_);
  }

{%-   elif kind|is_enum_kind %}
  template <typename UserType>
  [[nodiscard]] bool Read{{name|under_to_camel}}(UserType* output) const {
    CHECK(is_{{name}}());
    return mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
        data_->data.f_{{name}}, output);
  }

{%-     if not kind|is_typemapped_kind %}
  {{kind|cpp_data_view_type}} {{name}}() const {
    CHECK(is_{{name}}());
    // TODO(dcheng): This seems incorrect, as it bypasses enum traits.
    return ::mojo::internal::ToKnownEnumValueHelper(
        static_cast<{{kind|unmapped_type_for_serializer}}>(data_->data.f_{{name}}));
  }
{%-     endif %}

{%-   elif kind|is_any_handle_kind %}
  {{kind|cpp_data_view_type}} Take{{name|under_to_camel}}() {
    CHECK(is_{{name}}());
    {{kind|cpp_data_view_type}} result;
    bool ret =
        mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
            &data_->data.f_{{name}}, &result, message_);
    CHECK(ret);
    return result;
  }

{%-   elif kind|is_any_interface_kind %}
  template <typename UserType>
  UserType Take{{name|under_to_camel}}() {
    CHECK(is_{{name}}());
    UserType result;
    bool ret =
        mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
            &data_->data.f_{{name}}, &result, message_);
    CHECK(ret);
    return result;
  }

{%-   else %}
  {{kind|cpp_data_view_type}} {{name}}() const {
    CHECK(is_{{name}}());
    return data_->data.f_{{name}};
  }

{%-   endif %}
{%- endfor %}

 private:
  internal::{{union.name}}_Data* data_ = nullptr;
{%- if union|requires_context_for_data_view %}
  mojo::Message* message_ = nullptr;
{%- endif %}
};