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

#pragma once

#include <lib/fidl/internal.h>
#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.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/vector_view.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>

#include <algorithm>
#include <cstddef>
#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/fidl/llcpp/wire_messaging.h>
#include <lib/fidl/txn_header.h>
#include <lib/zx/channel.h>

#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace fidl_test_union {
namespace wire {
class Union;

struct StructWithNullableXUnion;

class StrictUnion;

class StrictSimpleXUnion;

class StrictFoo;

class StrictBoundedXUnion;

class ReverseOrdinalUnion;

struct Pizza;

struct Pasta;

class StrictPizzaOrPasta;

class PizzaOrPasta;

class FlexiblePizzaOrPasta;

class ExplicitPizzaOrPasta;

class OlderSimpleUnion;
}  // namespace wire
class TestProtocol;
namespace wire {
struct NullableUnionStruct;

class NewerSimpleUnion;

class FlexibleUnion;

class FlexibleFoo;

class FieldCollision;

class ExplicitXUnion;

class ExplicitUnion;

class ExplicitStrictFoo;

class ExplicitFoo;

struct Empty;

class XUnionContainingEmptyStruct;

extern "C" const fidl_type_t fidl_test_union_UnionTable;

class Union {
 public:
  Union()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::Union::Ordinal::Invalid;
  }

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

  static Union WithPrimitive(::fidl::ObjectView<int32_t> val) {
    Union result;
    result.set_primitive(val);
    return result;
  }

  template <typename... Args>
  static Union WithPrimitive(::fidl::AnyAllocator& allocator, Args&&... args) {
    Union result;
    result.set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_primitive(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::Union::Ordinal::kPrimitive;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_primitive(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::Union::Ordinal::kPrimitive;
    set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_primitive() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::Union::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::Union::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }

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

  static Union WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    Union result;
    result.set_string_needs_constructor(val);
    return result;
  }

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

  void set_string_needs_constructor(
      ::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::Union::Ordinal::kStringNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_string_needs_constructor(::fidl::AnyAllocator& allocator,
                                    Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::Union::Ordinal::kStringNeedsConstructor;
    set_string_needs_constructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_string_needs_constructor() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::Union::Ordinal::kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::Union::Ordinal::kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static Union WithVectorStringAlsoNeedsConstructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    Union result;
    result.set_vector_string_also_needs_constructor(val);
    return result;
  }

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

  void set_vector_string_also_needs_constructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> elem) {
    ordinal_ = ::fidl_test_union::wire::Union::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_vector_string_also_needs_constructor(::fidl::AnyAllocator& allocator,
                                                Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::Union::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    set_vector_string_also_needs_constructor(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>&
  mutable_vector_string_also_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::Union::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  const ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::Union::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  ::fidl_test_union::wire::Union::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::Union::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type = &fidl_test_union_UnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::Union::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_StrictUnionTable;

class StrictUnion {
 public:
  StrictUnion()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::StrictUnion::Ordinal::Invalid;
  }

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

  static StrictUnion WithPrimitive(::fidl::ObjectView<int32_t> val) {
    StrictUnion result;
    result.set_primitive(val);
    return result;
  }

  template <typename... Args>
  static StrictUnion WithPrimitive(::fidl::AnyAllocator& allocator,
                                   Args&&... args) {
    StrictUnion result;
    result.set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_primitive(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictUnion::Ordinal::kPrimitive;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_primitive(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictUnion::Ordinal::kPrimitive;
    set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_primitive() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictUnion::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictUnion::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }

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

  static StrictUnion WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    StrictUnion result;
    result.set_string_needs_constructor(val);
    return result;
  }

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

  void set_string_needs_constructor(
      ::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ =
        ::fidl_test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_string_needs_constructor(::fidl::AnyAllocator& allocator,
                                    Args&&... args) {
    ordinal_ =
        ::fidl_test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor;
    set_string_needs_constructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_string_needs_constructor() {
    ZX_ASSERT(
        ordinal_ ==
        ::fidl_test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(
        ordinal_ ==
        ::fidl_test_union::wire::StrictUnion::Ordinal::kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static StrictUnion WithVectorStringAlsoNeedsConstructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    StrictUnion result;
    result.set_vector_string_also_needs_constructor(val);
    return result;
  }

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

  void set_vector_string_also_needs_constructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_vector_string_also_needs_constructor(::fidl::AnyAllocator& allocator,
                                                Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    set_vector_string_also_needs_constructor(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>&
  mutable_vector_string_also_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::StrictUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  const ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::StrictUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  ::fidl_test_union::wire::StrictUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::StrictUnion::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type = &fidl_test_union_StrictUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::StrictUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_StrictSimpleXUnionTable;

class StrictSimpleXUnion {
 public:
  StrictSimpleXUnion()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::Invalid;
  }

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

  static StrictSimpleXUnion WithI(::fidl::ObjectView<int32_t> val) {
    StrictSimpleXUnion result;
    result.set_i(val);
    return result;
  }

  template <typename... Args>
  static StrictSimpleXUnion WithI(::fidl::AnyAllocator& allocator,
                                  Args&&... args) {
    StrictSimpleXUnion result;
    result.set_i(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_i(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kI;
    set_i(::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_i() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }

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

  static StrictSimpleXUnion WithF(::fidl::ObjectView<float> val) {
    StrictSimpleXUnion result;
    result.set_f(val);
    return result;
  }

  template <typename... Args>
  static StrictSimpleXUnion WithF(::fidl::AnyAllocator& allocator,
                                  Args&&... args) {
    StrictSimpleXUnion result;
    result.set_f(
        ::fidl::ObjectView<float>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_f(::fidl::ObjectView<float> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kF;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_f(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kF;
    set_f(::fidl::ObjectView<float>(allocator, std::forward<Args>(args)...));
  }

  float& mutable_f() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kF);
    return *static_cast<float*>(envelope_.data.get());
  }
  const float& f() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kF);
    return *static_cast<float*>(envelope_.data.get());
  }

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

  static StrictSimpleXUnion WithS(::fidl::ObjectView<::fidl::StringView> val) {
    StrictSimpleXUnion result;
    result.set_s(val);
    return result;
  }

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

  void set_s(::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kS;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_s(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kS;
    set_s(::fidl::ObjectView<::fidl::StringView>(allocator,
                                                 std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_s() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::StrictSimpleXUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::StrictSimpleXUnion::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_StrictSimpleXUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::StrictSimpleXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_StrictFooTable;

class StrictFoo {
 public:
  StrictFoo()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::StrictFoo::Ordinal::Invalid;
  }

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

  static StrictFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    StrictFoo result;
    result.set_s(val);
    return result;
  }

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

  void set_s(::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictFoo::Ordinal::kS;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_s(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictFoo::Ordinal::kS;
    set_s(::fidl::ObjectView<::fidl::StringView>(allocator,
                                                 std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_s() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::StrictFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::StrictFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static StrictFoo WithI(::fidl::ObjectView<int32_t> val) {
    StrictFoo result;
    result.set_i(val);
    return result;
  }

  template <typename... Args>
  static StrictFoo WithI(::fidl::AnyAllocator& allocator, Args&&... args) {
    StrictFoo result;
    result.set_i(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_i(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictFoo::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictFoo::Ordinal::kI;
    set_i(::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_i() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::StrictFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::StrictFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::StrictFoo::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::StrictFoo::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type = &fidl_test_union_StrictFooTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::StrictFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_StrictBoundedXUnionTable;

class StrictBoundedXUnion {
 public:
  StrictBoundedXUnion()
      : ordinal_(
            ::fidl_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_ ==
           ::fidl_test_union::wire::StrictBoundedXUnion::Ordinal::Invalid;
  }

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

  static StrictBoundedXUnion WithV(
      ::fidl::ObjectView<::fidl::VectorView<uint8_t>> val) {
    StrictBoundedXUnion result;
    result.set_v(val);
    return result;
  }

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

  void set_v(::fidl::ObjectView<::fidl::VectorView<uint8_t>> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictBoundedXUnion::Ordinal::kV;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_v(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictBoundedXUnion::Ordinal::kV;
    set_v(::fidl::ObjectView<::fidl::VectorView<uint8_t>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<uint8_t>& mutable_v() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictBoundedXUnion::Ordinal::kV);
    return *static_cast<::fidl::VectorView<uint8_t>*>(envelope_.data.get());
  }
  const ::fidl::VectorView<uint8_t>& v() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictBoundedXUnion::Ordinal::kV);
    return *static_cast<::fidl::VectorView<uint8_t>*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::StrictBoundedXUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::StrictBoundedXUnion::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_StrictBoundedXUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 32;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::StrictBoundedXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_ReverseOrdinalUnionTable;

class ReverseOrdinalUnion {
 public:
  ReverseOrdinalUnion()
      : ordinal_(
            ::fidl_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_ ==
           ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::Invalid;
  }

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

  static ReverseOrdinalUnion WithSecond(::fidl::ObjectView<uint32_t> val) {
    ReverseOrdinalUnion result;
    result.set_second(val);
    return result;
  }

  template <typename... Args>
  static ReverseOrdinalUnion WithSecond(::fidl::AnyAllocator& allocator,
                                        Args&&... args) {
    ReverseOrdinalUnion result;
    result.set_second(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_second(::fidl::ObjectView<uint32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_second(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond;
    set_second(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

  uint32_t& mutable_second() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& second() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kSecond);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }

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

  static ReverseOrdinalUnion WithFirst(::fidl::ObjectView<uint32_t> val) {
    ReverseOrdinalUnion result;
    result.set_first(val);
    return result;
  }

  template <typename... Args>
  static ReverseOrdinalUnion WithFirst(::fidl::AnyAllocator& allocator,
                                       Args&&... args) {
    ReverseOrdinalUnion result;
    result.set_first(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_first(::fidl::ObjectView<uint32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_first(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst;
    set_first(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

  uint32_t& mutable_first() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& first() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal::kFirst);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::ReverseOrdinalUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::ReverseOrdinalUnion::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_ReverseOrdinalUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::ReverseOrdinalUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_StrictPizzaOrPastaTable;

class StrictPizzaOrPasta {
 public:
  StrictPizzaOrPasta()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::Invalid;
  }

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

  static StrictPizzaOrPasta WithPizza(
      ::fidl::ObjectView<::fidl_test_union::wire::Pizza> val) {
    StrictPizzaOrPasta result;
    result.set_pizza(val);
    return result;
  }

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

  void set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pizza(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza;
    set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pizza& mutable_pizza() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }

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

  static StrictPizzaOrPasta WithPasta(
      ::fidl::ObjectView<::fidl_test_union::wire::Pasta> val) {
    StrictPizzaOrPasta result;
    result.set_pasta(val);
    return result;
  }

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

  void set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta> elem) {
    ordinal_ = ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pasta(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta;
    set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pasta& mutable_pasta() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::StrictPizzaOrPasta::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::StrictPizzaOrPasta::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_StrictPizzaOrPastaTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::StrictPizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_PizzaOrPastaTable;

class PizzaOrPasta {
 public:
  PizzaOrPasta()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::PizzaOrPasta::Ordinal::Invalid;
  }

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

  static PizzaOrPasta WithPizza(
      ::fidl::ObjectView<::fidl_test_union::wire::Pizza> val) {
    PizzaOrPasta result;
    result.set_pizza(val);
    return result;
  }

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

  void set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza> elem) {
    ordinal_ = ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPizza;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pizza(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPizza;
    set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pizza& mutable_pizza() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }

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

  static PizzaOrPasta WithPasta(
      ::fidl::ObjectView<::fidl_test_union::wire::Pasta> val) {
    PizzaOrPasta result;
    result.set_pasta(val);
    return result;
  }

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

  void set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta> elem) {
    ordinal_ = ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPasta;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pasta(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPasta;
    set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pasta& mutable_pasta() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::PizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::PizzaOrPasta::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::PizzaOrPasta::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type = &fidl_test_union_PizzaOrPastaTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::PizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_FlexiblePizzaOrPastaTable;

class FlexiblePizzaOrPasta {
 public:
  FlexiblePizzaOrPasta()
      : ordinal_(
            ::fidl_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_ ==
           ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::Invalid;
  }

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

  static FlexiblePizzaOrPasta WithPizza(
      ::fidl::ObjectView<::fidl_test_union::wire::Pizza> val) {
    FlexiblePizzaOrPasta result;
    result.set_pizza(val);
    return result;
  }

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

  void set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pizza(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza;
    set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pizza& mutable_pizza() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }

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

  static FlexiblePizzaOrPasta WithPasta(
      ::fidl::ObjectView<::fidl_test_union::wire::Pasta> val) {
    FlexiblePizzaOrPasta result;
    result.set_pasta(val);
    return result;
  }

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

  void set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pasta(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta;
    set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pasta& mutable_pasta() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::FlexiblePizzaOrPasta::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_FlexiblePizzaOrPastaTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::FlexiblePizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_ExplicitPizzaOrPastaTable;

class ExplicitPizzaOrPasta {
 public:
  ExplicitPizzaOrPasta()
      : ordinal_(
            ::fidl_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_ ==
           ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::Invalid;
  }

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

  static ExplicitPizzaOrPasta WithPizza(
      ::fidl::ObjectView<::fidl_test_union::wire::Pizza> val) {
    ExplicitPizzaOrPasta result;
    result.set_pizza(val);
    return result;
  }

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

  void set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pizza(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza;
    set_pizza(::fidl::ObjectView<::fidl_test_union::wire::Pizza>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pizza& mutable_pizza() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pizza& pizza() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPizza);
    return *static_cast<::fidl_test_union::wire::Pizza*>(envelope_.data.get());
  }

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

  static ExplicitPizzaOrPasta WithPasta(
      ::fidl::ObjectView<::fidl_test_union::wire::Pasta> val) {
    ExplicitPizzaOrPasta result;
    result.set_pasta(val);
    return result;
  }

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

  void set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_pasta(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta;
    set_pasta(::fidl::ObjectView<::fidl_test_union::wire::Pasta>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Pasta& mutable_pasta() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Pasta& pasta() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal::kPasta);
    return *static_cast<::fidl_test_union::wire::Pasta*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::ExplicitPizzaOrPasta::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::ExplicitPizzaOrPasta::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_ExplicitPizzaOrPastaTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::ExplicitPizzaOrPasta::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_OlderSimpleUnionTable;

class OlderSimpleUnion {
 public:
  OlderSimpleUnion()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::Invalid;
  }

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

  static OlderSimpleUnion WithI(::fidl::ObjectView<int64_t> val) {
    OlderSimpleUnion result;
    result.set_i(val);
    return result;
  }

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

  void set_i(::fidl::ObjectView<int64_t> elem) {
    ordinal_ = ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kI;
    set_i(::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& mutable_i() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kI);
    return *static_cast<int64_t*>(envelope_.data.get());
  }
  const int64_t& i() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kI);
    return *static_cast<int64_t*>(envelope_.data.get());
  }

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

  static OlderSimpleUnion WithF(::fidl::ObjectView<float> val) {
    OlderSimpleUnion result;
    result.set_f(val);
    return result;
  }

  template <typename... Args>
  static OlderSimpleUnion WithF(::fidl::AnyAllocator& allocator,
                                Args&&... args) {
    OlderSimpleUnion result;
    result.set_f(
        ::fidl::ObjectView<float>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_f(::fidl::ObjectView<float> elem) {
    ordinal_ = ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kF;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_f(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kF;
    set_f(::fidl::ObjectView<float>(allocator, std::forward<Args>(args)...));
  }

  float& mutable_f() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kF);
    return *static_cast<float*>(envelope_.data.get());
  }
  const float& f() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::OlderSimpleUnion::Ordinal::kF);
    return *static_cast<float*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::OlderSimpleUnion::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_OlderSimpleUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::OlderSimpleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_NewerSimpleUnionTable;

class NewerSimpleUnion {
 public:
  NewerSimpleUnion()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::Invalid;
  }

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

  static NewerSimpleUnion WithI(::fidl::ObjectView<int64_t> val) {
    NewerSimpleUnion result;
    result.set_i(val);
    return result;
  }

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

  void set_i(::fidl::ObjectView<int64_t> elem) {
    ordinal_ = ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kI;
    set_i(::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& mutable_i() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kI);
    return *static_cast<int64_t*>(envelope_.data.get());
  }
  const int64_t& i() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kI);
    return *static_cast<int64_t*>(envelope_.data.get());
  }

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

  static NewerSimpleUnion WithS(::fidl::ObjectView<::fidl::StringView> val) {
    NewerSimpleUnion result;
    result.set_s(val);
    return result;
  }

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

  void set_s(::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kS;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_s(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kS;
    set_s(::fidl::ObjectView<::fidl::StringView>(allocator,
                                                 std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_s() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static NewerSimpleUnion WithV(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    NewerSimpleUnion result;
    result.set_v(val);
    return result;
  }

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

  void set_v(::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> elem) {
    ordinal_ = ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kV;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_v(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kV;
    set_v(::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>& mutable_v() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kV);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  const ::fidl::VectorView<::fidl::StringView>& v() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::NewerSimpleUnion::Ordinal::kV);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  ::fidl_test_union::wire::NewerSimpleUnion::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_NewerSimpleUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::NewerSimpleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_FlexibleUnionTable;

class FlexibleUnion {
 public:
  FlexibleUnion()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::FlexibleUnion::Ordinal::Invalid;
  }

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

  static FlexibleUnion WithPrimitive(::fidl::ObjectView<int32_t> val) {
    FlexibleUnion result;
    result.set_primitive(val);
    return result;
  }

  template <typename... Args>
  static FlexibleUnion WithPrimitive(::fidl::AnyAllocator& allocator,
                                     Args&&... args) {
    FlexibleUnion result;
    result.set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_primitive(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexibleUnion::Ordinal::kPrimitive;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_primitive(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexibleUnion::Ordinal::kPrimitive;
    set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_primitive() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::FlexibleUnion::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::FlexibleUnion::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }

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

  static FlexibleUnion WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    FlexibleUnion result;
    result.set_string_needs_constructor(val);
    return result;
  }

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

  void set_string_needs_constructor(
      ::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexibleUnion::Ordinal::
        kStringNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_string_needs_constructor(::fidl::AnyAllocator& allocator,
                                    Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexibleUnion::Ordinal::
        kStringNeedsConstructor;
    set_string_needs_constructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_string_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleUnion::Ordinal::
                              kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleUnion::Ordinal::
                              kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static FlexibleUnion WithVectorStringAlsoNeedsConstructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> val) {
    FlexibleUnion result;
    result.set_vector_string_also_needs_constructor(val);
    return result;
  }

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

  void set_vector_string_also_needs_constructor(
      ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexibleUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_vector_string_also_needs_constructor(::fidl::AnyAllocator& allocator,
                                                Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexibleUnion::Ordinal::
        kVectorStringAlsoNeedsConstructor;
    set_vector_string_also_needs_constructor(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::StringView>>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl::VectorView<::fidl::StringView>&
  mutable_vector_string_also_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  const ::fidl::VectorView<::fidl::StringView>&
  vector_string_also_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleUnion::Ordinal::
                              kVectorStringAlsoNeedsConstructor);
    return *static_cast<::fidl::VectorView<::fidl::StringView>*>(
        envelope_.data.get());
  }
  ::fidl_test_union::wire::FlexibleUnion::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_FlexibleUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::FlexibleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_FlexibleFooTable;

class FlexibleFoo {
 public:
  FlexibleFoo()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::FlexibleFoo::Ordinal::Invalid;
  }

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

  static FlexibleFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    FlexibleFoo result;
    result.set_s(val);
    return result;
  }

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

  void set_s(::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexibleFoo::Ordinal::kS;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_s(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexibleFoo::Ordinal::kS;
    set_s(::fidl::ObjectView<::fidl::StringView>(allocator,
                                                 std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_s() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static FlexibleFoo WithI(::fidl::ObjectView<int32_t> val) {
    FlexibleFoo result;
    result.set_i(val);
    return result;
  }

  template <typename... Args>
  static FlexibleFoo WithI(::fidl::AnyAllocator& allocator, Args&&... args) {
    FlexibleFoo result;
    result.set_i(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_i(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::FlexibleFoo::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::FlexibleFoo::Ordinal::kI;
    set_i(::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_i() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::FlexibleFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::FlexibleFoo::Tag which() const;

  static constexpr const fidl_type_t* Type = &fidl_test_union_FlexibleFooTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::FlexibleFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_FieldCollisionTable;

class FieldCollision {
 public:
  FieldCollision()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::FieldCollision::Ordinal::Invalid;
  }

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

  static FieldCollision WithFieldCollisionTag(::fidl::ObjectView<int32_t> val) {
    FieldCollision result;
    result.set_field_collision_tag(val);
    return result;
  }

  template <typename... Args>
  static FieldCollision WithFieldCollisionTag(::fidl::AnyAllocator& allocator,
                                              Args&&... args) {
    FieldCollision result;
    result.set_field_collision_tag(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_field_collision_tag(::fidl::ObjectView<int32_t> elem) {
    ordinal_ =
        ::fidl_test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_field_collision_tag(::fidl::AnyAllocator& allocator,
                               Args&&... args) {
    ordinal_ =
        ::fidl_test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag;
    set_field_collision_tag(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_field_collision_tag() {
    ZX_ASSERT(
        ordinal_ ==
        ::fidl_test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& field_collision_tag() const {
    ZX_ASSERT(
        ordinal_ ==
        ::fidl_test_union::wire::FieldCollision::Ordinal::kFieldCollisionTag);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::FieldCollision::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::FieldCollision::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_FieldCollisionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::FieldCollision::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_ExplicitXUnionTable;

class ExplicitXUnion {
 public:
  ExplicitXUnion()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::ExplicitXUnion::Ordinal::Invalid;
  }

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

  static ExplicitXUnion WithI(::fidl::ObjectView<int64_t> val) {
    ExplicitXUnion result;
    result.set_i(val);
    return result;
  }

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

  void set_i(::fidl::ObjectView<int64_t> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kI;
    set_i(::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...));
  }

  int64_t& mutable_i() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kI);
    return *static_cast<int64_t*>(envelope_.data.get());
  }
  const int64_t& i() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kI);
    return *static_cast<int64_t*>(envelope_.data.get());
  }

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

  static ExplicitXUnion WithF(::fidl::ObjectView<float> val) {
    ExplicitXUnion result;
    result.set_f(val);
    return result;
  }

  template <typename... Args>
  static ExplicitXUnion WithF(::fidl::AnyAllocator& allocator, Args&&... args) {
    ExplicitXUnion result;
    result.set_f(
        ::fidl::ObjectView<float>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_f(::fidl::ObjectView<float> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kF;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_f(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kF;
    set_f(::fidl::ObjectView<float>(allocator, std::forward<Args>(args)...));
  }

  float& mutable_f() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kF);
    return *static_cast<float*>(envelope_.data.get());
  }
  const float& f() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitXUnion::Ordinal::kF);
    return *static_cast<float*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::ExplicitXUnion::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_ExplicitXUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::ExplicitXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_ExplicitUnionTable;

class ExplicitUnion {
 public:
  ExplicitUnion()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::ExplicitUnion::Ordinal::Invalid;
  }

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

  static ExplicitUnion WithPrimitive(::fidl::ObjectView<int32_t> val) {
    ExplicitUnion result;
    result.set_primitive(val);
    return result;
  }

  template <typename... Args>
  static ExplicitUnion WithPrimitive(::fidl::AnyAllocator& allocator,
                                     Args&&... args) {
    ExplicitUnion result;
    result.set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_primitive(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitUnion::Ordinal::kPrimitive;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_primitive(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitUnion::Ordinal::kPrimitive;
    set_primitive(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_primitive() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitUnion::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& primitive() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitUnion::Ordinal::kPrimitive);
    return *static_cast<int32_t*>(envelope_.data.get());
  }

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

  static ExplicitUnion WithStringNeedsConstructor(
      ::fidl::ObjectView<::fidl::StringView> val) {
    ExplicitUnion result;
    result.set_string_needs_constructor(val);
    return result;
  }

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

  void set_string_needs_constructor(
      ::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitUnion::Ordinal::
        kStringNeedsConstructor;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_string_needs_constructor(::fidl::AnyAllocator& allocator,
                                    Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitUnion::Ordinal::
        kStringNeedsConstructor;
    set_string_needs_constructor(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_string_needs_constructor() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitUnion::Ordinal::
                              kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& string_needs_constructor() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitUnion::Ordinal::
                              kStringNeedsConstructor);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::ExplicitUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::ExplicitUnion::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_ExplicitUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::ExplicitUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_ExplicitStrictFooTable;

class ExplicitStrictFoo {
 public:
  ExplicitStrictFoo()
      : ordinal_(::fidl_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_ ==
           ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::Invalid;
  }

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

  static ExplicitStrictFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    ExplicitStrictFoo result;
    result.set_s(val);
    return result;
  }

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

  void set_s(::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kS;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_s(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kS;
    set_s(::fidl::ObjectView<::fidl::StringView>(allocator,
                                                 std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_s() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static ExplicitStrictFoo WithI(::fidl::ObjectView<int32_t> val) {
    ExplicitStrictFoo result;
    result.set_i(val);
    return result;
  }

  template <typename... Args>
  static ExplicitStrictFoo WithI(::fidl::AnyAllocator& allocator,
                                 Args&&... args) {
    ExplicitStrictFoo result;
    result.set_i(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_i(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kI;
    set_i(::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_i() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::ExplicitStrictFoo::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_union::wire::ExplicitStrictFoo::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_ExplicitStrictFooTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::ExplicitStrictFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_ExplicitFooTable;

class ExplicitFoo {
 public:
  ExplicitFoo()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::ExplicitFoo::Ordinal::Invalid;
  }

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

  static ExplicitFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    ExplicitFoo result;
    result.set_s(val);
    return result;
  }

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

  void set_s(::fidl::ObjectView<::fidl::StringView> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitFoo::Ordinal::kS;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_s(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitFoo::Ordinal::kS;
    set_s(::fidl::ObjectView<::fidl::StringView>(allocator,
                                                 std::forward<Args>(args)...));
  }

  ::fidl::StringView& mutable_s() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitFoo::Ordinal::kS);
    return *static_cast<::fidl::StringView*>(envelope_.data.get());
  }

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

  static ExplicitFoo WithI(::fidl::ObjectView<int32_t> val) {
    ExplicitFoo result;
    result.set_i(val);
    return result;
  }

  template <typename... Args>
  static ExplicitFoo WithI(::fidl::AnyAllocator& allocator, Args&&... args) {
    ExplicitFoo result;
    result.set_i(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_i(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_union::wire::ExplicitFoo::Ordinal::kI;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_i(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_union::wire::ExplicitFoo::Ordinal::kI;
    set_i(::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  int32_t& mutable_i() {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_union::wire::ExplicitFoo::Ordinal::kI);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::ExplicitFoo::Tag which() const;

  static constexpr const fidl_type_t* Type = &fidl_test_union_ExplicitFooTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::ExplicitFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_XUnionContainingEmptyStructTable;

class XUnionContainingEmptyStruct {
 public:
  XUnionContainingEmptyStruct()
      : ordinal_(::fidl_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_ == ::fidl_test_union::wire::XUnionContainingEmptyStruct::
                           Ordinal::Invalid;
  }

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

  static XUnionContainingEmptyStruct WithEmpty(
      ::fidl::ObjectView<::fidl_test_union::wire::Empty> val) {
    XUnionContainingEmptyStruct result;
    result.set_empty(val);
    return result;
  }

  template <typename... Args>
  static XUnionContainingEmptyStruct WithEmpty(::fidl::AnyAllocator& allocator,
                                               Args&&... args) {
    XUnionContainingEmptyStruct result;
    result.set_empty(::fidl::ObjectView<::fidl_test_union::wire::Empty>(
        allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_empty(::fidl::ObjectView<::fidl_test_union::wire::Empty> elem) {
    ordinal_ =
        ::fidl_test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_empty(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ =
        ::fidl_test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty;
    set_empty(::fidl::ObjectView<::fidl_test_union::wire::Empty>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_union::wire::Empty& mutable_empty() {
    ZX_ASSERT(
        ordinal_ ==
        ::fidl_test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty);
    return *static_cast<::fidl_test_union::wire::Empty*>(envelope_.data.get());
  }
  const ::fidl_test_union::wire::Empty& empty() const {
    ZX_ASSERT(
        ordinal_ ==
        ::fidl_test_union::wire::XUnionContainingEmptyStruct::Ordinal::kEmpty);
    return *static_cast<::fidl_test_union::wire::Empty*>(envelope_.data.get());
  }
  ::fidl_test_union::wire::XUnionContainingEmptyStruct::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_union_XUnionContainingEmptyStructTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_union::wire::XUnionContainingEmptyStruct::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_union_StructWithNullableXUnionTable;

struct StructWithNullableXUnion {
  static constexpr const fidl_type_t* Type =
      &fidl_test_union_StructWithNullableXUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

  ::fidl_test_union::wire::OlderSimpleUnion x1 = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          StructWithNullableXUnion* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(StructWithNullableXUnion)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<StructWithNullableXUnion>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(StructWithNullableXUnion* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<32> backing_buffer_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct StructWithNullableXUnion>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct StructWithNullableXUnion>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct StructWithNullableXUnion* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct StructWithNullableXUnion*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

extern "C" const fidl_type_t fidl_test_union_PizzaTable;

struct Pizza {
  static constexpr const fidl_type_t* Type = &fidl_test_union_PizzaTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

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

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          Pizza* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(Pizza)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<Pizza>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(Pizza* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES>
        backing_buffer_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct Pizza>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Pizza>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct Pizza* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct Pizza*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

extern "C" const fidl_type_t fidl_test_union_PastaTable;

struct Pasta {
  static constexpr const fidl_type_t* Type = &fidl_test_union_PastaTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 16;
  static constexpr bool HasPointer = true;

  ::fidl::StringView sauce = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          Pasta* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(Pasta)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<Pasta>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(Pasta* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<32> backing_buffer_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct Pasta>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Pasta>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct Pasta* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct Pasta*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

}  // namespace wire
extern "C" const fidl_type_t
    fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable;

class TestProtocol final {
  TestProtocol() = delete;

 public:
  class StrictXUnionHenceResponseMayBeStackAllocated final {
    StrictXUnionHenceResponseMayBeStackAllocated() = delete;
  };
  class FlexibleXUnionHenceResponseMustBeHeapAllocated final {
    FlexibleXUnionHenceResponseMustBeHeapAllocated() = delete;
  };
};
}  // namespace fidl_test_union
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::fidl_test_union::TestProtocol> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<::fidl_test_union::TestProtocol> final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_union::TestProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_union::TestProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};

template <>
struct ::fidl::internal::WireServerDispatcher<::fidl_test_union::TestProtocol>
    final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireServer<::fidl_test_union::TestProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireServer<::fidl_test_union::TestProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                               StrictXUnionHenceResponseMayBeStackAllocated>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType =
      ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                               StrictXUnionHenceResponseMayBeStackAllocated>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size, zx_txid_t _txid)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      if (_backing_buffer_size < sizeof(WireRequest)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size, WireRequest* request)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      if (_backing_buffer_size < sizeof(WireRequest)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(backing_buffer_.data(), backing_buffer_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(backing_buffer_.data(), backing_buffer_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> backing_buffer_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl_test_union::wire::StrictBoundedXUnion xu;
  explicit WireResponse(::fidl_test_union::wire::StrictBoundedXUnion xu)
      : xu(xu) {
    _InitHeader();
  }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_union::
          fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  static constexpr uint32_t MaxOutOfLine = 32;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size,
                          ::fidl_test_union::wire::StrictBoundedXUnion xu)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      FIDL_ALIGNDECL WireResponse _response{xu};
      if (_backing_buffer_size < sizeof(WireResponse)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size, WireResponse* response)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      if (_backing_buffer_size < sizeof(WireResponse)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(
        ::fidl_test_union::wire::StrictBoundedXUnion xu)
        : message_(backing_buffer_.data(), backing_buffer_.size(), xu) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
            response)
        : message_(backing_buffer_.data(), backing_buffer_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<72> backing_buffer_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                               FlexibleXUnionHenceResponseMustBeHeapAllocated>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType =
      ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                               FlexibleXUnionHenceResponseMustBeHeapAllocated>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size, zx_txid_t _txid)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      if (_backing_buffer_size < sizeof(WireRequest)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size, WireRequest* request)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      if (_backing_buffer_size < sizeof(WireRequest)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(backing_buffer_.data(), backing_buffer_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(backing_buffer_.data(), backing_buffer_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> backing_buffer_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl_test_union::wire::OlderSimpleUnion xu;
  explicit WireResponse(::fidl_test_union::wire::OlderSimpleUnion xu) : xu(xu) {
    _InitHeader();
  }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_union::
          fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasFlexibleEnvelope = true;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size,
                          ::fidl_test_union::wire::OlderSimpleUnion xu)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      FIDL_ALIGNDECL WireResponse _response{xu};
      if (_backing_buffer_size < sizeof(WireResponse)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* _backing_buffer,
                          uint32_t _backing_buffer_size, WireResponse* response)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = _backing_buffer,
              .backing_buffer_capacity = _backing_buffer_size,
          }) {
      if (_backing_buffer_size < sizeof(WireResponse)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(::fidl_test_union::wire::OlderSimpleUnion xu)
        : message_(backing_buffer_.data(), backing_buffer_.size(), xu) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_union::TestProtocol::
                FlexibleXUnionHenceResponseMustBeHeapAllocated>* response)
        : message_(backing_buffer_.data(), backing_buffer_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<48> backing_buffer_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader();
};
template <>
class ::fidl::WireResult<::fidl_test_union::TestProtocol::
                             StrictXUnionHenceResponseMayBeStackAllocated>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client);
  WireResult(::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
             zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>*>(bytes_.data());
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<72> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_union::TestProtocol::
        StrictXUnionHenceResponseMayBeStackAllocated>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>*>(bytes_);
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           StrictXUnionHenceResponseMayBeStackAllocated>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<::fidl_test_union::TestProtocol::
                             FlexibleXUnionHenceResponseMustBeHeapAllocated>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client);
  WireResult(::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
             zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_union::TestProtocol::
        FlexibleXUnionHenceResponseMustBeHeapAllocated>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                           FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};

// Methods to make a sync FIDL call directly on an unowned channel or a
// const reference to a |fidl::ClientEnd<::fidl_test_union::TestProtocol>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireCaller<::fidl_test_union::TestProtocol> final {
 public:
  explicit WireCaller(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> client_end)
      : client_end_(client_end) {}

  // Allocates 88 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client_end) {
    return ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                  StrictXUnionHenceResponseMayBeStackAllocated>(
        _client_end);
  }
  // Allocates 88 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_union::TestProtocol::
                         StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated() && {
    return ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                  StrictXUnionHenceResponseMayBeStackAllocated>(
        client_end_);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_union::TestProtocol::
          StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client_end,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>(
        _client_end, _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>(
        client_end_, _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 16 bytes of request buffer on the stack. Response is
  // heap-allocated.
  static ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(_client_end);
  }
  // Allocates 16 bytes of request buffer on the stack. Response is
  // heap-allocated.
  ::fidl::WireResult<::fidl_test_union::TestProtocol::
                         FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated() && {
    return ::fidl::WireResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(client_end_);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_union::TestProtocol::
          FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> _client_end,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(
        _client_end, _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(
        client_end_, _response_buffer.data, _response_buffer.capacity);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_union::TestProtocol> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fidl::WireAsyncEventHandler<::fidl_test_union::TestProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_union::TestProtocol> {
 public:
  WireAsyncEventHandler() = default;

  virtual void Unbound(::fidl::UnbindInfo info) {}
};

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_union::TestProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_union::TestProtocol> {
 public:
  WireSyncEventHandler() = default;

  // Method called when an unknown event is found. This methods gives the status
  // which, in this case, is returned by HandleOneEvent.
  virtual zx_status_t Unknown() = 0;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Result HandleOneEvent(
      ::fidl::UnownedClientEnd<::fidl_test_union::TestProtocol> client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_union::TestProtocol> final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_union::TestProtocol> client_end)
      : client_end_(std::move(client_end)) {}

  ~WireSyncClient() = default;
  WireSyncClient(WireSyncClient&&) = default;
  WireSyncClient& operator=(WireSyncClient&&) = default;

  const ::fidl::ClientEnd<::fidl_test_union::TestProtocol>& client_end() const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_union::TestProtocol>& client_end() {
    return client_end_;
  }

  const ::zx::channel& channel() const { return client_end_.channel(); }
  ::zx::channel* mutable_channel() { return &client_end_.channel(); }

  // Allocates 88 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_union::TestProtocol::
                         StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated() {
    return ::fidl::WireResult<::fidl_test_union::TestProtocol::
                                  StrictXUnionHenceResponseMayBeStackAllocated>(
        this->client_end());
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>(
        this->client_end(), _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 16 bytes of request buffer on the stack. Response is
  // heap-allocated.
  ::fidl::WireResult<::fidl_test_union::TestProtocol::
                         FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated() {
    return ::fidl::WireResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(this->client_end());
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>(
        this->client_end(), _response_buffer.data, _response_buffer.capacity);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_union::TestProtocol> client_end_;
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireServer<::fidl_test_union::TestProtocol>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::fidl_test_union::TestProtocol;

  class StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase
      : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(::fidl_test_union::wire::StrictBoundedXUnion xu);
    ::fidl::Result Reply(::fidl::BufferSpan _backing_buffer,
                         ::fidl_test_union::wire::StrictBoundedXUnion xu);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };
  using StrictXUnionHenceResponseMayBeStackAllocatedCompleter =
      ::fidl::Completer<
          StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase>;
  class StrictXUnionHenceResponseMayBeStackAllocatedRequestView {
   public:
    StrictXUnionHenceResponseMayBeStackAllocatedRequestView(
        ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>*
            request)
        : request_(request) {}
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            StrictXUnionHenceResponseMayBeStackAllocated>*
    operator->() const {
      return request_;
    }

   private:
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            StrictXUnionHenceResponseMayBeStackAllocated>*
        request_;
  };

  virtual void StrictXUnionHenceResponseMayBeStackAllocated(
      StrictXUnionHenceResponseMayBeStackAllocatedRequestView request,
      StrictXUnionHenceResponseMayBeStackAllocatedCompleter::Sync&
          _completer) = 0;

  class FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase
      : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(::fidl_test_union::wire::OlderSimpleUnion xu);
    ::fidl::Result Reply(::fidl::BufferSpan _backing_buffer,
                         ::fidl_test_union::wire::OlderSimpleUnion xu);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };
  using FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleter =
      ::fidl::Completer<
          FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase>;
  class FlexibleXUnionHenceResponseMustBeHeapAllocatedRequestView {
   public:
    FlexibleXUnionHenceResponseMustBeHeapAllocatedRequestView(
        ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>*
            request)
        : request_(request) {}
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            FlexibleXUnionHenceResponseMustBeHeapAllocated>*
    operator->() const {
      return request_;
    }

   private:
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            FlexibleXUnionHenceResponseMustBeHeapAllocated>*
        request_;
  };

  virtual void FlexibleXUnionHenceResponseMustBeHeapAllocated(
      FlexibleXUnionHenceResponseMustBeHeapAllocatedRequestView request,
      FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleter::Sync&
          _completer) = 0;

 private:
  ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) final;
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireInterface<::fidl_test_union::TestProtocol>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireInterface() = default;
  virtual ~WireInterface() = default;

  // The marker protocol type within which this |WireInterface| class is
  // defined.
  using _EnclosingProtocol = ::fidl_test_union::TestProtocol;

  using StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase =
      ::fidl::WireServer<::fidl_test_union::TestProtocol>::
          StrictXUnionHenceResponseMayBeStackAllocatedCompleterBase;

  using StrictXUnionHenceResponseMayBeStackAllocatedCompleter =
      ::fidl::WireServer<::fidl_test_union::TestProtocol>::
          StrictXUnionHenceResponseMayBeStackAllocatedCompleter;
  virtual void StrictXUnionHenceResponseMayBeStackAllocated(
      StrictXUnionHenceResponseMayBeStackAllocatedCompleter::Sync&
          _completer) = 0;

  using FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase =
      ::fidl::WireServer<::fidl_test_union::TestProtocol>::
          FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleterBase;

  using FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleter =
      ::fidl::WireServer<::fidl_test_union::TestProtocol>::
          FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleter;
  virtual void FlexibleXUnionHenceResponseMustBeHeapAllocated(
      FlexibleXUnionHenceResponseMustBeHeapAllocatedCompleter::Sync&
          _completer) = 0;

 private:
  ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) final;
};

namespace fidl_test_union {
namespace wire {

extern "C" const fidl_type_t fidl_test_union_NullableUnionStructTable;

struct NullableUnionStruct {
  static constexpr const fidl_type_t* Type =
      &fidl_test_union_NullableUnionStructTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasPointer = true;

  ::fidl_test_union::wire::Union the_union = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          NullableUnionStruct* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(NullableUnionStruct)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<NullableUnionStruct>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(NullableUnionStruct* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES>
        backing_buffer_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct NullableUnionStruct>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct NullableUnionStruct>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct NullableUnionStruct* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct NullableUnionStruct*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

extern "C" const fidl_type_t fidl_test_union_EmptyTable;

struct Empty {
  static constexpr const fidl_type_t* Type = &fidl_test_union_EmptyTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 1;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  uint8_t __reserved = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          Empty* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(Empty)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<Empty>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(Empty* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<8> backing_buffer_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct Empty>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Empty>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct Empty* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct Empty*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

}  // namespace wire
}  // namespace fidl_test_union
namespace fidl {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            StrictXUnionHenceResponseMayBeStackAllocated>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            StrictXUnionHenceResponseMayBeStackAllocated>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_union::TestProtocol::
               StrictXUnionHenceResponseMayBeStackAllocated>) ==
    ::fidl::WireRequest<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                             StrictXUnionHenceResponseMayBeStackAllocated>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                             StrictXUnionHenceResponseMayBeStackAllocated>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_union::TestProtocol::
               StrictXUnionHenceResponseMayBeStackAllocated>) ==
    ::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            StrictXUnionHenceResponseMayBeStackAllocated>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                                 StrictXUnionHenceResponseMayBeStackAllocated>,
        xu) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            FlexibleXUnionHenceResponseMustBeHeapAllocated>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_union::TestProtocol::
                            FlexibleXUnionHenceResponseMustBeHeapAllocated>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_union::TestProtocol::
               FlexibleXUnionHenceResponseMustBeHeapAllocated>) ==
    ::fidl::WireRequest<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                             FlexibleXUnionHenceResponseMustBeHeapAllocated>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                             FlexibleXUnionHenceResponseMustBeHeapAllocated>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_union::TestProtocol::
               FlexibleXUnionHenceResponseMustBeHeapAllocated>) ==
    ::fidl::WireResponse<
        ::fidl_test_union::TestProtocol::
            FlexibleXUnionHenceResponseMustBeHeapAllocated>::PrimarySize);
static_assert(offsetof(::fidl::WireResponse<
                           ::fidl_test_union::TestProtocol::
                               FlexibleXUnionHenceResponseMustBeHeapAllocated>,
                       xu) == 16);

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

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

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

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

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

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

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

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

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

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

template <>
struct IsFidlType<::fidl_test_union::wire::XUnionContainingEmptyStruct>
    : public std::true_type {};
template <>
struct IsUnion<::fidl_test_union::wire::XUnionContainingEmptyStruct>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_union::wire::XUnionContainingEmptyStruct>);
}  // namespace fidl
#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_union::TestProtocol::
        StrictXUnionHenceResponseMayBeStackAllocated>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                               StrictXUnionHenceResponseMayBeStackAllocated>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_union::TestProtocol::
        FlexibleXUnionHenceResponseMustBeHeapAllocated>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<::fidl_test_union::TestProtocol::
                               FlexibleXUnionHenceResponseMustBeHeapAllocated>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireClientImpl<::fidl_test_union::TestProtocol> final
    : private ::fidl::internal::ClientBase {
 public:
  // Asynchronous variant of
  // |TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated()|. Allocates 16
  // bytes of request buffer on the stack. The callback is stored on the heap.
  ::fidl::Result StrictXUnionHenceResponseMayBeStackAllocated(
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_union::TestProtocol::
                   StrictXUnionHenceResponseMayBeStackAllocated>* response)>
          _cb);

  // Asynchronous variant of
  // |TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated()|. Caller
  // provides the backing storage for FIDL message via request buffer. Ownership
  // of |_context| is given unsafely to the binding until |OnError| or |OnReply|
  // are called on it.
  ::fidl::Result StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::WireResponseContext<
          ::fidl_test_union::TestProtocol::
              StrictXUnionHenceResponseMayBeStackAllocated>* _context);

  // Synchronous variant of
  // |TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated()|. Allocates 88
  // bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::WireResult<::fidl_test_union::TestProtocol::
                         StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated_Sync();

  // Synchronous variant of
  // |TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated()|. Caller
  // provides the backing storage for FIDL message via request and response
  // buffers.
  ::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                                StrictXUnionHenceResponseMayBeStackAllocated>
  StrictXUnionHenceResponseMayBeStackAllocated_Sync(
      ::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of
  // |TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated()|. Allocates
  // 16 bytes of request buffer on the stack. The callback is stored on the
  // heap.
  ::fidl::Result FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_union::TestProtocol::
                   FlexibleXUnionHenceResponseMustBeHeapAllocated>* response)>
          _cb);

  // Asynchronous variant of
  // |TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated()|. Caller
  // provides the backing storage for FIDL message via request buffer. Ownership
  // of |_context| is given unsafely to the binding until |OnError| or |OnReply|
  // are called on it.
  ::fidl::Result FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::WireResponseContext<
          ::fidl_test_union::TestProtocol::
              FlexibleXUnionHenceResponseMustBeHeapAllocated>* _context);

  // Synchronous variant of
  // |TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated()|. Allocates
  // 16 bytes of request buffer on the stack. Response is heap-allocated.
  ::fidl::WireResult<::fidl_test_union::TestProtocol::
                         FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated_Sync();

  // Synchronous variant of
  // |TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated()|. Caller
  // provides the backing storage for FIDL message via request and response
  // buffers.
  ::fidl::WireUnownedResult<::fidl_test_union::TestProtocol::
                                FlexibleXUnionHenceResponseMustBeHeapAllocated>
  FlexibleXUnionHenceResponseMustBeHeapAllocated_Sync(
      ::fidl::BufferSpan _response_buffer);

  ::fidl::WireAsyncEventHandler<::fidl_test_union::TestProtocol>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_union::TestProtocol>;
  friend class ::fidl::internal::ControlBlock<::fidl_test_union::TestProtocol>;

  explicit WireClientImpl(
      std::shared_ptr<
          ::fidl::WireAsyncEventHandler<::fidl_test_union::TestProtocol>>
          event_handler)
      : event_handler_(std::move(event_handler)) {}

  std::optional<::fidl::UnbindInfo> DispatchEvent(
      fidl_incoming_msg_t* msg) override;

  std::shared_ptr<
      ::fidl::WireAsyncEventHandler<::fidl_test_union::TestProtocol>>
      event_handler_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__
// |EventSender| owns a server endpoint of a channel speaking
// the TestProtocol protocol, and can send events in that protocol.
template <>
class ::fidl::WireEventSender<::fidl_test_union::TestProtocol> {
 public:
  // Constructs an event sender with an invalid channel.
  WireEventSender() = default;

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_union::TestProtocol> server_end)
      : server_end_(std::move(server_end)) {}

  // The underlying server channel endpoint, which may be replaced at run-time.
  const ::fidl::ServerEnd<::fidl_test_union::TestProtocol>& server_end() const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_union::TestProtocol>& server_end() {
    return server_end_;
  }

  const ::zx::channel& channel() const { return server_end_.channel(); }
  ::zx::channel& channel() { return server_end_.channel(); }

  // Whether the underlying channel is valid.
  bool is_valid() const { return server_end_.is_valid(); }

 private:
  ::fidl::ServerEnd<::fidl_test_union::TestProtocol> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<::fidl_test_union::TestProtocol> {
 public:
 private:
  friend class ::fidl::ServerBindingRef<::fidl_test_union::TestProtocol>;

  explicit WireWeakEventSender(
      std::weak_ptr<
          ::fidl::internal::AsyncServerBinding<::fidl_test_union::TestProtocol>>
          binding)
      : binding_(std::move(binding)) {}

  std::weak_ptr<
      ::fidl::internal::AsyncServerBinding<::fidl_test_union::TestProtocol>>
      binding_;
};
#endif  // __Fuchsia__
