// WARNING: This file is machine generated by fidlgen.

#pragma once

#include <fidl/test.union/cpp/common_types.h>
#include <fidl/test.union/cpp/markers.h>
#include <lib/fidl/cpp/natural_coding_traits.h>
#include <lib/fidl/cpp/natural_types.h>

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#include <lib/zx/channel.h>

#endif  // __Fuchsia__

namespace test_union {
class StructWithNullableXUnion;

class TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse;

class Pizza;

class Pasta;

class TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse;

class NullableUnionStruct;

class UnionSandwich;

class Empty;

class UnionWithAttributes;

class Union;

class StrictUnion;

class StrictSimpleXUnion;

class StrictFoo;

class StrictBoundedXUnion;

class ReverseOrdinalUnion;

class StrictPizzaOrPasta;

class PizzaOrPasta;

class FlexiblePizzaOrPasta;

class ExplicitPizzaOrPasta;

class OlderSimpleUnion;

class NewerSimpleUnion;

class FlexibleUnion;

class FlexibleFoo;

class FieldCollision;

class ExplicitXUnion;

class ExplicitUnion;

class ExplicitStrictFoo;

class ExplicitFoo;

class XUnionContainingEmptyStruct;

extern "C" const fidl_type_t test_union_UnionWithAttributesTable;

class UnionWithAttributes {
 private:
  using Storage_ = std::variant<std::monostate, int64_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kX = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  UnionWithAttributes() : storage_(std::make_shared<Storage_>()) {}

  UnionWithAttributes(UnionWithAttributes&& other) noexcept
      : UnionWithAttributes(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  UnionWithAttributes& operator=(UnionWithAttributes&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  UnionWithAttributes(const UnionWithAttributes& other) noexcept
      : UnionWithAttributes(other.CloneStorage_()) {}
  UnionWithAttributes& operator=(const UnionWithAttributes& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const UnionWithAttributes& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const UnionWithAttributes& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::UnionWithAttributes::Tag Which() const {
    return UnionWithAttributes::IndexToTag(storage_->index()).value();
  }
  static UnionWithAttributes WithX(int64_t val) {
    return UnionWithAttributes(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> x() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> x() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  UnionWithAttributes(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::UnionWithAttributes>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit UnionWithAttributes(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::UnionWithAttributes::Tag tag) {
    switch (tag) {
      case ::test_union::UnionWithAttributes::Tag::kX:
        return 1;
      case ::test_union::UnionWithAttributes::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::UnionWithAttributes::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::UnionWithAttributes::Tag::kX;
      default:
        return ::test_union::UnionWithAttributes::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_UnionTable;

class Union {
 private:
  using Storage_ = std::variant<std::monostate, int32_t, ::std::string,
                                ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  Union(Union&& other) noexcept
      : Union(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  Union& operator=(Union&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  Union(const Union& other) noexcept : Union(other.CloneStorage_()) {}
  Union& operator=(const Union& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const Union& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const Union& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::Union::Tag Which() const {
    return Union::IndexToTag(storage_->index()).value();
  }
  static Union WithPrimitive(int32_t val) {
    return Union(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static Union WithStringNeedsConstructor(::std::string val) {
    return Union(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_>
  string_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  static Union WithVectorStringAlsoNeedsConstructor(
      ::std::vector<::std::string> val) {
    return Union(
        std::make_shared<Storage_>(std::in_place_index_t<3>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<3, Storage_>
  vector_string_also_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<3, Storage_>
  vector_string_also_needs_constructor() {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  Union(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::Union>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<
          ::fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintString<>>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintVector<
              fidl::internal::NaturalCodingConstraintString<>>>());

  explicit Union(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::Union::Tag tag) {
    switch (tag) {
      case ::test_union::Union::Tag::kPrimitive:
        return 1;
      case ::test_union::Union::Tag::kStringNeedsConstructor:
        return 2;
      case ::test_union::Union::Tag::kVectorStringAlsoNeedsConstructor:
        return 3;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::Union::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::Union::Tag::kPrimitive;
      case 2:
        return ::test_union::Union::Tag::kStringNeedsConstructor;
      case 3:
        return ::test_union::Union::Tag::kVectorStringAlsoNeedsConstructor;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_StructWithNullableXUnionTable;

class StructWithNullableXUnion {
 private:
  struct Storage_;

 public:
  StructWithNullableXUnion(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  StructWithNullableXUnion(
      ::std::unique_ptr<::test_union::OlderSimpleUnion> x1) noexcept
      : storage_({.x1 = std::move(x1)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |StructWithNullableXUnion| only if all of its members
  // are default constructible.
  StructWithNullableXUnion() = default;
#pragma clang diagnostic pop

  StructWithNullableXUnion(StructWithNullableXUnion&&) noexcept = default;
  StructWithNullableXUnion& operator=(StructWithNullableXUnion&&) noexcept =
      default;
  StructWithNullableXUnion(const StructWithNullableXUnion& other) noexcept
      : StructWithNullableXUnion(other.CloneStorage_()) {}
  StructWithNullableXUnion& operator=(
      const StructWithNullableXUnion& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(const StructWithNullableXUnion& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<
        ::test_union::StructWithNullableXUnion, 16>::Equal(this, &other);
  }
  bool operator!=(const StructWithNullableXUnion& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<
        ::test_union::StructWithNullableXUnion, 16>::Equal(this, &other);
  }

  const ::std::unique_ptr<::test_union::OlderSimpleUnion>& x1() const {
    return storage_.x1;
  }

  ::std::unique_ptr<::test_union::OlderSimpleUnion>& x1() {
    return storage_.x1;
  }

  StructWithNullableXUnion(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : StructWithNullableXUnion(Storage_{
            .x1 = {},
        }) {}

 private:
  struct Storage_ final {
    ::std::unique_ptr<::test_union::OlderSimpleUnion> x1;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_union::StructWithNullableXUnion, 16>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_union::StructWithNullableXUnion>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, ::std::unique_ptr<::test_union::OlderSimpleUnion>,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::x1, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_StrictUnionTable;

class StrictUnion {
 private:
  using Storage_ = std::variant<std::monostate, int32_t, ::std::string,
                                ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  StrictUnion(StrictUnion&& other) noexcept
      : StrictUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictUnion& operator=(StrictUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  StrictUnion(const StrictUnion& other) noexcept
      : StrictUnion(other.CloneStorage_()) {}
  StrictUnion& operator=(const StrictUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const StrictUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const StrictUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::StrictUnion::Tag Which() const {
    return StrictUnion::IndexToTag(storage_->index()).value();
  }
  static StrictUnion WithPrimitive(int32_t val) {
    return StrictUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static StrictUnion WithStringNeedsConstructor(::std::string val) {
    return StrictUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_>
  string_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  static StrictUnion WithVectorStringAlsoNeedsConstructor(
      ::std::vector<::std::string> val) {
    return StrictUnion(
        std::make_shared<Storage_>(std::in_place_index_t<3>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<3, Storage_>
  vector_string_also_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<3, Storage_>
  vector_string_also_needs_constructor() {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  StrictUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::StrictUnion>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<
          ::fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintString<>>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintVector<
              fidl::internal::NaturalCodingConstraintString<>>>());

  explicit StrictUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::StrictUnion::Tag tag) {
    switch (tag) {
      case ::test_union::StrictUnion::Tag::kPrimitive:
        return 1;
      case ::test_union::StrictUnion::Tag::kStringNeedsConstructor:
        return 2;
      case ::test_union::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
        return 3;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictUnion::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::StrictUnion::Tag::kPrimitive;
      case 2:
        return ::test_union::StrictUnion::Tag::kStringNeedsConstructor;
      case 3:
        return ::test_union::StrictUnion::Tag::
            kVectorStringAlsoNeedsConstructor;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_StrictSimpleXUnionTable;

class StrictSimpleXUnion {
 private:
  using Storage_ = std::variant<std::monostate, int32_t, float, ::std::string>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kS = 3,  // 0x3
  };

  StrictSimpleXUnion(StrictSimpleXUnion&& other) noexcept
      : StrictSimpleXUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictSimpleXUnion& operator=(StrictSimpleXUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  StrictSimpleXUnion(const StrictSimpleXUnion& other) noexcept
      : StrictSimpleXUnion(other.CloneStorage_()) {}
  StrictSimpleXUnion& operator=(const StrictSimpleXUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const StrictSimpleXUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const StrictSimpleXUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::StrictSimpleXUnion::Tag Which() const {
    return StrictSimpleXUnion::IndexToTag(storage_->index()).value();
  }
  static StrictSimpleXUnion WithI(int32_t val) {
    return StrictSimpleXUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> i() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static StrictSimpleXUnion WithF(float val) {
    return StrictSimpleXUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> f() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> f() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  static StrictSimpleXUnion WithS(::std::string val) {
    return StrictSimpleXUnion(
        std::make_shared<Storage_>(std::in_place_index_t<3>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<3, Storage_> s() const {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<3, Storage_> s() {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  StrictSimpleXUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::StrictSimpleXUnion>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintString<>>());

  explicit StrictSimpleXUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::StrictSimpleXUnion::Tag tag) {
    switch (tag) {
      case ::test_union::StrictSimpleXUnion::Tag::kI:
        return 1;
      case ::test_union::StrictSimpleXUnion::Tag::kF:
        return 2;
      case ::test_union::StrictSimpleXUnion::Tag::kS:
        return 3;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictSimpleXUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::StrictSimpleXUnion::Tag::kI;
      case 2:
        return ::test_union::StrictSimpleXUnion::Tag::kF;
      case 3:
        return ::test_union::StrictSimpleXUnion::Tag::kS;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_StrictFooTable;

class StrictFoo {
 private:
  using Storage_ = std::variant<std::monostate, ::std::string, int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
  };

  StrictFoo(StrictFoo&& other) noexcept
      : StrictFoo(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictFoo& operator=(StrictFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  StrictFoo(const StrictFoo& other) noexcept
      : StrictFoo(other.CloneStorage_()) {}
  StrictFoo& operator=(const StrictFoo& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const StrictFoo& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const StrictFoo& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::StrictFoo::Tag Which() const {
    return StrictFoo::IndexToTag(storage_->index()).value();
  }
  static StrictFoo WithS(::std::string val) {
    return StrictFoo(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> s() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> s() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static StrictFoo WithI(int32_t val) {
    return StrictFoo(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> i() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  StrictFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::StrictFoo>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintString<>>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit StrictFoo(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::StrictFoo::Tag tag) {
    switch (tag) {
      case ::test_union::StrictFoo::Tag::kS:
        return 1;
      case ::test_union::StrictFoo::Tag::kI:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictFoo::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::StrictFoo::Tag::kS;
      case 2:
        return ::test_union::StrictFoo::Tag::kI;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_StrictBoundedXUnionTable;

class StrictBoundedXUnion {
 private:
  using Storage_ = std::variant<std::monostate, ::std::vector<uint8_t>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kV = 1,  // 0x1
  };

  StrictBoundedXUnion(StrictBoundedXUnion&& other) noexcept
      : StrictBoundedXUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictBoundedXUnion& operator=(StrictBoundedXUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  StrictBoundedXUnion(const StrictBoundedXUnion& other) noexcept
      : StrictBoundedXUnion(other.CloneStorage_()) {}
  StrictBoundedXUnion& operator=(const StrictBoundedXUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const StrictBoundedXUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const StrictBoundedXUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::StrictBoundedXUnion::Tag Which() const {
    return StrictBoundedXUnion::IndexToTag(storage_->index()).value();
  }
  static StrictBoundedXUnion WithV(::std::vector<uint8_t> val) {
    return StrictBoundedXUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> v() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> v() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  StrictBoundedXUnion(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::StrictBoundedXUnion>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<
          ::fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintVector<
              fidl::internal::NaturalCodingConstraintEmpty, 10>>());

  explicit StrictBoundedXUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::StrictBoundedXUnion::Tag tag) {
    switch (tag) {
      case ::test_union::StrictBoundedXUnion::Tag::kV:
        return 1;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictBoundedXUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::StrictBoundedXUnion::Tag::kV;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t
    test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;

class TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse {
 private:
  struct Storage_;

 public:
  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
      Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
      ::test_union::StrictBoundedXUnion xu) noexcept
      : storage_({.xu = std::move(xu)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a
  // |TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse| only
  // if all of its members are default constructible.
  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse() =
      default;
#pragma clang diagnostic pop

  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
      TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&&) noexcept =
      default;
  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&
  operator=(
      TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&&) noexcept =
      default;
  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
      const TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&
          other) noexcept
      : TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
            other.CloneStorage_()) {}
  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&
  operator=(
      const TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&
          other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(
      const TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&
          other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<
        ::test_union::
            TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse,
        16>::Equal(this, &other);
  }
  bool operator!=(
      const TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse&
          other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<
        ::test_union::
            TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse,
        16>::Equal(this, &other);
  }

  const ::test_union::StrictBoundedXUnion& xu() const { return storage_.xu; }

  ::test_union::StrictBoundedXUnion& xu() { return storage_.xu; }

  TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse(
            Storage_{
                .xu = ::fidl::internal::
                    DefaultConstructPossiblyInvalidObjectTag{},
            }) {}

 private:
  struct Storage_ final {
    ::test_union::StrictBoundedXUnion xu;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_union::
          TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse,
      16>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_union::
          TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, ::test_union::StrictBoundedXUnion,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::xu, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_ReverseOrdinalUnionTable;

class ReverseOrdinalUnion {
 private:
  using Storage_ = std::variant<std::monostate, uint32_t, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kSecond = 2,  // 0x2
    kFirst = 1,   // 0x1
  };

  ReverseOrdinalUnion(ReverseOrdinalUnion&& other) noexcept
      : ReverseOrdinalUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ReverseOrdinalUnion& operator=(ReverseOrdinalUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  ReverseOrdinalUnion(const ReverseOrdinalUnion& other) noexcept
      : ReverseOrdinalUnion(other.CloneStorage_()) {}
  ReverseOrdinalUnion& operator=(const ReverseOrdinalUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const ReverseOrdinalUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const ReverseOrdinalUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::ReverseOrdinalUnion::Tag Which() const {
    return ReverseOrdinalUnion::IndexToTag(storage_->index()).value();
  }
  static ReverseOrdinalUnion WithSecond(uint32_t val) {
    return ReverseOrdinalUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> second() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> second() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static ReverseOrdinalUnion WithFirst(uint32_t val) {
    return ReverseOrdinalUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> first() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> first() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ReverseOrdinalUnion(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::ReverseOrdinalUnion>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ReverseOrdinalUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::ReverseOrdinalUnion::Tag tag) {
    switch (tag) {
      case ::test_union::ReverseOrdinalUnion::Tag::kSecond:
        return 1;
      case ::test_union::ReverseOrdinalUnion::Tag::kFirst:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ReverseOrdinalUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::ReverseOrdinalUnion::Tag::kSecond;
      case 2:
        return ::test_union::ReverseOrdinalUnion::Tag::kFirst;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_PizzaTable;

class Pizza {
 private:
  struct Storage_;

 public:
  Pizza(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  Pizza(::std::vector<::std::string> toppings) noexcept
      : storage_({.toppings = std::move(toppings)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |Pizza| only if all of its members are default
  // constructible.
  Pizza() = default;
#pragma clang diagnostic pop

  Pizza(Pizza&&) noexcept = default;
  Pizza& operator=(Pizza&&) noexcept = default;
  Pizza(const Pizza& other) noexcept : Pizza(other.CloneStorage_()) {}
  Pizza& operator=(const Pizza& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(const Pizza& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza,
                                                       16>::Equal(this, &other);
  }
  bool operator!=(const Pizza& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza,
                                                        16>::Equal(this,
                                                                   &other);
  }

  const ::std::vector<::std::string>& toppings() const {
    return storage_.toppings;
  }

  ::std::vector<::std::string>& toppings() { return storage_.toppings; }

  Pizza(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : Pizza(Storage_{
            .toppings = {},
        }) {}

 private:
  struct Storage_ final {
    ::std::vector<::std::string> toppings;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza,
                                                            16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::Pizza>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalStructMember<
                      Storage_, ::std::vector<::std::string>,
                      fidl::internal::NaturalCodingConstraintVector<
                          fidl::internal::NaturalCodingConstraintString<16>>>{
          &Storage_::toppings, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_PastaTable;

class Pasta {
 private:
  struct Storage_;

 public:
  Pasta(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  Pasta(::std::string sauce) noexcept : storage_({.sauce = std::move(sauce)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |Pasta| only if all of its members are default
  // constructible.
  Pasta() = default;
#pragma clang diagnostic pop

  Pasta(Pasta&&) noexcept = default;
  Pasta& operator=(Pasta&&) noexcept = default;
  Pasta(const Pasta& other) noexcept : Pasta(other.CloneStorage_()) {}
  Pasta& operator=(const Pasta& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(const Pasta& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta,
                                                       16>::Equal(this, &other);
  }
  bool operator!=(const Pasta& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta,
                                                        16>::Equal(this,
                                                                   &other);
  }

  const ::std::string& sauce() const { return storage_.sauce; }

  ::std::string& sauce() { return storage_.sauce; }

  Pasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : Pasta(Storage_{
            .sauce = {},
        }) {}

 private:
  struct Storage_ final {
    ::std::string sauce;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta,
                                                            16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::Pasta>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalStructMember<
                      Storage_, ::std::string,
                      fidl::internal::NaturalCodingConstraintString<16>>{
          &Storage_::sauce, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_StrictPizzaOrPastaTable;

class StrictPizzaOrPasta {
 private:
  using Storage_ =
      std::variant<std::monostate, ::test_union::Pizza, ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  StrictPizzaOrPasta(StrictPizzaOrPasta&& other) noexcept
      : StrictPizzaOrPasta(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictPizzaOrPasta& operator=(StrictPizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  StrictPizzaOrPasta(const StrictPizzaOrPasta& other) noexcept
      : StrictPizzaOrPasta(other.CloneStorage_()) {}
  StrictPizzaOrPasta& operator=(const StrictPizzaOrPasta& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const StrictPizzaOrPasta& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const StrictPizzaOrPasta& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::StrictPizzaOrPasta::Tag Which() const {
    return StrictPizzaOrPasta::IndexToTag(storage_->index()).value();
  }
  static StrictPizzaOrPasta WithPizza(::test_union::Pizza val) {
    return StrictPizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static StrictPizzaOrPasta WithPasta(::test_union::Pasta val) {
    return StrictPizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  StrictPizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::StrictPizzaOrPasta>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit StrictPizzaOrPasta(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::StrictPizzaOrPasta::Tag tag) {
    switch (tag) {
      case ::test_union::StrictPizzaOrPasta::Tag::kPizza:
        return 1;
      case ::test_union::StrictPizzaOrPasta::Tag::kPasta:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictPizzaOrPasta::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::StrictPizzaOrPasta::Tag::kPizza;
      case 2:
        return ::test_union::StrictPizzaOrPasta::Tag::kPasta;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_PizzaOrPastaTable;

class PizzaOrPasta {
 private:
  using Storage_ =
      std::variant<std::monostate, ::test_union::Pizza, ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  PizzaOrPasta(PizzaOrPasta&& other) noexcept
      : PizzaOrPasta(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  PizzaOrPasta& operator=(PizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  PizzaOrPasta(const PizzaOrPasta& other) noexcept
      : PizzaOrPasta(other.CloneStorage_()) {}
  PizzaOrPasta& operator=(const PizzaOrPasta& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const PizzaOrPasta& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const PizzaOrPasta& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::PizzaOrPasta::Tag Which() const {
    return PizzaOrPasta::IndexToTag(storage_->index()).value();
  }
  static PizzaOrPasta WithPizza(::test_union::Pizza val) {
    return PizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static PizzaOrPasta WithPasta(::test_union::Pasta val) {
    return PizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  PizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::PizzaOrPasta>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit PizzaOrPasta(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::PizzaOrPasta::Tag tag) {
    switch (tag) {
      case ::test_union::PizzaOrPasta::Tag::kPizza:
        return 1;
      case ::test_union::PizzaOrPasta::Tag::kPasta:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::PizzaOrPasta::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::PizzaOrPasta::Tag::kPizza;
      case 2:
        return ::test_union::PizzaOrPasta::Tag::kPasta;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_FlexiblePizzaOrPastaTable;

class FlexiblePizzaOrPasta {
 private:
  using Storage_ =
      std::variant<std::monostate, ::test_union::Pizza, ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  FlexiblePizzaOrPasta() : storage_(std::make_shared<Storage_>()) {}

  FlexiblePizzaOrPasta(FlexiblePizzaOrPasta&& other) noexcept
      : FlexiblePizzaOrPasta(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FlexiblePizzaOrPasta& operator=(FlexiblePizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  FlexiblePizzaOrPasta(const FlexiblePizzaOrPasta& other) noexcept
      : FlexiblePizzaOrPasta(other.CloneStorage_()) {}
  FlexiblePizzaOrPasta& operator=(const FlexiblePizzaOrPasta& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const FlexiblePizzaOrPasta& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const FlexiblePizzaOrPasta& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::FlexiblePizzaOrPasta::Tag Which() const {
    return FlexiblePizzaOrPasta::IndexToTag(storage_->index()).value();
  }
  static FlexiblePizzaOrPasta WithPizza(::test_union::Pizza val) {
    return FlexiblePizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static FlexiblePizzaOrPasta WithPasta(::test_union::Pasta val) {
    return FlexiblePizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  FlexiblePizzaOrPasta(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::FlexiblePizzaOrPasta>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit FlexiblePizzaOrPasta(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::FlexiblePizzaOrPasta::Tag tag) {
    switch (tag) {
      case ::test_union::FlexiblePizzaOrPasta::Tag::kPizza:
        return 1;
      case ::test_union::FlexiblePizzaOrPasta::Tag::kPasta:
        return 2;
      case ::test_union::FlexiblePizzaOrPasta::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FlexiblePizzaOrPasta::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::FlexiblePizzaOrPasta::Tag::kPizza;
      case 2:
        return ::test_union::FlexiblePizzaOrPasta::Tag::kPasta;
      default:
        return ::test_union::FlexiblePizzaOrPasta::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_ExplicitPizzaOrPastaTable;

class ExplicitPizzaOrPasta {
 private:
  using Storage_ =
      std::variant<std::monostate, ::test_union::Pizza, ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 4,  // 0x4
  };

  ExplicitPizzaOrPasta(ExplicitPizzaOrPasta&& other) noexcept
      : ExplicitPizzaOrPasta(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitPizzaOrPasta& operator=(ExplicitPizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  ExplicitPizzaOrPasta(const ExplicitPizzaOrPasta& other) noexcept
      : ExplicitPizzaOrPasta(other.CloneStorage_()) {}
  ExplicitPizzaOrPasta& operator=(const ExplicitPizzaOrPasta& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const ExplicitPizzaOrPasta& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const ExplicitPizzaOrPasta& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::ExplicitPizzaOrPasta::Tag Which() const {
    return ExplicitPizzaOrPasta::IndexToTag(storage_->index()).value();
  }
  static ExplicitPizzaOrPasta WithPizza(::test_union::Pizza val) {
    return ExplicitPizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static ExplicitPizzaOrPasta WithPasta(::test_union::Pasta val) {
    return ExplicitPizzaOrPasta(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ExplicitPizzaOrPasta(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::ExplicitPizzaOrPasta>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ExplicitPizzaOrPasta(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::ExplicitPizzaOrPasta::Tag tag) {
    switch (tag) {
      case ::test_union::ExplicitPizzaOrPasta::Tag::kPizza:
        return 1;
      case ::test_union::ExplicitPizzaOrPasta::Tag::kPasta:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitPizzaOrPasta::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::ExplicitPizzaOrPasta::Tag::kPizza;
      case 2:
        return ::test_union::ExplicitPizzaOrPasta::Tag::kPasta;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_OlderSimpleUnionTable;

class OlderSimpleUnion {
 private:
  using Storage_ = std::variant<std::monostate, int64_t, float>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  OlderSimpleUnion() : storage_(std::make_shared<Storage_>()) {}

  OlderSimpleUnion(OlderSimpleUnion&& other) noexcept
      : OlderSimpleUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  OlderSimpleUnion& operator=(OlderSimpleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  OlderSimpleUnion(const OlderSimpleUnion& other) noexcept
      : OlderSimpleUnion(other.CloneStorage_()) {}
  OlderSimpleUnion& operator=(const OlderSimpleUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const OlderSimpleUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const OlderSimpleUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::OlderSimpleUnion::Tag Which() const {
    return OlderSimpleUnion::IndexToTag(storage_->index()).value();
  }
  static OlderSimpleUnion WithI(int64_t val) {
    return OlderSimpleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> i() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static OlderSimpleUnion WithF(float val) {
    return OlderSimpleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> f() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> f() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  OlderSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::OlderSimpleUnion>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit OlderSimpleUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::OlderSimpleUnion::Tag tag) {
    switch (tag) {
      case ::test_union::OlderSimpleUnion::Tag::kI:
        return 1;
      case ::test_union::OlderSimpleUnion::Tag::kF:
        return 2;
      case ::test_union::OlderSimpleUnion::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::OlderSimpleUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::OlderSimpleUnion::Tag::kI;
      case 2:
        return ::test_union::OlderSimpleUnion::Tag::kF;
      default:
        return ::test_union::OlderSimpleUnion::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t
    test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;

class TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse {
 private:
  struct Storage_;

 public:
  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
      Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
      ::test_union::OlderSimpleUnion xu) noexcept
      : storage_({.xu = std::move(xu)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a
  // |TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse|
  // only if all of its members are default constructible.
  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse() =
      default;
#pragma clang diagnostic pop

  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
      TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&&) noexcept =
      default;
  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&
  operator=(
      TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&&) noexcept =
      default;
  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
      const TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&
          other) noexcept
      : TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
            other.CloneStorage_()) {}
  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&
  operator=(
      const TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&
          other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(
      const TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&
          other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<
        ::test_union::
            TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse,
        16>::Equal(this, &other);
  }
  bool operator!=(
      const TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse&
          other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<
        ::test_union::
            TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse,
        16>::Equal(this, &other);
  }

  const ::test_union::OlderSimpleUnion& xu() const { return storage_.xu; }

  ::test_union::OlderSimpleUnion& xu() { return storage_.xu; }

  TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse(
            Storage_{
                .xu = ::fidl::internal::
                    DefaultConstructPossiblyInvalidObjectTag{},
            }) {}

 private:
  struct Storage_ final {
    ::test_union::OlderSimpleUnion xu;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_union::
          TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse,
      16>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_union::
          TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, ::test_union::OlderSimpleUnion,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::xu, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_NullableUnionStructTable;

class NullableUnionStruct {
 private:
  struct Storage_;

 public:
  NullableUnionStruct(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  NullableUnionStruct(::std::unique_ptr<::test_union::Union> the_union) noexcept
      : storage_({.the_union = std::move(the_union)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |NullableUnionStruct| only if all of its members are
  // default constructible.
  NullableUnionStruct() = default;
#pragma clang diagnostic pop

  NullableUnionStruct(NullableUnionStruct&&) noexcept = default;
  NullableUnionStruct& operator=(NullableUnionStruct&&) noexcept = default;
  NullableUnionStruct(const NullableUnionStruct& other) noexcept
      : NullableUnionStruct(other.CloneStorage_()) {}
  NullableUnionStruct& operator=(const NullableUnionStruct& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(const NullableUnionStruct& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<
        ::test_union::NullableUnionStruct, 16>::Equal(this, &other);
  }
  bool operator!=(const NullableUnionStruct& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<
        ::test_union::NullableUnionStruct, 16>::Equal(this, &other);
  }

  const ::std::unique_ptr<::test_union::Union>& the_union() const {
    return storage_.the_union;
  }

  ::std::unique_ptr<::test_union::Union>& the_union() {
    return storage_.the_union;
  }

  NullableUnionStruct(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : NullableUnionStruct(Storage_{
            .the_union = {},
        }) {}

 private:
  struct Storage_ final {
    ::std::unique_ptr<::test_union::Union> the_union;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_union::NullableUnionStruct, 16>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_union::NullableUnionStruct>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalStructMember<
                      Storage_, ::std::unique_ptr<::test_union::Union>,
                      fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::the_union, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_NewerSimpleUnionTable;

class NewerSimpleUnion {
 private:
  using Storage_ = std::variant<std::monostate, int64_t, ::std::string,
                                ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    kV = 3,  // 0x3
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  NewerSimpleUnion() : storage_(std::make_shared<Storage_>()) {}

  NewerSimpleUnion(NewerSimpleUnion&& other) noexcept
      : NewerSimpleUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  NewerSimpleUnion& operator=(NewerSimpleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  NewerSimpleUnion(const NewerSimpleUnion& other) noexcept
      : NewerSimpleUnion(other.CloneStorage_()) {}
  NewerSimpleUnion& operator=(const NewerSimpleUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const NewerSimpleUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const NewerSimpleUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::NewerSimpleUnion::Tag Which() const {
    return NewerSimpleUnion::IndexToTag(storage_->index()).value();
  }
  static NewerSimpleUnion WithI(int64_t val) {
    return NewerSimpleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> i() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static NewerSimpleUnion WithS(::std::string val) {
    return NewerSimpleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> s() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> s() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  static NewerSimpleUnion WithV(::std::vector<::std::string> val) {
    return NewerSimpleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<3>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<3, Storage_> v() const {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<3, Storage_> v() {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  NewerSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::NewerSimpleUnion>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<
          ::fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintString<>>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintVector<
              fidl::internal::NaturalCodingConstraintString<>>>());

  explicit NewerSimpleUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::NewerSimpleUnion::Tag tag) {
    switch (tag) {
      case ::test_union::NewerSimpleUnion::Tag::kI:
        return 1;
      case ::test_union::NewerSimpleUnion::Tag::kS:
        return 2;
      case ::test_union::NewerSimpleUnion::Tag::kV:
        return 3;
      case ::test_union::NewerSimpleUnion::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::NewerSimpleUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::NewerSimpleUnion::Tag::kI;
      case 2:
        return ::test_union::NewerSimpleUnion::Tag::kS;
      case 3:
        return ::test_union::NewerSimpleUnion::Tag::kV;
      default:
        return ::test_union::NewerSimpleUnion::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_FlexibleUnionTable;

class FlexibleUnion {
 private:
  using Storage_ = std::variant<std::monostate, int32_t, ::std::string,
                                ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  FlexibleUnion() : storage_(std::make_shared<Storage_>()) {}

  FlexibleUnion(FlexibleUnion&& other) noexcept
      : FlexibleUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FlexibleUnion& operator=(FlexibleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  FlexibleUnion(const FlexibleUnion& other) noexcept
      : FlexibleUnion(other.CloneStorage_()) {}
  FlexibleUnion& operator=(const FlexibleUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const FlexibleUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const FlexibleUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::FlexibleUnion::Tag Which() const {
    return FlexibleUnion::IndexToTag(storage_->index()).value();
  }
  static FlexibleUnion WithPrimitive(int32_t val) {
    return FlexibleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static FlexibleUnion WithStringNeedsConstructor(::std::string val) {
    return FlexibleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_>
  string_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  static FlexibleUnion WithVectorStringAlsoNeedsConstructor(
      ::std::vector<::std::string> val) {
    return FlexibleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<3>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<3, Storage_>
  vector_string_also_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<3, Storage_>
  vector_string_also_needs_constructor() {
    return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
  }

  FlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::FlexibleUnion>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<
          ::fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintEmpty>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintString<>>(),
      ::fidl::internal::NaturalUnionMember<
          fidl::internal::NaturalCodingConstraintVector<
              fidl::internal::NaturalCodingConstraintString<>>>());

  explicit FlexibleUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::FlexibleUnion::Tag tag) {
    switch (tag) {
      case ::test_union::FlexibleUnion::Tag::kPrimitive:
        return 1;
      case ::test_union::FlexibleUnion::Tag::kStringNeedsConstructor:
        return 2;
      case ::test_union::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        return 3;
      case ::test_union::FlexibleUnion::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FlexibleUnion::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::FlexibleUnion::Tag::kPrimitive;
      case 2:
        return ::test_union::FlexibleUnion::Tag::kStringNeedsConstructor;
      case 3:
        return ::test_union::FlexibleUnion::Tag::
            kVectorStringAlsoNeedsConstructor;
      default:
        return ::test_union::FlexibleUnion::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_FlexibleFooTable;

class FlexibleFoo {
 private:
  using Storage_ = std::variant<std::monostate, ::std::string, int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  FlexibleFoo() : storage_(std::make_shared<Storage_>()) {}

  FlexibleFoo(FlexibleFoo&& other) noexcept
      : FlexibleFoo(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FlexibleFoo& operator=(FlexibleFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  FlexibleFoo(const FlexibleFoo& other) noexcept
      : FlexibleFoo(other.CloneStorage_()) {}
  FlexibleFoo& operator=(const FlexibleFoo& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const FlexibleFoo& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const FlexibleFoo& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::FlexibleFoo::Tag Which() const {
    return FlexibleFoo::IndexToTag(storage_->index()).value();
  }
  static FlexibleFoo WithS(::std::string val) {
    return FlexibleFoo(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> s() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> s() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static FlexibleFoo WithI(int32_t val) {
    return FlexibleFoo(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> i() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  FlexibleFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::FlexibleFoo>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintString<>>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit FlexibleFoo(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::FlexibleFoo::Tag tag) {
    switch (tag) {
      case ::test_union::FlexibleFoo::Tag::kS:
        return 1;
      case ::test_union::FlexibleFoo::Tag::kI:
        return 2;
      case ::test_union::FlexibleFoo::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FlexibleFoo::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::FlexibleFoo::Tag::kS;
      case 2:
        return ::test_union::FlexibleFoo::Tag::kI;
      default:
        return ::test_union::FlexibleFoo::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_FieldCollisionTable;

class FieldCollision {
 private:
  using Storage_ = std::variant<std::monostate, int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kFieldCollisionTag = 1,  // 0x1
  };

  FieldCollision(FieldCollision&& other) noexcept
      : FieldCollision(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FieldCollision& operator=(FieldCollision&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  FieldCollision(const FieldCollision& other) noexcept
      : FieldCollision(other.CloneStorage_()) {}
  FieldCollision& operator=(const FieldCollision& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const FieldCollision& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const FieldCollision& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::FieldCollision::Tag Which() const {
    return FieldCollision::IndexToTag(storage_->index()).value();
  }
  static FieldCollision WithFieldCollisionTag(int32_t val) {
    return FieldCollision(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> field_collision_tag()
      const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> field_collision_tag() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  FieldCollision(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::FieldCollision>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit FieldCollision(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::FieldCollision::Tag tag) {
    switch (tag) {
      case ::test_union::FieldCollision::Tag::kFieldCollisionTag:
        return 1;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FieldCollision::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::FieldCollision::Tag::kFieldCollisionTag;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_ExplicitXUnionTable;

class ExplicitXUnion {
 private:
  using Storage_ = std::variant<std::monostate, int64_t, float>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kI = 1,  // 0x1
    kF = 4,  // 0x4
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  ExplicitXUnion() : storage_(std::make_shared<Storage_>()) {}

  ExplicitXUnion(ExplicitXUnion&& other) noexcept
      : ExplicitXUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitXUnion& operator=(ExplicitXUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  ExplicitXUnion(const ExplicitXUnion& other) noexcept
      : ExplicitXUnion(other.CloneStorage_()) {}
  ExplicitXUnion& operator=(const ExplicitXUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const ExplicitXUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const ExplicitXUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::ExplicitXUnion::Tag Which() const {
    return ExplicitXUnion::IndexToTag(storage_->index()).value();
  }
  static ExplicitXUnion WithI(int64_t val) {
    return ExplicitXUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> i() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static ExplicitXUnion WithF(float val) {
    return ExplicitXUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> f() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> f() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ExplicitXUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::ExplicitXUnion>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ExplicitXUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::ExplicitXUnion::Tag tag) {
    switch (tag) {
      case ::test_union::ExplicitXUnion::Tag::kI:
        return 1;
      case ::test_union::ExplicitXUnion::Tag::kF:
        return 2;
      case ::test_union::ExplicitXUnion::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitXUnion::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::ExplicitXUnion::Tag::kI;
      case 2:
        return ::test_union::ExplicitXUnion::Tag::kF;
      default:
        return ::test_union::ExplicitXUnion::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_UnionSandwichTable;

class UnionSandwich {
 private:
  struct Storage_;

 public:
  UnionSandwich(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  UnionSandwich(uint32_t a, ::test_union::ExplicitXUnion u, uint32_t b) noexcept
      : storage_({.a = std::move(a), .u = std::move(u), .b = std::move(b)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |UnionSandwich| only if all of its members are default
  // constructible.
  UnionSandwich() = default;
#pragma clang diagnostic pop

  UnionSandwich(UnionSandwich&&) noexcept = default;
  UnionSandwich& operator=(UnionSandwich&&) noexcept = default;
  UnionSandwich(const UnionSandwich& other) noexcept
      : UnionSandwich(other.CloneStorage_()) {}
  UnionSandwich& operator=(const UnionSandwich& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(const UnionSandwich& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<
        ::test_union::UnionSandwich, 32>::Equal(this, &other);
  }
  bool operator!=(const UnionSandwich& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<
        ::test_union::UnionSandwich, 32>::Equal(this, &other);
  }

  uint32_t a() const { return storage_.a; }

  uint32_t& a() { return storage_.a; }

  const ::test_union::ExplicitXUnion& u() const { return storage_.u; }

  ::test_union::ExplicitXUnion& u() { return storage_.u; }

  uint32_t b() const { return storage_.b; }

  uint32_t& b() { return storage_.b; }

  UnionSandwich(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : UnionSandwich(Storage_{
            .a = {},
            .u = ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
            .b = {},
        }) {}

 private:
  struct Storage_ final {
    uint32_t a = {};
    ::test_union::ExplicitXUnion u;
    uint32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_union::UnionSandwich, 32>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::UnionSandwich>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::a, 0},
      ::fidl::internal::NaturalStructMember<
          Storage_, ::test_union::ExplicitXUnion,
          fidl::internal::NaturalCodingConstraintEmpty>{&Storage_::u, 8},
      ::fidl::internal::NaturalStructMember<
          Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::b, 24});
  static constexpr auto kPadding = std::make_tuple(
      ::fidl::internal::NaturalStructPadding<uint64_t>{
          .offset = 0,
          .mask = 0xffffffff00000000ull,
      },
      ::fidl::internal::NaturalStructPadding<uint64_t>{
          .offset = 24,
          .mask = 0xffffffff00000000ull,
      });
};

extern "C" const fidl_type_t test_union_ExplicitUnionTable;

class ExplicitUnion {
 private:
  using Storage_ = std::variant<std::monostate, int32_t, ::std::string>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kPrimitive = 1,               // 0x1
    kStringNeedsConstructor = 3,  // 0x3
  };

  ExplicitUnion(ExplicitUnion&& other) noexcept
      : ExplicitUnion(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitUnion& operator=(ExplicitUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  ExplicitUnion(const ExplicitUnion& other) noexcept
      : ExplicitUnion(other.CloneStorage_()) {}
  ExplicitUnion& operator=(const ExplicitUnion& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const ExplicitUnion& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const ExplicitUnion& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::ExplicitUnion::Tag Which() const {
    return ExplicitUnion::IndexToTag(storage_->index()).value();
  }
  static ExplicitUnion WithPrimitive(int32_t val) {
    return ExplicitUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static ExplicitUnion WithStringNeedsConstructor(::std::string val) {
    return ExplicitUnion(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_>
  string_needs_constructor() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ExplicitUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::ExplicitUnion>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintString<>>());

  explicit ExplicitUnion(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::ExplicitUnion::Tag tag) {
    switch (tag) {
      case ::test_union::ExplicitUnion::Tag::kPrimitive:
        return 1;
      case ::test_union::ExplicitUnion::Tag::kStringNeedsConstructor:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitUnion::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::ExplicitUnion::Tag::kPrimitive;
      case 2:
        return ::test_union::ExplicitUnion::Tag::kStringNeedsConstructor;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_ExplicitStrictFooTable;

class ExplicitStrictFoo {
 private:
  using Storage_ = std::variant<std::monostate, ::std::string, int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kS = 3,  // 0x3
    kI = 2,  // 0x2
  };

  ExplicitStrictFoo(ExplicitStrictFoo&& other) noexcept
      : ExplicitStrictFoo(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitStrictFoo& operator=(ExplicitStrictFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  ExplicitStrictFoo(const ExplicitStrictFoo& other) noexcept
      : ExplicitStrictFoo(other.CloneStorage_()) {}
  ExplicitStrictFoo& operator=(const ExplicitStrictFoo& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const ExplicitStrictFoo& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const ExplicitStrictFoo& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::ExplicitStrictFoo::Tag Which() const {
    return ExplicitStrictFoo::IndexToTag(storage_->index()).value();
  }
  static ExplicitStrictFoo WithS(::std::string val) {
    return ExplicitStrictFoo(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> s() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> s() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static ExplicitStrictFoo WithI(int32_t val) {
    return ExplicitStrictFoo(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> i() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ExplicitStrictFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::ExplicitStrictFoo>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintString<>>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ExplicitStrictFoo(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::ExplicitStrictFoo::Tag tag) {
    switch (tag) {
      case ::test_union::ExplicitStrictFoo::Tag::kS:
        return 1;
      case ::test_union::ExplicitStrictFoo::Tag::kI:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitStrictFoo::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::ExplicitStrictFoo::Tag::kS;
      case 2:
        return ::test_union::ExplicitStrictFoo::Tag::kI;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_union_ExplicitFooTable;

class ExplicitFoo {
 private:
  using Storage_ = std::variant<std::monostate, ::std::string, int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kS = 2,  // 0x2
    kI = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  ExplicitFoo() : storage_(std::make_shared<Storage_>()) {}

  ExplicitFoo(ExplicitFoo&& other) noexcept
      : ExplicitFoo(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitFoo& operator=(ExplicitFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  ExplicitFoo(const ExplicitFoo& other) noexcept
      : ExplicitFoo(other.CloneStorage_()) {}
  ExplicitFoo& operator=(const ExplicitFoo& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const ExplicitFoo& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const ExplicitFoo& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::ExplicitFoo::Tag Which() const {
    return ExplicitFoo::IndexToTag(storage_->index()).value();
  }
  static ExplicitFoo WithS(::std::string val) {
    return ExplicitFoo(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> s() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> s() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  static ExplicitFoo WithI(int32_t val) {
    return ExplicitFoo(
        std::make_shared<Storage_>(std::in_place_index_t<2>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> i() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<2, Storage_> i() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ExplicitFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::ExplicitFoo>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintString<>>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ExplicitFoo(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder,
                                     ::test_union::ExplicitFoo::Tag tag) {
    switch (tag) {
      case ::test_union::ExplicitFoo::Tag::kS:
        return 1;
      case ::test_union::ExplicitFoo::Tag::kI:
        return 2;
      case ::test_union::ExplicitFoo::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitFoo::Tag> IndexToTag(
      size_t index) {
    switch (index) {
      case 1:
        return ::test_union::ExplicitFoo::Tag::kS;
      case 2:
        return ::test_union::ExplicitFoo::Tag::kI;
      default:
        return ::test_union::ExplicitFoo::Tag::kUnknown;
    }
  }
};

extern "C" const fidl_type_t test_union_EmptyTable;

class Empty {
 private:
  struct Storage_;

 public:
  Empty(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  Empty(uint8_t __reserved) noexcept
      : storage_({.__reserved = std::move(__reserved)}) {}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |Empty| only if all of its members are default
  // constructible.
  Empty() = default;
#pragma clang diagnostic pop

  Empty(Empty&&) noexcept = default;
  Empty& operator=(Empty&&) noexcept = default;
  Empty(const Empty& other) noexcept : Empty(other.CloneStorage_()) {}
  Empty& operator=(const Empty& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool operator==(const Empty& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_union::Empty,
                                                       1>::Equal(this, &other);
  }
  bool operator!=(const Empty& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_union::Empty,
                                                        1>::Equal(this, &other);
  }

  uint8_t __reserved() const { return storage_.__reserved; }

  uint8_t& __reserved() { return storage_.__reserved; }

  Empty(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : Empty(Storage_{
            .__reserved = 0u,
        }) {}

 private:
  struct Storage_ final {
    uint8_t __reserved = 0u;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::Empty,
                                                            1>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::Empty>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, uint8_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::__reserved, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_union_XUnionContainingEmptyStructTable;

class XUnionContainingEmptyStruct {
 private:
  using Storage_ = std::variant<std::monostate, ::test_union::Empty>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kEmpty = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  XUnionContainingEmptyStruct() : storage_(std::make_shared<Storage_>()) {}

  XUnionContainingEmptyStruct(XUnionContainingEmptyStruct&& other) noexcept
      : XUnionContainingEmptyStruct(
            ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  XUnionContainingEmptyStruct& operator=(
      XUnionContainingEmptyStruct&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  XUnionContainingEmptyStruct(const XUnionContainingEmptyStruct& other) noexcept
      : XUnionContainingEmptyStruct(other.CloneStorage_()) {}
  XUnionContainingEmptyStruct& operator=(
      const XUnionContainingEmptyStruct& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const XUnionContainingEmptyStruct& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const XUnionContainingEmptyStruct& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_union::XUnionContainingEmptyStruct::Tag Which() const {
    return XUnionContainingEmptyStruct::IndexToTag(storage_->index()).value();
  }
  static XUnionContainingEmptyStruct WithEmpty(::test_union::Empty val) {
    return XUnionContainingEmptyStruct(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> empty() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }
  ::fidl::internal::UnionMemberView<1, Storage_> empty() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  XUnionContainingEmptyStruct(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<
      ::test_union::XUnionContainingEmptyStruct>;
  static constexpr auto kMembers =
      std::make_tuple(::fidl::internal::NaturalUnionMember<
                          ::fidl::internal::NaturalCodingConstraintEmpty>(),
                      ::fidl::internal::NaturalUnionMember<
                          fidl::internal::NaturalCodingConstraintEmpty>());

  explicit XUnionContainingEmptyStruct(std::shared_ptr<Storage_> storage)
      : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(
      ::fidl::internal::NaturalDecoder* decoder,
      ::test_union::XUnionContainingEmptyStruct::Tag tag) {
    switch (tag) {
      case ::test_union::XUnionContainingEmptyStruct::Tag::kEmpty:
        return 1;
      case ::test_union::XUnionContainingEmptyStruct::Tag::kUnknown:
        return 0;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::XUnionContainingEmptyStruct::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_union::XUnionContainingEmptyStruct::Tag::kEmpty;
      default:
        return ::test_union::XUnionContainingEmptyStruct::Tag::kUnknown;
    }
  }
};

}  // namespace test_union
namespace fidl {

extern "C" const fidl_type_t test_union_StructWithNullableXUnionTable;

template <>
struct IsFidlType<::test_union::StructWithNullableXUnion>
    : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::StructWithNullableXUnion>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_StructWithNullableXUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::StructWithNullableXUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalStructCodingTraits<
                ::test_union::StructWithNullableXUnion, 16> {};

extern "C" const fidl_type_t
    test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;

template <>
struct IsFidlType<
    ::test_union::
        TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>
    : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<
    ::test_union::
        TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::
        TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final
    : public ::fidl::internal::NaturalStructCodingTraits<
          ::test_union::
              TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse,
          16> {};

extern "C" const fidl_type_t test_union_PizzaTable;

template <>
struct IsFidlType<::test_union::Pizza> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::Pizza> final {
 public:
  static constexpr const fidl_type_t* kCodingTable = &test_union_PizzaTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::Pizza, ::fidl::internal::NaturalCodingConstraintEmpty>
    final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza,
                                                         16> {};

extern "C" const fidl_type_t test_union_PastaTable;

template <>
struct IsFidlType<::test_union::Pasta> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::Pasta> final {
 public:
  static constexpr const fidl_type_t* kCodingTable = &test_union_PastaTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::Pasta, ::fidl::internal::NaturalCodingConstraintEmpty>
    final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta,
                                                         16> {};

extern "C" const fidl_type_t
    test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;

template <>
struct IsFidlType<
    ::test_union::
        TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>
    : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<
    ::test_union::
        TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::
        TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final
    : public ::fidl::internal::NaturalStructCodingTraits<
          ::test_union::
              TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse,
          16> {};

extern "C" const fidl_type_t test_union_NullableUnionStructTable;

template <>
struct IsFidlType<::test_union::NullableUnionStruct> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::NullableUnionStruct> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_NullableUnionStructTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::NullableUnionStruct,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalStructCodingTraits<
                ::test_union::NullableUnionStruct, 16> {};

extern "C" const fidl_type_t test_union_UnionSandwichTable;

template <>
struct IsFidlType<::test_union::UnionSandwich> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::UnionSandwich> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_UnionSandwichTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::UnionSandwich, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalStructCodingTraits<
                ::test_union::UnionSandwich, 32> {};

extern "C" const fidl_type_t test_union_EmptyTable;

template <>
struct IsFidlType<::test_union::Empty> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::Empty> final {
 public:
  static constexpr const fidl_type_t* kCodingTable = &test_union_EmptyTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::Empty, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalEmptyStructCodingTraits<
                ::test_union::Empty> {};

extern "C" const fidl_type_t test_union_UnionWithAttributesTable;

template <>
struct IsFidlType<::test_union::UnionWithAttributes> : public std::true_type {};
template <>
struct IsUnion<::test_union::UnionWithAttributes> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::UnionWithAttributes> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_UnionWithAttributesTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::UnionWithAttributes,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::UnionWithAttributes> {};

extern "C" const fidl_type_t test_union_UnionTable;

template <>
struct IsFidlType<::test_union::Union> : public std::true_type {};
template <>
struct IsUnion<::test_union::Union> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::Union> final {
 public:
  static constexpr const fidl_type_t* kCodingTable = &test_union_UnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::Union, ::fidl::internal::NaturalCodingConstraintEmpty>
    final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::Union> {};

extern "C" const fidl_type_t test_union_StrictUnionTable;

template <>
struct IsFidlType<::test_union::StrictUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::StrictUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::StrictUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_StrictUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::StrictUnion, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::StrictUnion> {};

extern "C" const fidl_type_t test_union_StrictSimpleXUnionTable;

template <>
struct IsFidlType<::test_union::StrictSimpleXUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::StrictSimpleXUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::StrictSimpleXUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_StrictSimpleXUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::StrictSimpleXUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::StrictSimpleXUnion> {};

extern "C" const fidl_type_t test_union_StrictFooTable;

template <>
struct IsFidlType<::test_union::StrictFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::StrictFoo> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::StrictFoo> final {
 public:
  static constexpr const fidl_type_t* kCodingTable = &test_union_StrictFooTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::StrictFoo, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::StrictFoo> {};

extern "C" const fidl_type_t test_union_StrictBoundedXUnionTable;

template <>
struct IsFidlType<::test_union::StrictBoundedXUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::StrictBoundedXUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::StrictBoundedXUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_StrictBoundedXUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::StrictBoundedXUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::StrictBoundedXUnion> {};

extern "C" const fidl_type_t test_union_ReverseOrdinalUnionTable;

template <>
struct IsFidlType<::test_union::ReverseOrdinalUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::ReverseOrdinalUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::ReverseOrdinalUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_ReverseOrdinalUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::ReverseOrdinalUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::ReverseOrdinalUnion> {};

extern "C" const fidl_type_t test_union_StrictPizzaOrPastaTable;

template <>
struct IsFidlType<::test_union::StrictPizzaOrPasta> : public std::true_type {};
template <>
struct IsUnion<::test_union::StrictPizzaOrPasta> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::StrictPizzaOrPasta> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_StrictPizzaOrPastaTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::StrictPizzaOrPasta,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::StrictPizzaOrPasta> {};

extern "C" const fidl_type_t test_union_PizzaOrPastaTable;

template <>
struct IsFidlType<::test_union::PizzaOrPasta> : public std::true_type {};
template <>
struct IsUnion<::test_union::PizzaOrPasta> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::PizzaOrPasta> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_PizzaOrPastaTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::PizzaOrPasta, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::PizzaOrPasta> {};

extern "C" const fidl_type_t test_union_FlexiblePizzaOrPastaTable;

template <>
struct IsFidlType<::test_union::FlexiblePizzaOrPasta> : public std::true_type {
};
template <>
struct IsUnion<::test_union::FlexiblePizzaOrPasta> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::FlexiblePizzaOrPasta> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_FlexiblePizzaOrPastaTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::FlexiblePizzaOrPasta,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::FlexiblePizzaOrPasta> {};

extern "C" const fidl_type_t test_union_ExplicitPizzaOrPastaTable;

template <>
struct IsFidlType<::test_union::ExplicitPizzaOrPasta> : public std::true_type {
};
template <>
struct IsUnion<::test_union::ExplicitPizzaOrPasta> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::ExplicitPizzaOrPasta> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_ExplicitPizzaOrPastaTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::ExplicitPizzaOrPasta,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::ExplicitPizzaOrPasta> {};

extern "C" const fidl_type_t test_union_OlderSimpleUnionTable;

template <>
struct IsFidlType<::test_union::OlderSimpleUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::OlderSimpleUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::OlderSimpleUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_OlderSimpleUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::OlderSimpleUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::OlderSimpleUnion> {};

extern "C" const fidl_type_t test_union_NewerSimpleUnionTable;

template <>
struct IsFidlType<::test_union::NewerSimpleUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::NewerSimpleUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::NewerSimpleUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_NewerSimpleUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::NewerSimpleUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::NewerSimpleUnion> {};

extern "C" const fidl_type_t test_union_FlexibleUnionTable;

template <>
struct IsFidlType<::test_union::FlexibleUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::FlexibleUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::FlexibleUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_FlexibleUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::FlexibleUnion, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::FlexibleUnion> {};

extern "C" const fidl_type_t test_union_FlexibleFooTable;

template <>
struct IsFidlType<::test_union::FlexibleFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::FlexibleFoo> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::FlexibleFoo> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_FlexibleFooTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::FlexibleFoo, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::FlexibleFoo> {};

extern "C" const fidl_type_t test_union_FieldCollisionTable;

template <>
struct IsFidlType<::test_union::FieldCollision> : public std::true_type {};
template <>
struct IsUnion<::test_union::FieldCollision> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::FieldCollision> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_FieldCollisionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::FieldCollision,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::FieldCollision> {};

extern "C" const fidl_type_t test_union_ExplicitXUnionTable;

template <>
struct IsFidlType<::test_union::ExplicitXUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::ExplicitXUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::ExplicitXUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_ExplicitXUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::ExplicitXUnion,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::ExplicitXUnion> {};

extern "C" const fidl_type_t test_union_ExplicitUnionTable;

template <>
struct IsFidlType<::test_union::ExplicitUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::ExplicitUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::ExplicitUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_ExplicitUnionTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::ExplicitUnion, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::ExplicitUnion> {};

extern "C" const fidl_type_t test_union_ExplicitStrictFooTable;

template <>
struct IsFidlType<::test_union::ExplicitStrictFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::ExplicitStrictFoo> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::ExplicitStrictFoo> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_ExplicitStrictFooTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::ExplicitStrictFoo,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::ExplicitStrictFoo> {};

extern "C" const fidl_type_t test_union_ExplicitFooTable;

template <>
struct IsFidlType<::test_union::ExplicitFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::ExplicitFoo> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::ExplicitFoo> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_ExplicitFooTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::ExplicitFoo, ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::ExplicitFoo> {};

extern "C" const fidl_type_t test_union_XUnionContainingEmptyStructTable;

template <>
struct IsFidlType<::test_union::XUnionContainingEmptyStruct>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::XUnionContainingEmptyStruct>
    : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_union::XUnionContainingEmptyStruct>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_union_XUnionContainingEmptyStructTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_union::XUnionContainingEmptyStruct,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalUnionCodingTraits<
                ::test_union::XUnionContainingEmptyStruct> {};

}  // namespace fidl
