{%- 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 %}
};