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

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

class {{struct.name}}DataView {
 public:
  {{struct.name}}DataView() = default;

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

  bool is_null() const { return !data_; }

{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
{%-   if pf|is_nullable_value_kind_packed_field %}
{%-     if pf|is_primary_nullable_value_kind_packed_field %}
{%-       set original_field = pf.original_field %}
{%-       set has_value_pf = pf %}
{%-       set value_pf = pf.linked_value_packed_field %}
{%-       set kind = original_field.kind %}
{%-       set name = original_field.name %}

{%-       if kind|is_enum_kind %}
  template <typename UserType>
  [[nodiscard]] bool Read{{name|under_to_camel}}(UserType* output) const {
{%-         if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}}) {
      *output = std::nullopt;
      return true;
    }
{%-         endif %}
    if (!data_->{{has_value_pf.field.name}}) {
      *output = std::nullopt;
      return true;
    }

    return mojo::internal::Deserialize<{{value_pf.field.kind|unmapped_type_for_serializer}}>(
        data_->{{value_pf.field.name}}, &output->emplace());
  }

{%-         if not kind|is_typemapped_kind %}
  {{kind|cpp_data_view_type}} {{name}}() const {
{%-           if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}}) {
      return std::nullopt;
    }
{%-           endif %}
    if (!data_->{{has_value_pf.field.name}}) {
      return std::nullopt;
    }
    return ::mojo::internal::ToKnownEnumValueHelper(
          static_cast<{{value_pf.field.kind|unmapped_type_for_serializer}}>(data_->{{value_pf.field.name}}));
  }
{%-         endif %}

{%-       else %}
  {{kind|cpp_data_view_type}} {{name}}() const {
{%-         if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}}) {
      return std::nullopt;
    }
{%-         endif %}

    return data_->{{has_value_pf.field.name}}
        ? std::make_optional({{ "!!" if kind|is_bool_kind }}data_->{{value_pf.field.name}})
        : std::nullopt;
  }

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

{%-   else %}
{%-     set kind = pf.field.kind %}
{%-     set name = pf.field.name %}
{%-     if kind|is_union_kind %}
  inline void Get{{name|under_to_camel}}DataView(
      {{kind|cpp_data_view_type}}* output);

  template <typename UserType>
  [[nodiscard]] bool Read{{name|under_to_camel}}(UserType* output) {
    {{struct_macros.assert_nullable_output_type_if_necessary(kind, name)}}
{%-       if pf.min_version != 0 %}
    auto* pointer = data_->header_.version >= {{pf.min_version}} && !data_->{{name}}.is_null()
                    ? &data_->{{name}} : nullptr;
{%-       else %}
    auto* pointer = !data_->{{name}}.is_null() ? &data_->{{name}} : nullptr;
{%-       endif %}
    return mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
        pointer, output, message_);
  }

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

  template <typename UserType>
  [[nodiscard]] bool Read{{name|under_to_camel}}(UserType* output) {
    {{struct_macros.assert_nullable_output_type_if_necessary(kind, name)}}
{%-       if pf.min_version != 0 %}
    auto* pointer = data_->header_.version >= {{pf.min_version}}
                    ? data_->{{name}}.Get() : nullptr;
{%-       else %}
    auto* pointer = data_->{{name}}.Get();
{%-       endif %}
    return mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
        pointer, output, message_);
  }

{%-     elif kind|is_enum_kind %}
  template <typename UserType>
  [[nodiscard]] bool Read{{name|under_to_camel}}(UserType* output) const {
{%-       if pf.min_version != 0 %}
    auto data_value = data_->header_.version >= {{pf.min_version}}
                      ? data_->{{name}} : 0;
{%-       else %}
    auto data_value = data_->{{name}};
{%-       endif %}
    return mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
        data_value, output);
  }

{%-       if not kind|is_typemapped_kind %}
  {{kind|cpp_data_view_type}} {{name}}() const {
{%-         if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}})
      return {{kind|cpp_data_view_type}}{};
{%-         endif %}
    return ::mojo::internal::ToKnownEnumValueHelper(
          static_cast<{{kind|unmapped_type_for_serializer}}>(data_->{{name}}));
  }
{%-       endif %}

{%-     elif kind|is_any_handle_kind %}
  {{kind|cpp_data_view_type}} Take{{name|under_to_camel}}() {
    {{kind|cpp_data_view_type}} result;
{%-       if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}})
      return result;
{%-       endif %}
    bool ret =
        mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
            &data_->{{name}}, &result, message_);
    DCHECK(ret);
    return result;
  }

{%-     elif kind|is_any_interface_kind %}
  template <typename UserType>
  UserType Take{{name|under_to_camel}}() {
    UserType result;
{%-       if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}})
      return result;
{%-       endif %}
    bool ret =
        mojo::internal::Deserialize<{{kind|unmapped_type_for_serializer}}>(
            &data_->{{name}}, &result, message_);
    DCHECK(ret);
    return result;
  }

{%-     else %}
  {{kind|cpp_data_view_type}} {{name}}() const {
{%-       if pf.min_version != 0 %}
    if (data_->header_.version < {{pf.min_version}})
      return {{kind|cpp_data_view_type}}{};
{%-       endif %}
    return data_->{{name}};
  }

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