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

#pragma once

#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

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

namespace test_union {
namespace wire {
struct StructWithNullableXUnion;

struct TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse;

struct Pizza;

struct Pasta;

struct TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse;

struct NullableUnionStruct;

struct UnionSandwich;

struct 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_EmptyTable;

struct Empty {
  uint8_t __reserved = {};
};

extern "C" const fidl_type_t test_union_UnionWithAttributesTable;

class UnionWithAttributes {
 public:
  UnionWithAttributes()
      : ordinal_(::test_union::wire::UnionWithAttributes::Ordinal::Invalid),
        envelope_{} {}

  UnionWithAttributes(const UnionWithAttributes&) = default;
  UnionWithAttributes& operator=(const UnionWithAttributes&) = default;
  UnionWithAttributes(UnionWithAttributes&&) = default;
  UnionWithAttributes& operator=(UnionWithAttributes&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kX = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_union::wire::UnionWithAttributes::Ordinal::Invalid;
  }

  bool is_x() const {
    return ordinal_ == ::test_union::wire::UnionWithAttributes::Ordinal::kX;
  }

  static UnionWithAttributes WithX(::fidl::ObjectView<int64_t> val) {
    UnionWithAttributes result;
    result.ordinal_ = ::test_union::wire::UnionWithAttributes::Ordinal::kX;
    result.envelope_.As<int64_t>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static UnionWithAttributes WithX(::fidl::AnyArena& allocator,
                                   Args&&... args) {
    return WithX(
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& x() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::UnionWithAttributes::Ordinal::kX);
    return envelope_.As<int64_t>().get_data();
  }
  const int64_t& x() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::UnionWithAttributes::Ordinal::kX);
    return envelope_.As<int64_t>().get_data();
  }
  ::test_union::wire::UnionWithAttributes::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kX = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::UnionWithAttributes::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_UnionTable;

class Union {
 public:
  Union()
      : ordinal_(::test_union::wire::Union::Ordinal::Invalid), envelope_{} {}

  Union(const Union&) = default;
  Union& operator=(const Union&) = default;
  Union(Union&&) = default;
  Union& operator=(Union&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::Union::Ordinal::Invalid;
  }

  bool is_primitive() const {
    return ordinal_ == ::test_union::wire::Union::Ordinal::kPrimitive;
  }

  static Union WithPrimitive(int32_t val) {
    Union result;
    result.ordinal_ = ::test_union::wire::Union::Ordinal::kPrimitive;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& primitive() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::Union::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::Union::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }

  bool is_string_needs_constructor() const {
    return ordinal_ ==
           ::test_union::wire::Union::Ordinal::kStringNeedsConstructor;
  }

  static Union WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    Union result;
    result.ordinal_ =
        ::test_union::wire::Union::Ordinal::kStringNeedsConstructor;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static Union WithStringNeedsConstructor(::fidl::AnyArena& allocator,
                                          Args&&... args) {
    return WithStringNeedsConstructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& string_needs_constructor() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::Union::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::Union::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_vector_string_also_needs_constructor() const {
    return ordinal_ == ::test_union::wire::Union::Ordinal::
                           kVectorStringAlsoNeedsConstructor;
  }

  static Union WithVectorStringAlsoNeedsConstructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    Union result;
    result.ordinal_ =
        ::test_union::wire::Union::Ordinal::kVectorStringAlsoNeedsConstructor;
    result.envelope_.As<::fidl::VectorView<::fidl::StringView>>().set_data(
        std::move(val));
    return result;
  }

  template <typename... Args>
  static Union WithVectorStringAlsoNeedsConstructor(::fidl::AnyArena& allocator,
                                                    Args&&... args) {
    return WithVectorStringAlsoNeedsConstructor(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::Union::Ordinal::kVectorStringAlsoNeedsConstructor);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  const ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() const {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::Union::Ordinal::kVectorStringAlsoNeedsConstructor);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  ::test_union::wire::Union::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::Union::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::Union::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_StrictUnionTable;

class StrictUnion {
 public:
  StrictUnion()
      : ordinal_(::test_union::wire::StrictUnion::Ordinal::Invalid),
        envelope_{} {}

  StrictUnion(const StrictUnion&) = default;
  StrictUnion& operator=(const StrictUnion&) = default;
  StrictUnion(StrictUnion&&) = default;
  StrictUnion& operator=(StrictUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::StrictUnion::Ordinal::Invalid;
  }

  bool is_primitive() const {
    return ordinal_ == ::test_union::wire::StrictUnion::Ordinal::kPrimitive;
  }

  static StrictUnion WithPrimitive(int32_t val) {
    StrictUnion result;
    result.ordinal_ = ::test_union::wire::StrictUnion::Ordinal::kPrimitive;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& primitive() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictUnion::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictUnion::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }

  bool is_string_needs_constructor() const {
    return ordinal_ ==
           ::test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor;
  }

  static StrictUnion WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    StrictUnion result;
    result.ordinal_ =
        ::test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictUnion WithStringNeedsConstructor(::fidl::AnyArena& allocator,
                                                Args&&... args) {
    return WithStringNeedsConstructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& string_needs_constructor() {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_vector_string_also_needs_constructor() const {
    return ordinal_ == ::test_union::wire::StrictUnion::Ordinal::
                           kVectorStringAlsoNeedsConstructor;
  }

  static StrictUnion WithVectorStringAlsoNeedsConstructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    StrictUnion result;
    result.ordinal_ = ::test_union::wire::StrictUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    result.envelope_.As<::fidl::VectorView<::fidl::StringView>>().set_data(
        std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictUnion WithVectorStringAlsoNeedsConstructor(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithVectorStringAlsoNeedsConstructor(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  const ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  ::test_union::wire::StrictUnion::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::StrictUnion::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::StrictUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_StrictSimpleXUnionTable;

class StrictSimpleXUnion {
 public:
  StrictSimpleXUnion()
      : ordinal_(::test_union::wire::StrictSimpleXUnion::Ordinal::Invalid),
        envelope_{} {}

  StrictSimpleXUnion(const StrictSimpleXUnion&) = default;
  StrictSimpleXUnion& operator=(const StrictSimpleXUnion&) = default;
  StrictSimpleXUnion(StrictSimpleXUnion&&) = default;
  StrictSimpleXUnion& operator=(StrictSimpleXUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kS = 3,  // 0x3
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::Invalid;
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kI;
  }

  static StrictSimpleXUnion WithI(int32_t val) {
    StrictSimpleXUnion result;
    result.ordinal_ = ::test_union::wire::StrictSimpleXUnion::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }

  bool is_f() const {
    return ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kF;
  }

  static StrictSimpleXUnion WithF(float val) {
    StrictSimpleXUnion result;
    result.ordinal_ = ::test_union::wire::StrictSimpleXUnion::Ordinal::kF;
    result.envelope_.As<float>().set_data(std::move(val));
    return result;
  }

  float& f() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kF);
    return envelope_.As<float>().get_data();
  }
  const float& f() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kF);
    return envelope_.As<float>().get_data();
  }

  bool is_s() const {
    return ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kS;
  }

  static StrictSimpleXUnion WithS(::fidl::ObjectView<::fidl::StringView> val) {
    StrictSimpleXUnion result;
    result.ordinal_ = ::test_union::wire::StrictSimpleXUnion::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictSimpleXUnion WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictSimpleXUnion::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  ::test_union::wire::StrictSimpleXUnion::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::StrictSimpleXUnion::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kS = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::StrictSimpleXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_StrictFooTable;

class StrictFoo {
 public:
  StrictFoo()
      : ordinal_(::test_union::wire::StrictFoo::Ordinal::Invalid),
        envelope_{} {}

  StrictFoo(const StrictFoo&) = default;
  StrictFoo& operator=(const StrictFoo&) = default;
  StrictFoo(StrictFoo&&) = default;
  StrictFoo& operator=(StrictFoo&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::StrictFoo::Ordinal::Invalid;
  }

  bool is_s() const {
    return ordinal_ == ::test_union::wire::StrictFoo::Ordinal::kS;
  }

  static StrictFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    StrictFoo result;
    result.ordinal_ = ::test_union::wire::StrictFoo::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictFoo WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::StrictFoo::Ordinal::kI;
  }

  static StrictFoo WithI(int32_t val) {
    StrictFoo result;
    result.ordinal_ = ::test_union::wire::StrictFoo::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_union::wire::StrictFoo::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::StrictFoo::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kS = 1,  // 0x1
    kI = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::StrictFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_StrictBoundedXUnionTable;

class StrictBoundedXUnion {
 public:
  StrictBoundedXUnion()
      : ordinal_(::test_union::wire::StrictBoundedXUnion::Ordinal::Invalid),
        envelope_{} {}

  StrictBoundedXUnion(const StrictBoundedXUnion&) = default;
  StrictBoundedXUnion& operator=(const StrictBoundedXUnion&) = default;
  StrictBoundedXUnion(StrictBoundedXUnion&&) = default;
  StrictBoundedXUnion& operator=(StrictBoundedXUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kV = 1,  // 0x1
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_union::wire::StrictBoundedXUnion::Ordinal::Invalid;
  }

  bool is_v() const {
    return ordinal_ == ::test_union::wire::StrictBoundedXUnion::Ordinal::kV;
  }

  static StrictBoundedXUnion WithV(
      ::fidl::ObjectView<::fidl::VectorView<uint8_t>> val) {
    StrictBoundedXUnion result;
    result.ordinal_ = ::test_union::wire::StrictBoundedXUnion::Ordinal::kV;
    result.envelope_.As<::fidl::VectorView<uint8_t>>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictBoundedXUnion WithV(::fidl::AnyArena& allocator,
                                   Args&&... args) {
    return WithV(::fidl::ObjectView<::fidl::VectorView<uint8_t>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<uint8_t>& v() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictBoundedXUnion::Ordinal::kV);
    return envelope_.As<::fidl::VectorView<uint8_t>>().get_data();
  }
  const ::fidl::VectorView<uint8_t>& v() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::StrictBoundedXUnion::Ordinal::kV);
    return envelope_.As<::fidl::VectorView<uint8_t>>().get_data();
  }
  ::test_union::wire::StrictBoundedXUnion::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::StrictBoundedXUnion::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kV = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::StrictBoundedXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_ReverseOrdinalUnionTable;

class ReverseOrdinalUnion {
 public:
  ReverseOrdinalUnion()
      : ordinal_(::test_union::wire::ReverseOrdinalUnion::Ordinal::Invalid),
        envelope_{} {}

  ReverseOrdinalUnion(const ReverseOrdinalUnion&) = default;
  ReverseOrdinalUnion& operator=(const ReverseOrdinalUnion&) = default;
  ReverseOrdinalUnion(ReverseOrdinalUnion&&) = default;
  ReverseOrdinalUnion& operator=(ReverseOrdinalUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kSecond = 2,  // 0x2
    kFirst = 1,   // 0x1
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_union::wire::ReverseOrdinalUnion::Ordinal::Invalid;
  }

  bool is_second() const {
    return ordinal_ ==
           ::test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond;
  }

  static ReverseOrdinalUnion WithSecond(uint32_t val) {
    ReverseOrdinalUnion result;
    result.ordinal_ = ::test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& second() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& second() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond);
    return envelope_.As<uint32_t>().get_data();
  }

  bool is_first() const {
    return ordinal_ == ::test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst;
  }

  static ReverseOrdinalUnion WithFirst(uint32_t val) {
    ReverseOrdinalUnion result;
    result.ordinal_ = ::test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& first() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& first() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_union::wire::ReverseOrdinalUnion::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::ReverseOrdinalUnion::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kSecond = 2,  // 0x2
    kFirst = 1,   // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::ReverseOrdinalUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_StrictPizzaOrPastaTable;

class StrictPizzaOrPasta {
 public:
  StrictPizzaOrPasta()
      : ordinal_(::test_union::wire::StrictPizzaOrPasta::Ordinal::Invalid),
        envelope_{} {}

  StrictPizzaOrPasta(const StrictPizzaOrPasta&) = default;
  StrictPizzaOrPasta& operator=(const StrictPizzaOrPasta&) = default;
  StrictPizzaOrPasta(StrictPizzaOrPasta&&) = default;
  StrictPizzaOrPasta& operator=(StrictPizzaOrPasta&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::StrictPizzaOrPasta::Ordinal::Invalid;
  }

  bool is_pizza() const {
    return ordinal_ == ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza;
  }

  static StrictPizzaOrPasta WithPizza(
      ::fidl::ObjectView<::test_union::wire::Pizza> val) {
    StrictPizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza;
    result.envelope_.As<::test_union::wire::Pizza>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictPizzaOrPasta WithPizza(::fidl::AnyArena& allocator,
                                      Args&&... args) {
    return WithPizza(::fidl::ObjectView<::test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pizza& pizza() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }
  const ::test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }

  bool is_pasta() const {
    return ordinal_ == ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta;
  }

  static StrictPizzaOrPasta WithPasta(
      ::fidl::ObjectView<::test_union::wire::Pasta> val) {
    StrictPizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta;
    result.envelope_.As<::test_union::wire::Pasta>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictPizzaOrPasta WithPasta(::fidl::AnyArena& allocator,
                                      Args&&... args) {
    return WithPasta(::fidl::ObjectView<::test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pasta& pasta() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  const ::test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  ::test_union::wire::StrictPizzaOrPasta::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::StrictPizzaOrPasta::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::StrictPizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_PizzaOrPastaTable;

class PizzaOrPasta {
 public:
  PizzaOrPasta()
      : ordinal_(::test_union::wire::PizzaOrPasta::Ordinal::Invalid),
        envelope_{} {}

  PizzaOrPasta(const PizzaOrPasta&) = default;
  PizzaOrPasta& operator=(const PizzaOrPasta&) = default;
  PizzaOrPasta(PizzaOrPasta&&) = default;
  PizzaOrPasta& operator=(PizzaOrPasta&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::Invalid;
  }

  bool is_pizza() const {
    return ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::kPizza;
  }

  static PizzaOrPasta WithPizza(
      ::fidl::ObjectView<::test_union::wire::Pizza> val) {
    PizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::PizzaOrPasta::Ordinal::kPizza;
    result.envelope_.As<::test_union::wire::Pizza>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static PizzaOrPasta WithPizza(::fidl::AnyArena& allocator, Args&&... args) {
    return WithPizza(::fidl::ObjectView<::test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pizza& pizza() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }
  const ::test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }

  bool is_pasta() const {
    return ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::kPasta;
  }

  static PizzaOrPasta WithPasta(
      ::fidl::ObjectView<::test_union::wire::Pasta> val) {
    PizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::PizzaOrPasta::Ordinal::kPasta;
    result.envelope_.As<::test_union::wire::Pasta>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static PizzaOrPasta WithPasta(::fidl::AnyArena& allocator, Args&&... args) {
    return WithPasta(::fidl::ObjectView<::test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pasta& pasta() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  const ::test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::PizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  ::test_union::wire::PizzaOrPasta::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::PizzaOrPasta::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::PizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_FlexiblePizzaOrPastaTable;

class FlexiblePizzaOrPasta {
 public:
  FlexiblePizzaOrPasta()
      : ordinal_(::test_union::wire::FlexiblePizzaOrPasta::Ordinal::Invalid),
        envelope_{} {}

  FlexiblePizzaOrPasta(const FlexiblePizzaOrPasta&) = default;
  FlexiblePizzaOrPasta& operator=(const FlexiblePizzaOrPasta&) = default;
  FlexiblePizzaOrPasta(FlexiblePizzaOrPasta&&) = default;
  FlexiblePizzaOrPasta& operator=(FlexiblePizzaOrPasta&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::Invalid;
  }

  bool is_pizza() const {
    return ordinal_ ==
           ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza;
  }

  static FlexiblePizzaOrPasta WithPizza(
      ::fidl::ObjectView<::test_union::wire::Pizza> val) {
    FlexiblePizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza;
    result.envelope_.As<::test_union::wire::Pizza>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static FlexiblePizzaOrPasta WithPizza(::fidl::AnyArena& allocator,
                                        Args&&... args) {
    return WithPizza(::fidl::ObjectView<::test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pizza& pizza() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }
  const ::test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }

  bool is_pasta() const {
    return ordinal_ ==
           ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta;
  }

  static FlexiblePizzaOrPasta WithPasta(
      ::fidl::ObjectView<::test_union::wire::Pasta> val) {
    FlexiblePizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta;
    result.envelope_.As<::test_union::wire::Pasta>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static FlexiblePizzaOrPasta WithPasta(::fidl::AnyArena& allocator,
                                        Args&&... args) {
    return WithPasta(::fidl::ObjectView<::test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pasta& pasta() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  const ::test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  ::test_union::wire::FlexiblePizzaOrPasta::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::FlexiblePizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_ExplicitPizzaOrPastaTable;

class ExplicitPizzaOrPasta {
 public:
  ExplicitPizzaOrPasta()
      : ordinal_(::test_union::wire::ExplicitPizzaOrPasta::Ordinal::Invalid),
        envelope_{} {}

  ExplicitPizzaOrPasta(const ExplicitPizzaOrPasta&) = default;
  ExplicitPizzaOrPasta& operator=(const ExplicitPizzaOrPasta&) = default;
  ExplicitPizzaOrPasta(ExplicitPizzaOrPasta&&) = default;
  ExplicitPizzaOrPasta& operator=(ExplicitPizzaOrPasta&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 4,  // 0x4
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::Invalid;
  }

  bool is_pizza() const {
    return ordinal_ ==
           ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza;
  }

  static ExplicitPizzaOrPasta WithPizza(
      ::fidl::ObjectView<::test_union::wire::Pizza> val) {
    ExplicitPizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza;
    result.envelope_.As<::test_union::wire::Pizza>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static ExplicitPizzaOrPasta WithPizza(::fidl::AnyArena& allocator,
                                        Args&&... args) {
    return WithPizza(::fidl::ObjectView<::test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pizza& pizza() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }
  const ::test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza);
    return envelope_.As<::test_union::wire::Pizza>().get_data();
  }

  bool is_pasta() const {
    return ordinal_ ==
           ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta;
  }

  static ExplicitPizzaOrPasta WithPasta(
      ::fidl::ObjectView<::test_union::wire::Pasta> val) {
    ExplicitPizzaOrPasta result;
    result.ordinal_ = ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta;
    result.envelope_.As<::test_union::wire::Pasta>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static ExplicitPizzaOrPasta WithPasta(::fidl::AnyArena& allocator,
                                        Args&&... args) {
    return WithPasta(::fidl::ObjectView<::test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::test_union::wire::Pasta& pasta() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  const ::test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta);
    return envelope_.As<::test_union::wire::Pasta>().get_data();
  }
  ::test_union::wire::ExplicitPizzaOrPasta::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::ExplicitPizzaOrPasta::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPizza = 1,  // 0x1
    kPasta = 4,  // 0x4
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::ExplicitPizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_OlderSimpleUnionTable;

class OlderSimpleUnion {
 public:
  OlderSimpleUnion()
      : ordinal_(::test_union::wire::OlderSimpleUnion::Ordinal::Invalid),
        envelope_{} {}

  OlderSimpleUnion(const OlderSimpleUnion&) = default;
  OlderSimpleUnion& operator=(const OlderSimpleUnion&) = default;
  OlderSimpleUnion(OlderSimpleUnion&&) = default;
  OlderSimpleUnion& operator=(OlderSimpleUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::Invalid;
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::kI;
  }

  static OlderSimpleUnion WithI(::fidl::ObjectView<int64_t> val) {
    OlderSimpleUnion result;
    result.ordinal_ = ::test_union::wire::OlderSimpleUnion::Ordinal::kI;
    result.envelope_.As<int64_t>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static OlderSimpleUnion WithI(::fidl::AnyArena& allocator, Args&&... args) {
    return WithI(
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::kI);
    return envelope_.As<int64_t>().get_data();
  }
  const int64_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::kI);
    return envelope_.As<int64_t>().get_data();
  }

  bool is_f() const {
    return ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::kF;
  }

  static OlderSimpleUnion WithF(float val) {
    OlderSimpleUnion result;
    result.ordinal_ = ::test_union::wire::OlderSimpleUnion::Ordinal::kF;
    result.envelope_.As<float>().set_data(std::move(val));
    return result;
  }

  float& f() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::kF);
    return envelope_.As<float>().get_data();
  }
  const float& f() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::OlderSimpleUnion::Ordinal::kF);
    return envelope_.As<float>().get_data();
  }
  ::test_union::wire::OlderSimpleUnion::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kI = 1,  // 0x1
    kF = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::OlderSimpleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_NewerSimpleUnionTable;

class NewerSimpleUnion {
 public:
  NewerSimpleUnion()
      : ordinal_(::test_union::wire::NewerSimpleUnion::Ordinal::Invalid),
        envelope_{} {}

  NewerSimpleUnion(const NewerSimpleUnion&) = default;
  NewerSimpleUnion& operator=(const NewerSimpleUnion&) = default;
  NewerSimpleUnion(NewerSimpleUnion&&) = default;
  NewerSimpleUnion& operator=(NewerSimpleUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    kV = 3,  // 0x3
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::Invalid;
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kI;
  }

  static NewerSimpleUnion WithI(::fidl::ObjectView<int64_t> val) {
    NewerSimpleUnion result;
    result.ordinal_ = ::test_union::wire::NewerSimpleUnion::Ordinal::kI;
    result.envelope_.As<int64_t>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static NewerSimpleUnion WithI(::fidl::AnyArena& allocator, Args&&... args) {
    return WithI(
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kI);
    return envelope_.As<int64_t>().get_data();
  }
  const int64_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kI);
    return envelope_.As<int64_t>().get_data();
  }

  bool is_s() const {
    return ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kS;
  }

  static NewerSimpleUnion WithS(::fidl::ObjectView<::fidl::StringView> val) {
    NewerSimpleUnion result;
    result.ordinal_ = ::test_union::wire::NewerSimpleUnion::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static NewerSimpleUnion WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_v() const {
    return ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kV;
  }

  static NewerSimpleUnion WithV(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    NewerSimpleUnion result;
    result.ordinal_ = ::test_union::wire::NewerSimpleUnion::Ordinal::kV;
    result.envelope_.As<::fidl::VectorView<::fidl::StringView>>().set_data(
        std::move(val));
    return result;
  }

  template <typename... Args>
  static NewerSimpleUnion WithV(::fidl::AnyArena& allocator, Args&&... args) {
    return WithV(::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>& v() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kV);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  const ::fidl::VectorView<::fidl::StringView>& v() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::NewerSimpleUnion::Ordinal::kV);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  ::test_union::wire::NewerSimpleUnion::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    kV = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::NewerSimpleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_FlexibleUnionTable;

class FlexibleUnion {
 public:
  FlexibleUnion()
      : ordinal_(::test_union::wire::FlexibleUnion::Ordinal::Invalid),
        envelope_{} {}

  FlexibleUnion(const FlexibleUnion&) = default;
  FlexibleUnion& operator=(const FlexibleUnion&) = default;
  FlexibleUnion(FlexibleUnion&&) = default;
  FlexibleUnion& operator=(FlexibleUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::FlexibleUnion::Ordinal::Invalid;
  }

  bool is_primitive() const {
    return ordinal_ == ::test_union::wire::FlexibleUnion::Ordinal::kPrimitive;
  }

  static FlexibleUnion WithPrimitive(int32_t val) {
    FlexibleUnion result;
    result.ordinal_ = ::test_union::wire::FlexibleUnion::Ordinal::kPrimitive;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& primitive() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FlexibleUnion::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FlexibleUnion::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }

  bool is_string_needs_constructor() const {
    return ordinal_ ==
           ::test_union::wire::FlexibleUnion::Ordinal::kStringNeedsConstructor;
  }

  static FlexibleUnion WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    FlexibleUnion result;
    result.ordinal_ =
        ::test_union::wire::FlexibleUnion::Ordinal::kStringNeedsConstructor;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static FlexibleUnion WithStringNeedsConstructor(::fidl::AnyArena& allocator,
                                                  Args&&... args) {
    return WithStringNeedsConstructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& string_needs_constructor() {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::FlexibleUnion::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::FlexibleUnion::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_vector_string_also_needs_constructor() const {
    return ordinal_ == ::test_union::wire::FlexibleUnion::Ordinal::
                           kVectorStringAlsoNeedsConstructor;
  }

  static FlexibleUnion WithVectorStringAlsoNeedsConstructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    FlexibleUnion result;
    result.ordinal_ = ::test_union::wire::FlexibleUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    result.envelope_.As<::fidl::VectorView<::fidl::StringView>>().set_data(
        std::move(val));
    return result;
  }

  template <typename... Args>
  static FlexibleUnion WithVectorStringAlsoNeedsConstructor(
      ::fidl::AnyArena& allocator, Args&&... args) {
    return WithVectorStringAlsoNeedsConstructor(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::FlexibleUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  const ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::FlexibleUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return envelope_.As<::fidl::VectorView<::fidl::StringView>>().get_data();
  }
  ::test_union::wire::FlexibleUnion::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::FlexibleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_FlexibleFooTable;

class FlexibleFoo {
 public:
  FlexibleFoo()
      : ordinal_(::test_union::wire::FlexibleFoo::Ordinal::Invalid),
        envelope_{} {}

  FlexibleFoo(const FlexibleFoo&) = default;
  FlexibleFoo& operator=(const FlexibleFoo&) = default;
  FlexibleFoo(FlexibleFoo&&) = default;
  FlexibleFoo& operator=(FlexibleFoo&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::Invalid;
  }

  bool is_s() const {
    return ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::kS;
  }

  static FlexibleFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    FlexibleFoo result;
    result.ordinal_ = ::test_union::wire::FlexibleFoo::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static FlexibleFoo WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::kI;
  }

  static FlexibleFoo WithI(int32_t val) {
    FlexibleFoo result;
    result.ordinal_ = ::test_union::wire::FlexibleFoo::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::FlexibleFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_union::wire::FlexibleFoo::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kS = 1,  // 0x1
    kI = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::FlexibleFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_FieldCollisionTable;

class FieldCollision {
 public:
  FieldCollision()
      : ordinal_(::test_union::wire::FieldCollision::Ordinal::Invalid),
        envelope_{} {}

  FieldCollision(const FieldCollision&) = default;
  FieldCollision& operator=(const FieldCollision&) = default;
  FieldCollision(FieldCollision&&) = default;
  FieldCollision& operator=(FieldCollision&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kFieldCollisionTag = 1,  // 0x1
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::FieldCollision::Ordinal::Invalid;
  }

  bool is_field_collision_tag() const {
    return ordinal_ ==
           ::test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag;
  }

  static FieldCollision WithFieldCollisionTag(int32_t val) {
    FieldCollision result;
    result.ordinal_ =
        ::test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& field_collision_tag() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& field_collision_tag() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_union::wire::FieldCollision::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::FieldCollision::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kFieldCollisionTag = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::FieldCollision::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_ExplicitXUnionTable;

class ExplicitXUnion {
 public:
  ExplicitXUnion()
      : ordinal_(::test_union::wire::ExplicitXUnion::Ordinal::Invalid),
        envelope_{} {}

  ExplicitXUnion(const ExplicitXUnion&) = default;
  ExplicitXUnion& operator=(const ExplicitXUnion&) = default;
  ExplicitXUnion(ExplicitXUnion&&) = default;
  ExplicitXUnion& operator=(ExplicitXUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 4,  // 0x4
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::Invalid;
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::kI;
  }

  static ExplicitXUnion WithI(::fidl::ObjectView<int64_t> val) {
    ExplicitXUnion result;
    result.ordinal_ = ::test_union::wire::ExplicitXUnion::Ordinal::kI;
    result.envelope_.As<int64_t>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static ExplicitXUnion WithI(::fidl::AnyArena& allocator, Args&&... args) {
    return WithI(
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::kI);
    return envelope_.As<int64_t>().get_data();
  }
  const int64_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::kI);
    return envelope_.As<int64_t>().get_data();
  }

  bool is_f() const {
    return ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::kF;
  }

  static ExplicitXUnion WithF(float val) {
    ExplicitXUnion result;
    result.ordinal_ = ::test_union::wire::ExplicitXUnion::Ordinal::kF;
    result.envelope_.As<float>().set_data(std::move(val));
    return result;
  }

  float& f() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::kF);
    return envelope_.As<float>().get_data();
  }
  const float& f() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitXUnion::Ordinal::kF);
    return envelope_.As<float>().get_data();
  }
  ::test_union::wire::ExplicitXUnion::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kI = 1,  // 0x1
    kF = 4,  // 0x4
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::ExplicitXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_ExplicitUnionTable;

class ExplicitUnion {
 public:
  ExplicitUnion()
      : ordinal_(::test_union::wire::ExplicitUnion::Ordinal::Invalid),
        envelope_{} {}

  ExplicitUnion(const ExplicitUnion&) = default;
  ExplicitUnion& operator=(const ExplicitUnion&) = default;
  ExplicitUnion(ExplicitUnion&&) = default;
  ExplicitUnion& operator=(ExplicitUnion&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,               // 0x1
    kStringNeedsConstructor = 3,  // 0x3
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::ExplicitUnion::Ordinal::Invalid;
  }

  bool is_primitive() const {
    return ordinal_ == ::test_union::wire::ExplicitUnion::Ordinal::kPrimitive;
  }

  static ExplicitUnion WithPrimitive(int32_t val) {
    ExplicitUnion result;
    result.ordinal_ = ::test_union::wire::ExplicitUnion::Ordinal::kPrimitive;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& primitive() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ExplicitUnion::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::ExplicitUnion::Ordinal::kPrimitive);
    return envelope_.As<int32_t>().get_data();
  }

  bool is_string_needs_constructor() const {
    return ordinal_ ==
           ::test_union::wire::ExplicitUnion::Ordinal::kStringNeedsConstructor;
  }

  static ExplicitUnion WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    ExplicitUnion result;
    result.ordinal_ =
        ::test_union::wire::ExplicitUnion::Ordinal::kStringNeedsConstructor;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static ExplicitUnion WithStringNeedsConstructor(::fidl::AnyArena& allocator,
                                                  Args&&... args) {
    return WithStringNeedsConstructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& string_needs_constructor() {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::ExplicitUnion::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(
        ordinal_ ==
        ::test_union::wire::ExplicitUnion::Ordinal::kStringNeedsConstructor);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  ::test_union::wire::ExplicitUnion::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::ExplicitUnion::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kPrimitive = 1,               // 0x1
    kStringNeedsConstructor = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::ExplicitUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_ExplicitStrictFooTable;

class ExplicitStrictFoo {
 public:
  ExplicitStrictFoo()
      : ordinal_(::test_union::wire::ExplicitStrictFoo::Ordinal::Invalid),
        envelope_{} {}

  ExplicitStrictFoo(const ExplicitStrictFoo&) = default;
  ExplicitStrictFoo& operator=(const ExplicitStrictFoo&) = default;
  ExplicitStrictFoo(ExplicitStrictFoo&&) = default;
  ExplicitStrictFoo& operator=(ExplicitStrictFoo&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kS = 3,  // 0x3
    kI = 2,  // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::Invalid;
  }

  bool is_s() const {
    return ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::kS;
  }

  static ExplicitStrictFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    ExplicitStrictFoo result;
    result.ordinal_ = ::test_union::wire::ExplicitStrictFoo::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static ExplicitStrictFoo WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::kI;
  }

  static ExplicitStrictFoo WithI(int32_t val) {
    ExplicitStrictFoo result;
    result.ordinal_ = ::test_union::wire::ExplicitStrictFoo::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitStrictFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_union::wire::ExplicitStrictFoo::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_union::wire::ExplicitStrictFoo::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kS = 3,  // 0x3
    kI = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::ExplicitStrictFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_ExplicitFooTable;

class ExplicitFoo {
 public:
  ExplicitFoo()
      : ordinal_(::test_union::wire::ExplicitFoo::Ordinal::Invalid),
        envelope_{} {}

  ExplicitFoo(const ExplicitFoo&) = default;
  ExplicitFoo& operator=(const ExplicitFoo&) = default;
  ExplicitFoo(ExplicitFoo&&) = default;
  ExplicitFoo& operator=(ExplicitFoo&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kS = 2,  // 0x2
    kI = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::Invalid;
  }

  bool is_s() const {
    return ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::kS;
  }

  static ExplicitFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    ExplicitFoo result;
    result.ordinal_ = ::test_union::wire::ExplicitFoo::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static ExplicitFoo WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_i() const {
    return ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::kI;
  }

  static ExplicitFoo WithI(int32_t val) {
    ExplicitFoo result;
    result.ordinal_ = ::test_union::wire::ExplicitFoo::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::test_union::wire::ExplicitFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_union::wire::ExplicitFoo::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kS = 2,  // 0x2
    kI = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::ExplicitFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_XUnionContainingEmptyStructTable;

class XUnionContainingEmptyStruct {
 public:
  XUnionContainingEmptyStruct()
      : ordinal_(
            ::test_union::wire::XUnionContainingEmptyStruct::Ordinal::Invalid),
        envelope_{} {}

  XUnionContainingEmptyStruct(const XUnionContainingEmptyStruct&) = default;
  XUnionContainingEmptyStruct& operator=(const XUnionContainingEmptyStruct&) =
      default;
  XUnionContainingEmptyStruct(XUnionContainingEmptyStruct&&) = default;
  XUnionContainingEmptyStruct& operator=(XUnionContainingEmptyStruct&&) =
      default;

  enum class Tag : fidl_xunion_tag_t {
    kEmpty = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_union::wire::XUnionContainingEmptyStruct::Ordinal::Invalid;
  }

  bool is_empty() const {
    return ordinal_ ==
           ::test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty;
  }

  static XUnionContainingEmptyStruct WithEmpty(::test_union::wire::Empty val) {
    XUnionContainingEmptyStruct result;
    result.ordinal_ =
        ::test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty;
    result.envelope_.As<::test_union::wire::Empty>().set_data(std::move(val));
    return result;
  }

  ::test_union::wire::Empty& empty() {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty);
    return envelope_.As<::test_union::wire::Empty>().get_data();
  }
  const ::test_union::wire::Empty& empty() const {
    ZX_ASSERT(ordinal_ ==
              ::test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty);
    return envelope_.As<::test_union::wire::Empty>().get_data();
  }
  ::test_union::wire::XUnionContainingEmptyStruct::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kEmpty = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_union::wire::XUnionContainingEmptyStruct::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_union_StructWithNullableXUnionTable;

struct StructWithNullableXUnion {
  ::test_union::wire::OlderSimpleUnion x1 = {};
};

extern "C" const fidl_type_t
    test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;

struct TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse {
  ::test_union::wire::StrictBoundedXUnion xu = {};
};

extern "C" const fidl_type_t test_union_PizzaTable;

struct Pizza {
  ::fidl::VectorView<::fidl::StringView> toppings = {};
};

extern "C" const fidl_type_t test_union_PastaTable;

struct Pasta {
  ::fidl::StringView sauce = {};
};

extern "C" const fidl_type_t
    test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;

struct TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse {
  ::test_union::wire::OlderSimpleUnion xu = {};
};

extern "C" const fidl_type_t test_union_NullableUnionStructTable;

struct NullableUnionStruct {
  ::test_union::wire::Union the_union = {};
};

extern "C" const fidl_type_t test_union_UnionSandwichTable;

struct UnionSandwich {
  uint32_t a = {};

  ::test_union::wire::ExplicitXUnion u = {};

  uint32_t b = {};
};

}  // namespace wire
}  // namespace test_union
namespace fidl {

template <>
struct TypeTraits<::test_union::wire::StructWithNullableXUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_StructWithNullableXUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::StructWithNullableXUnion>
    : public std::true_type {};
template <>
struct IsStruct<::test_union::wire::StructWithNullableXUnion>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::StructWithNullableXUnion>);
static_assert(offsetof(::test_union::wire::StructWithNullableXUnion, x1) == 0);
static_assert(
    sizeof(::test_union::wire::StructWithNullableXUnion) ==
    TypeTraits<::test_union::wire::StructWithNullableXUnion>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_union::wire::
        TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::
          test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 32;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_union::wire::
        TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_union::wire::
        TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_union::wire::
            TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>);
static_assert(
    offsetof(
        ::test_union::wire::
            TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse,
        xu) == 0);
static_assert(
    sizeof(
        ::test_union::wire::
            TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse) ==
    TypeTraits<
        ::test_union::wire::
            TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>::
        kPrimarySize);

template <>
struct TypeTraits<::test_union::wire::Pizza> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_PizzaTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::Pizza> : public std::true_type {};
template <>
struct IsStruct<::test_union::wire::Pizza> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::Pizza>);
static_assert(offsetof(::test_union::wire::Pizza, toppings) == 0);
static_assert(sizeof(::test_union::wire::Pizza) ==
              TypeTraits<::test_union::wire::Pizza>::kPrimarySize);

template <>
struct TypeTraits<::test_union::wire::Pasta> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_PastaTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 16;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::Pasta> : public std::true_type {};
template <>
struct IsStruct<::test_union::wire::Pasta> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::Pasta>);
static_assert(offsetof(::test_union::wire::Pasta, sauce) == 0);
static_assert(sizeof(::test_union::wire::Pasta) ==
              TypeTraits<::test_union::wire::Pasta>::kPrimarySize);

template <>
struct TypeTraits<
    ::test_union::wire::
        TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::
          test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<
    ::test_union::wire::
        TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<
    ::test_union::wire::
        TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::test_union::wire::
            TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>);
static_assert(
    offsetof(
        ::test_union::wire::
            TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse,
        xu) == 0);
static_assert(
    sizeof(
        ::test_union::wire::
            TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse) ==
    TypeTraits<
        ::test_union::wire::
            TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>::
        kPrimarySize);

template <>
struct TypeTraits<::test_union::wire::NullableUnionStruct> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_NullableUnionStructTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::NullableUnionStruct>
    : public std::true_type {};
template <>
struct IsStruct<::test_union::wire::NullableUnionStruct>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::NullableUnionStruct>);
static_assert(offsetof(::test_union::wire::NullableUnionStruct, the_union) ==
              0);
static_assert(
    sizeof(::test_union::wire::NullableUnionStruct) ==
    TypeTraits<::test_union::wire::NullableUnionStruct>::kPrimarySize);

template <>
struct TypeTraits<::test_union::wire::UnionSandwich> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_UnionSandwichTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 32;
  static constexpr uint32_t kPrimarySizeV1 = 40;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::UnionSandwich> : public std::true_type {};
template <>
struct IsStruct<::test_union::wire::UnionSandwich> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::UnionSandwich>);
static_assert(offsetof(::test_union::wire::UnionSandwich, a) == 0);
static_assert(offsetof(::test_union::wire::UnionSandwich, u) == 8);
static_assert(offsetof(::test_union::wire::UnionSandwich, b) == 24);
static_assert(sizeof(::test_union::wire::UnionSandwich) ==
              TypeTraits<::test_union::wire::UnionSandwich>::kPrimarySize);

template <>
struct TypeTraits<::test_union::wire::Empty> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_EmptyTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 1;
  static constexpr uint32_t kPrimarySizeV1 = 1;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_union::wire::Empty> : public std::true_type {};
template <>
struct IsStruct<::test_union::wire::Empty> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::Empty>);
static_assert(offsetof(::test_union::wire::Empty, __reserved) == 0);
static_assert(sizeof(::test_union::wire::Empty) ==
              TypeTraits<::test_union::wire::Empty>::kPrimarySize);

template <>
struct TypeTraits<::test_union::wire::UnionWithAttributes> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_UnionWithAttributesTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::UnionWithAttributes>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::UnionWithAttributes>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::UnionWithAttributes>);

template <>
struct TypeTraits<::test_union::wire::Union> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_UnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::Union> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::Union> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::Union>);

template <>
struct TypeTraits<::test_union::wire::StrictUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_StrictUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::StrictUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::StrictUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::StrictUnion>);

template <>
struct TypeTraits<::test_union::wire::StrictSimpleXUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_StrictSimpleXUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::StrictSimpleXUnion>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::StrictSimpleXUnion> : public std::true_type {
};
static_assert(
    std::is_standard_layout_v<::test_union::wire::StrictSimpleXUnion>);

template <>
struct TypeTraits<::test_union::wire::StrictFoo> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_StrictFooTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::StrictFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::StrictFoo> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::StrictFoo>);

template <>
struct TypeTraits<::test_union::wire::StrictBoundedXUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_StrictBoundedXUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 32;
  static constexpr uint32_t kMaxOutOfLineV1 = 32;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::StrictBoundedXUnion>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::StrictBoundedXUnion>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::StrictBoundedXUnion>);

template <>
struct TypeTraits<::test_union::wire::ReverseOrdinalUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_ReverseOrdinalUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::ReverseOrdinalUnion>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::ReverseOrdinalUnion>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::ReverseOrdinalUnion>);

template <>
struct TypeTraits<::test_union::wire::StrictPizzaOrPasta> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_StrictPizzaOrPastaTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::StrictPizzaOrPasta>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::StrictPizzaOrPasta> : public std::true_type {
};
static_assert(
    std::is_standard_layout_v<::test_union::wire::StrictPizzaOrPasta>);

template <>
struct TypeTraits<::test_union::wire::PizzaOrPasta> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_PizzaOrPastaTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::PizzaOrPasta> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::PizzaOrPasta> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::PizzaOrPasta>);

template <>
struct TypeTraits<::test_union::wire::FlexiblePizzaOrPasta> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_FlexiblePizzaOrPastaTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::FlexiblePizzaOrPasta>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::FlexiblePizzaOrPasta>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::FlexiblePizzaOrPasta>);

template <>
struct TypeTraits<::test_union::wire::ExplicitPizzaOrPasta> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_ExplicitPizzaOrPastaTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::ExplicitPizzaOrPasta>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::ExplicitPizzaOrPasta>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::ExplicitPizzaOrPasta>);

template <>
struct TypeTraits<::test_union::wire::OlderSimpleUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_OlderSimpleUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::OlderSimpleUnion>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::OlderSimpleUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::OlderSimpleUnion>);

template <>
struct TypeTraits<::test_union::wire::NewerSimpleUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_NewerSimpleUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::NewerSimpleUnion>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::NewerSimpleUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::NewerSimpleUnion>);

template <>
struct TypeTraits<::test_union::wire::FlexibleUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_FlexibleUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::FlexibleUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::FlexibleUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::FlexibleUnion>);

template <>
struct TypeTraits<::test_union::wire::FlexibleFoo> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_FlexibleFooTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::FlexibleFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::FlexibleFoo> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::FlexibleFoo>);

template <>
struct TypeTraits<::test_union::wire::FieldCollision> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_FieldCollisionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::FieldCollision> : public std::true_type {
};
template <>
struct IsUnion<::test_union::wire::FieldCollision> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::FieldCollision>);

template <>
struct TypeTraits<::test_union::wire::ExplicitXUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_ExplicitXUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::ExplicitXUnion> : public std::true_type {
};
template <>
struct IsUnion<::test_union::wire::ExplicitXUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::ExplicitXUnion>);

template <>
struct TypeTraits<::test_union::wire::ExplicitUnion> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_ExplicitUnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::ExplicitUnion> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::ExplicitUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::ExplicitUnion>);

template <>
struct TypeTraits<::test_union::wire::ExplicitStrictFoo> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_ExplicitStrictFooTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::ExplicitStrictFoo>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::ExplicitStrictFoo> : public std::true_type {
};
static_assert(std::is_standard_layout_v<::test_union::wire::ExplicitStrictFoo>);

template <>
struct TypeTraits<::test_union::wire::ExplicitFoo> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_ExplicitFooTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::ExplicitFoo> : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::ExplicitFoo> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_union::wire::ExplicitFoo>);

template <>
struct TypeTraits<::test_union::wire::XUnionContainingEmptyStruct> {
  static constexpr const fidl_type_t* kType =
      &::test_union::wire::test_union_XUnionContainingEmptyStructTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_union::wire::XUnionContainingEmptyStruct>
    : public std::true_type {};
template <>
struct IsUnion<::test_union::wire::XUnionContainingEmptyStruct>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_union::wire::XUnionContainingEmptyStruct>);

}  // namespace fidl
