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

#pragma once

#include "lib/fidl/cpp/internal/header.h"

namespace test {
namespace union_ {

//
// Domain objects declarations
//

class UnionWithAttributes;

class Union;

class StructWithNullableXUnion;

class StrictUnion;

class StrictSimpleXUnion;

class StrictFoo;

class StrictBoundedXUnion;

class TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse;

class ReverseOrdinalUnion;

class Pizza;

class Pasta;

class StrictPizzaOrPasta;

class PizzaOrPasta;

class FlexiblePizzaOrPasta;

class ExplicitPizzaOrPasta;

class OlderSimpleUnion;

class TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse;

#ifdef __Fuchsia__

class TestProtocol;
using TestProtocolHandle = ::fidl::InterfaceHandle<TestProtocol>;
#endif  // __Fuchsia__

class NullableUnionStruct;

class NewerSimpleUnion;

class FlexibleUnion;

class FlexibleFoo;

class FieldCollision;

class ExplicitXUnion;

class UnionSandwich;

class ExplicitUnion;

class ExplicitStrictFoo;

class ExplicitFoo;

class Empty;

class XUnionContainingEmptyStruct;

class UnionWithAttributes final {
 public:
  static const fidl_type_t* FidlType;

  UnionWithAttributes();
  ~UnionWithAttributes();

  UnionWithAttributes(UnionWithAttributes&&);
  UnionWithAttributes& operator=(UnionWithAttributes&&);

  static UnionWithAttributes WithX(int64_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kX = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<UnionWithAttributes> New() { return ::std::make_unique<UnionWithAttributes>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, UnionWithAttributes* value, size_t offset);
  zx_status_t Clone(UnionWithAttributes* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_x() const { return tag_ == ::test::union_::UnionWithAttributes::Tag::kX; }

  int64_t& x() {
    EnsureStorageInitialized(::test::union_::UnionWithAttributes::Tag::kX);
    return x_;
  }

  const int64_t& x() const {
    ZX_ASSERT(is_x());
    return x_;
  }
  UnionWithAttributes& set_x(int64_t value);
  UnionWithAttributes& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::UnionWithAttributes::Tag Which() const {
    switch (tag_) {
      case ::test::union_::UnionWithAttributes::Tag::Invalid:
      case ::test::union_::UnionWithAttributes::Tag::kX:
        return ::test::union_::UnionWithAttributes::Tag(tag_);
      default:
        return ::test::union_::UnionWithAttributes::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::UnionWithAttributes::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::UnionWithAttributes>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid);
  union {
    int64_t x_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::UnionWithAttributes& value,
                         ::test::union_::UnionWithAttributes* result) {
  return value.Clone(result);
}

using UnionWithAttributesPtr = ::std::unique_ptr<UnionWithAttributes>;

class Union final {
 public:
  static const fidl_type_t* FidlType;

  Union();
  ~Union();

  Union(Union&&);
  Union& operator=(Union&&);

  static Union WithPrimitive(int32_t&&);
  static Union WithStringNeedsConstructor(::std::string&&);
  static Union WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<Union> New() { return ::std::make_unique<Union>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Union* value, size_t offset);
  zx_status_t Clone(Union* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_Primitive() const { return tag_ == ::test::union_::Union::Tag::kPrimitive; }

  int32_t& Primitive() {
    EnsureStorageInitialized(::test::union_::Union::Tag::kPrimitive);
    return Primitive_;
  }

  const int32_t& Primitive() const {
    ZX_ASSERT(is_Primitive());
    return Primitive_;
  }
  Union& set_Primitive(int32_t value);

  bool is_StringNeedsConstructor() const { return tag_ == ::test::union_::Union::Tag::kStringNeedsConstructor; }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::Union::Tag::kStringNeedsConstructor);
    return StringNeedsConstructor_;
  }

  const ::std::string& StringNeedsConstructor() const {
    ZX_ASSERT(is_StringNeedsConstructor());
    return StringNeedsConstructor_;
  }
  Union& set_StringNeedsConstructor(::std::string value);

  bool is_VectorStringAlsoNeedsConstructor() const { return tag_ == ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor; }

  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor);
    return VectorStringAlsoNeedsConstructor_;
  }

  const ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() const {
    ZX_ASSERT(is_VectorStringAlsoNeedsConstructor());
    return VectorStringAlsoNeedsConstructor_;
  }
  Union& set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value);

  ::test::union_::Union::Tag Which() const {
    return ::test::union_::Union::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::Union>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid);
  union {
    int32_t Primitive_;
    ::std::string StringNeedsConstructor_;
    ::std::vector<::std::string> VectorStringAlsoNeedsConstructor_;
  };
};

inline zx_status_t Clone(const ::test::union_::Union& value,
                         ::test::union_::Union* result) {
  return value.Clone(result);
}

using UnionPtr = ::std::unique_ptr<Union>;

class StructWithNullableXUnion final {
 public:
  static const fidl_type_t* FidlType;

  ::std::unique_ptr<::test::union_::OlderSimpleUnion> x1{};

  static inline ::std::unique_ptr<StructWithNullableXUnion> New() { return ::std::make_unique<StructWithNullableXUnion>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StructWithNullableXUnion* value, size_t _offset);
  zx_status_t Clone(StructWithNullableXUnion* result) const;
};

inline zx_status_t Clone(const ::test::union_::StructWithNullableXUnion& _value,
                         ::test::union_::StructWithNullableXUnion* _result) {
  return _value.Clone(_result);
}

using StructWithNullableXUnionPtr = ::std::unique_ptr<StructWithNullableXUnion>;

class StrictUnion final {
 public:
  static const fidl_type_t* FidlType;

  StrictUnion();
  ~StrictUnion();

  StrictUnion(StrictUnion&&);
  StrictUnion& operator=(StrictUnion&&);

  static StrictUnion WithPrimitive(int32_t&&);
  static StrictUnion WithStringNeedsConstructor(::std::string&&);
  static StrictUnion WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<StrictUnion> New() { return ::std::make_unique<StrictUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StrictUnion* value, size_t offset);
  zx_status_t Clone(StrictUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_Primitive() const { return tag_ == ::test::union_::StrictUnion::Tag::kPrimitive; }

  int32_t& Primitive() {
    EnsureStorageInitialized(::test::union_::StrictUnion::Tag::kPrimitive);
    return Primitive_;
  }

  const int32_t& Primitive() const {
    ZX_ASSERT(is_Primitive());
    return Primitive_;
  }
  StrictUnion& set_Primitive(int32_t value);

  bool is_StringNeedsConstructor() const { return tag_ == ::test::union_::StrictUnion::Tag::kStringNeedsConstructor; }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::StrictUnion::Tag::kStringNeedsConstructor);
    return StringNeedsConstructor_;
  }

  const ::std::string& StringNeedsConstructor() const {
    ZX_ASSERT(is_StringNeedsConstructor());
    return StringNeedsConstructor_;
  }
  StrictUnion& set_StringNeedsConstructor(::std::string value);

  bool is_VectorStringAlsoNeedsConstructor() const { return tag_ == ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor; }

  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor);
    return VectorStringAlsoNeedsConstructor_;
  }

  const ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() const {
    ZX_ASSERT(is_VectorStringAlsoNeedsConstructor());
    return VectorStringAlsoNeedsConstructor_;
  }
  StrictUnion& set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value);

  ::test::union_::StrictUnion::Tag Which() const {
    return ::test::union_::StrictUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::StrictUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid);
  union {
    int32_t Primitive_;
    ::std::string StringNeedsConstructor_;
    ::std::vector<::std::string> VectorStringAlsoNeedsConstructor_;
  };
};

inline zx_status_t Clone(const ::test::union_::StrictUnion& value,
                         ::test::union_::StrictUnion* result) {
  return value.Clone(result);
}

using StrictUnionPtr = ::std::unique_ptr<StrictUnion>;

class StrictSimpleXUnion final {
 public:
  static const fidl_type_t* FidlType;

  StrictSimpleXUnion();
  ~StrictSimpleXUnion();

  StrictSimpleXUnion(StrictSimpleXUnion&&);
  StrictSimpleXUnion& operator=(StrictSimpleXUnion&&);

  static StrictSimpleXUnion WithI(int32_t&&);
  static StrictSimpleXUnion WithF(float&&);
  static StrictSimpleXUnion WithS(::std::string&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kS = 3,  // 0x3
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<StrictSimpleXUnion> New() { return ::std::make_unique<StrictSimpleXUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StrictSimpleXUnion* value, size_t offset);
  zx_status_t Clone(StrictSimpleXUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_i() const { return tag_ == ::test::union_::StrictSimpleXUnion::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::union_::StrictSimpleXUnion::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  StrictSimpleXUnion& set_i(int32_t value);

  bool is_f() const { return tag_ == ::test::union_::StrictSimpleXUnion::Tag::kF; }

  float& f() {
    EnsureStorageInitialized(::test::union_::StrictSimpleXUnion::Tag::kF);
    return f_;
  }

  const float& f() const {
    ZX_ASSERT(is_f());
    return f_;
  }
  StrictSimpleXUnion& set_f(float value);

  bool is_s() const { return tag_ == ::test::union_::StrictSimpleXUnion::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::union_::StrictSimpleXUnion::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  StrictSimpleXUnion& set_s(::std::string value);

  ::test::union_::StrictSimpleXUnion::Tag Which() const {
    return ::test::union_::StrictSimpleXUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::StrictSimpleXUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid);
  union {
    int32_t i_;
    float f_;
    ::std::string s_;
  };
};

inline zx_status_t Clone(const ::test::union_::StrictSimpleXUnion& value,
                         ::test::union_::StrictSimpleXUnion* result) {
  return value.Clone(result);
}

using StrictSimpleXUnionPtr = ::std::unique_ptr<StrictSimpleXUnion>;

class StrictFoo final {
 public:
  static const fidl_type_t* FidlType;

  StrictFoo();
  ~StrictFoo();

  StrictFoo(StrictFoo&&);
  StrictFoo& operator=(StrictFoo&&);

  static StrictFoo WithS(::std::string&&);
  static StrictFoo WithI(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kS = 1,  // 0x1
    kI = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<StrictFoo> New() { return ::std::make_unique<StrictFoo>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StrictFoo* value, size_t offset);
  zx_status_t Clone(StrictFoo* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_s() const { return tag_ == ::test::union_::StrictFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::union_::StrictFoo::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  StrictFoo& set_s(::std::string value);

  bool is_i() const { return tag_ == ::test::union_::StrictFoo::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::union_::StrictFoo::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  StrictFoo& set_i(int32_t value);

  ::test::union_::StrictFoo::Tag Which() const {
    return ::test::union_::StrictFoo::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::StrictFoo>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid);
  union {
    ::std::string s_;
    int32_t i_;
  };
};

inline zx_status_t Clone(const ::test::union_::StrictFoo& value,
                         ::test::union_::StrictFoo* result) {
  return value.Clone(result);
}

using StrictFooPtr = ::std::unique_ptr<StrictFoo>;

class StrictBoundedXUnion final {
 public:
  static const fidl_type_t* FidlType;

  StrictBoundedXUnion();
  ~StrictBoundedXUnion();

  StrictBoundedXUnion(StrictBoundedXUnion&&);
  StrictBoundedXUnion& operator=(StrictBoundedXUnion&&);

  static StrictBoundedXUnion WithV(::std::vector<uint8_t>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kV = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<StrictBoundedXUnion> New() { return ::std::make_unique<StrictBoundedXUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StrictBoundedXUnion* value, size_t offset);
  zx_status_t Clone(StrictBoundedXUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_v() const { return tag_ == ::test::union_::StrictBoundedXUnion::Tag::kV; }

  ::std::vector<uint8_t>& v() {
    EnsureStorageInitialized(::test::union_::StrictBoundedXUnion::Tag::kV);
    return v_;
  }

  const ::std::vector<uint8_t>& v() const {
    ZX_ASSERT(is_v());
    return v_;
  }
  StrictBoundedXUnion& set_v(::std::vector<uint8_t> value);

  ::test::union_::StrictBoundedXUnion::Tag Which() const {
    return ::test::union_::StrictBoundedXUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::StrictBoundedXUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid);
  union {
    ::std::vector<uint8_t> v_;
  };
};

inline zx_status_t Clone(const ::test::union_::StrictBoundedXUnion& value,
                         ::test::union_::StrictBoundedXUnion* result) {
  return value.Clone(result);
}

using StrictBoundedXUnionPtr = ::std::unique_ptr<StrictBoundedXUnion>;

class TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse final {
 public:
  static const fidl_type_t* FidlType;

  ::test::union_::StrictBoundedXUnion xu{};

  static inline ::std::unique_ptr<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse> New() { return ::std::make_unique<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse* value, size_t _offset);
  zx_status_t Clone(TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse* result) const;
};

inline zx_status_t Clone(const ::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse& _value,
                         ::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse* _result) {
  return _value.Clone(_result);
}

using TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponsePtr = ::std::unique_ptr<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>;

class ReverseOrdinalUnion final {
 public:
  static const fidl_type_t* FidlType;

  ReverseOrdinalUnion();
  ~ReverseOrdinalUnion();

  ReverseOrdinalUnion(ReverseOrdinalUnion&&);
  ReverseOrdinalUnion& operator=(ReverseOrdinalUnion&&);

  static ReverseOrdinalUnion WithSecond(uint32_t&&);
  static ReverseOrdinalUnion WithFirst(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kSecond = 2,  // 0x2
    kFirst = 1,   // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ReverseOrdinalUnion> New() { return ::std::make_unique<ReverseOrdinalUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ReverseOrdinalUnion* value, size_t offset);
  zx_status_t Clone(ReverseOrdinalUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_second() const { return tag_ == ::test::union_::ReverseOrdinalUnion::Tag::kSecond; }

  uint32_t& second() {
    EnsureStorageInitialized(::test::union_::ReverseOrdinalUnion::Tag::kSecond);
    return second_;
  }

  const uint32_t& second() const {
    ZX_ASSERT(is_second());
    return second_;
  }
  ReverseOrdinalUnion& set_second(uint32_t value);

  bool is_first() const { return tag_ == ::test::union_::ReverseOrdinalUnion::Tag::kFirst; }

  uint32_t& first() {
    EnsureStorageInitialized(::test::union_::ReverseOrdinalUnion::Tag::kFirst);
    return first_;
  }

  const uint32_t& first() const {
    ZX_ASSERT(is_first());
    return first_;
  }
  ReverseOrdinalUnion& set_first(uint32_t value);

  ::test::union_::ReverseOrdinalUnion::Tag Which() const {
    return ::test::union_::ReverseOrdinalUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::ReverseOrdinalUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid);
  union {
    uint32_t second_;
    uint32_t first_;
  };
};

inline zx_status_t Clone(const ::test::union_::ReverseOrdinalUnion& value,
                         ::test::union_::ReverseOrdinalUnion* result) {
  return value.Clone(result);
}

using ReverseOrdinalUnionPtr = ::std::unique_ptr<ReverseOrdinalUnion>;

class Pizza final {
 public:
  static const fidl_type_t* FidlType;

  ::std::vector<::std::string> toppings{};

  static inline ::std::unique_ptr<Pizza> New() { return ::std::make_unique<Pizza>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Pizza* value, size_t _offset);
  zx_status_t Clone(Pizza* result) const;
};

inline zx_status_t Clone(const ::test::union_::Pizza& _value,
                         ::test::union_::Pizza* _result) {
  return _value.Clone(_result);
}

using PizzaPtr = ::std::unique_ptr<Pizza>;

class Pasta final {
 public:
  static const fidl_type_t* FidlType;

  ::std::string sauce{};

  static inline ::std::unique_ptr<Pasta> New() { return ::std::make_unique<Pasta>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Pasta* value, size_t _offset);
  zx_status_t Clone(Pasta* result) const;
};

inline zx_status_t Clone(const ::test::union_::Pasta& _value,
                         ::test::union_::Pasta* _result) {
  return _value.Clone(_result);
}

using PastaPtr = ::std::unique_ptr<Pasta>;

class StrictPizzaOrPasta final {
 public:
  static const fidl_type_t* FidlType;

  StrictPizzaOrPasta();
  ~StrictPizzaOrPasta();

  StrictPizzaOrPasta(StrictPizzaOrPasta&&);
  StrictPizzaOrPasta& operator=(StrictPizzaOrPasta&&);

  static StrictPizzaOrPasta WithPizza(::test::union_::Pizza&&);
  static StrictPizzaOrPasta WithPasta(::test::union_::Pasta&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<StrictPizzaOrPasta> New() { return ::std::make_unique<StrictPizzaOrPasta>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, StrictPizzaOrPasta* value, size_t offset);
  zx_status_t Clone(StrictPizzaOrPasta* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_pizza() const { return tag_ == ::test::union_::StrictPizzaOrPasta::Tag::kPizza; }

  ::test::union_::Pizza& pizza() {
    EnsureStorageInitialized(::test::union_::StrictPizzaOrPasta::Tag::kPizza);
    return pizza_;
  }

  const ::test::union_::Pizza& pizza() const {
    ZX_ASSERT(is_pizza());
    return pizza_;
  }
  StrictPizzaOrPasta& set_pizza(::test::union_::Pizza value);

  bool is_pasta() const { return tag_ == ::test::union_::StrictPizzaOrPasta::Tag::kPasta; }

  ::test::union_::Pasta& pasta() {
    EnsureStorageInitialized(::test::union_::StrictPizzaOrPasta::Tag::kPasta);
    return pasta_;
  }

  const ::test::union_::Pasta& pasta() const {
    ZX_ASSERT(is_pasta());
    return pasta_;
  }
  StrictPizzaOrPasta& set_pasta(::test::union_::Pasta value);

  ::test::union_::StrictPizzaOrPasta::Tag Which() const {
    return ::test::union_::StrictPizzaOrPasta::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::StrictPizzaOrPasta>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid);
  union {
    ::test::union_::Pizza pizza_;
    ::test::union_::Pasta pasta_;
  };
};

inline zx_status_t Clone(const ::test::union_::StrictPizzaOrPasta& value,
                         ::test::union_::StrictPizzaOrPasta* result) {
  return value.Clone(result);
}

using StrictPizzaOrPastaPtr = ::std::unique_ptr<StrictPizzaOrPasta>;

class PizzaOrPasta final {
 public:
  static const fidl_type_t* FidlType;

  PizzaOrPasta();
  ~PizzaOrPasta();

  PizzaOrPasta(PizzaOrPasta&&);
  PizzaOrPasta& operator=(PizzaOrPasta&&);

  static PizzaOrPasta WithPizza(::test::union_::Pizza&&);
  static PizzaOrPasta WithPasta(::test::union_::Pasta&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<PizzaOrPasta> New() { return ::std::make_unique<PizzaOrPasta>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, PizzaOrPasta* value, size_t offset);
  zx_status_t Clone(PizzaOrPasta* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_pizza() const { return tag_ == ::test::union_::PizzaOrPasta::Tag::kPizza; }

  ::test::union_::Pizza& pizza() {
    EnsureStorageInitialized(::test::union_::PizzaOrPasta::Tag::kPizza);
    return pizza_;
  }

  const ::test::union_::Pizza& pizza() const {
    ZX_ASSERT(is_pizza());
    return pizza_;
  }
  PizzaOrPasta& set_pizza(::test::union_::Pizza value);

  bool is_pasta() const { return tag_ == ::test::union_::PizzaOrPasta::Tag::kPasta; }

  ::test::union_::Pasta& pasta() {
    EnsureStorageInitialized(::test::union_::PizzaOrPasta::Tag::kPasta);
    return pasta_;
  }

  const ::test::union_::Pasta& pasta() const {
    ZX_ASSERT(is_pasta());
    return pasta_;
  }
  PizzaOrPasta& set_pasta(::test::union_::Pasta value);

  ::test::union_::PizzaOrPasta::Tag Which() const {
    return ::test::union_::PizzaOrPasta::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::PizzaOrPasta>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid);
  union {
    ::test::union_::Pizza pizza_;
    ::test::union_::Pasta pasta_;
  };
};

inline zx_status_t Clone(const ::test::union_::PizzaOrPasta& value,
                         ::test::union_::PizzaOrPasta* result) {
  return value.Clone(result);
}

using PizzaOrPastaPtr = ::std::unique_ptr<PizzaOrPasta>;

class FlexiblePizzaOrPasta final {
 public:
  static const fidl_type_t* FidlType;

  FlexiblePizzaOrPasta();
  ~FlexiblePizzaOrPasta();

  FlexiblePizzaOrPasta(FlexiblePizzaOrPasta&&);
  FlexiblePizzaOrPasta& operator=(FlexiblePizzaOrPasta&&);

  static FlexiblePizzaOrPasta WithPizza(::test::union_::Pizza&&);
  static FlexiblePizzaOrPasta WithPasta(::test::union_::Pasta&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<FlexiblePizzaOrPasta> New() { return ::std::make_unique<FlexiblePizzaOrPasta>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, FlexiblePizzaOrPasta* value, size_t offset);
  zx_status_t Clone(FlexiblePizzaOrPasta* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_pizza() const { return tag_ == ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza; }

  ::test::union_::Pizza& pizza() {
    EnsureStorageInitialized(::test::union_::FlexiblePizzaOrPasta::Tag::kPizza);
    return pizza_;
  }

  const ::test::union_::Pizza& pizza() const {
    ZX_ASSERT(is_pizza());
    return pizza_;
  }
  FlexiblePizzaOrPasta& set_pizza(::test::union_::Pizza value);

  bool is_pasta() const { return tag_ == ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta; }

  ::test::union_::Pasta& pasta() {
    EnsureStorageInitialized(::test::union_::FlexiblePizzaOrPasta::Tag::kPasta);
    return pasta_;
  }

  const ::test::union_::Pasta& pasta() const {
    ZX_ASSERT(is_pasta());
    return pasta_;
  }
  FlexiblePizzaOrPasta& set_pasta(::test::union_::Pasta value);
  FlexiblePizzaOrPasta& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::FlexiblePizzaOrPasta::Tag Which() const {
    switch (tag_) {
      case ::test::union_::FlexiblePizzaOrPasta::Tag::Invalid:
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
        return ::test::union_::FlexiblePizzaOrPasta::Tag(tag_);
      default:
        return ::test::union_::FlexiblePizzaOrPasta::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::FlexiblePizzaOrPasta::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::FlexiblePizzaOrPasta>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid);
  union {
    ::test::union_::Pizza pizza_;
    ::test::union_::Pasta pasta_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::FlexiblePizzaOrPasta& value,
                         ::test::union_::FlexiblePizzaOrPasta* result) {
  return value.Clone(result);
}

using FlexiblePizzaOrPastaPtr = ::std::unique_ptr<FlexiblePizzaOrPasta>;

class ExplicitPizzaOrPasta final {
 public:
  static const fidl_type_t* FidlType;

  ExplicitPizzaOrPasta();
  ~ExplicitPizzaOrPasta();

  ExplicitPizzaOrPasta(ExplicitPizzaOrPasta&&);
  ExplicitPizzaOrPasta& operator=(ExplicitPizzaOrPasta&&);

  static ExplicitPizzaOrPasta WithPizza(::test::union_::Pizza&&);
  static ExplicitPizzaOrPasta WithPasta(::test::union_::Pasta&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kPizza = 1,  // 0x1
    kPasta = 4,  // 0x4
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ExplicitPizzaOrPasta> New() { return ::std::make_unique<ExplicitPizzaOrPasta>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExplicitPizzaOrPasta* value, size_t offset);
  zx_status_t Clone(ExplicitPizzaOrPasta* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_pizza() const { return tag_ == ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza; }

  ::test::union_::Pizza& pizza() {
    EnsureStorageInitialized(::test::union_::ExplicitPizzaOrPasta::Tag::kPizza);
    return pizza_;
  }

  const ::test::union_::Pizza& pizza() const {
    ZX_ASSERT(is_pizza());
    return pizza_;
  }
  ExplicitPizzaOrPasta& set_pizza(::test::union_::Pizza value);

  bool is_pasta() const { return tag_ == ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta; }

  ::test::union_::Pasta& pasta() {
    EnsureStorageInitialized(::test::union_::ExplicitPizzaOrPasta::Tag::kPasta);
    return pasta_;
  }

  const ::test::union_::Pasta& pasta() const {
    ZX_ASSERT(is_pasta());
    return pasta_;
  }
  ExplicitPizzaOrPasta& set_pasta(::test::union_::Pasta value);

  ::test::union_::ExplicitPizzaOrPasta::Tag Which() const {
    return ::test::union_::ExplicitPizzaOrPasta::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::ExplicitPizzaOrPasta>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid);
  union {
    ::test::union_::Pizza pizza_;
    ::test::union_::Pasta pasta_;
  };
};

inline zx_status_t Clone(const ::test::union_::ExplicitPizzaOrPasta& value,
                         ::test::union_::ExplicitPizzaOrPasta* result) {
  return value.Clone(result);
}

using ExplicitPizzaOrPastaPtr = ::std::unique_ptr<ExplicitPizzaOrPasta>;

class OlderSimpleUnion final {
 public:
  static const fidl_type_t* FidlType;

  OlderSimpleUnion();
  ~OlderSimpleUnion();

  OlderSimpleUnion(OlderSimpleUnion&&);
  OlderSimpleUnion& operator=(OlderSimpleUnion&&);

  static OlderSimpleUnion WithI(int64_t&&);
  static OlderSimpleUnion WithF(float&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kI = 1,  // 0x1
    kF = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<OlderSimpleUnion> New() { return ::std::make_unique<OlderSimpleUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, OlderSimpleUnion* value, size_t offset);
  zx_status_t Clone(OlderSimpleUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_i() const { return tag_ == ::test::union_::OlderSimpleUnion::Tag::kI; }

  int64_t& i() {
    EnsureStorageInitialized(::test::union_::OlderSimpleUnion::Tag::kI);
    return i_;
  }

  const int64_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  OlderSimpleUnion& set_i(int64_t value);

  bool is_f() const { return tag_ == ::test::union_::OlderSimpleUnion::Tag::kF; }

  float& f() {
    EnsureStorageInitialized(::test::union_::OlderSimpleUnion::Tag::kF);
    return f_;
  }

  const float& f() const {
    ZX_ASSERT(is_f());
    return f_;
  }
  OlderSimpleUnion& set_f(float value);
  OlderSimpleUnion& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::OlderSimpleUnion::Tag Which() const {
    switch (tag_) {
      case ::test::union_::OlderSimpleUnion::Tag::Invalid:
      case ::test::union_::OlderSimpleUnion::Tag::kI:
      case ::test::union_::OlderSimpleUnion::Tag::kF:
        return ::test::union_::OlderSimpleUnion::Tag(tag_);
      default:
        return ::test::union_::OlderSimpleUnion::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::OlderSimpleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::OlderSimpleUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid);
  union {
    int64_t i_;
    float f_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::OlderSimpleUnion& value,
                         ::test::union_::OlderSimpleUnion* result) {
  return value.Clone(result);
}

using OlderSimpleUnionPtr = ::std::unique_ptr<OlderSimpleUnion>;

class TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse final {
 public:
  static const fidl_type_t* FidlType;

  ::test::union_::OlderSimpleUnion xu{};

  static inline ::std::unique_ptr<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse> New() { return ::std::make_unique<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse* value, size_t _offset);
  zx_status_t Clone(TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse* result) const;
};

inline zx_status_t Clone(const ::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse& _value,
                         ::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse* _result) {
  return _value.Clone(_result);
}

using TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponsePtr = ::std::unique_ptr<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>;

#ifdef __Fuchsia__

class TestProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage StrictXUnionHenceResponseMayBeStackAllocated(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage FlexibleXUnionHenceResponseMustBeHeapAllocated(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;

}  // namespace _internal
class TestProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage StrictXUnionHenceResponseMayBeStackAllocated(::fidl::MessageEncoder* _encoder, ::test::union_::StrictBoundedXUnion* xu) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, xu, 0 + sizeof(fidl_message_header_t));

    fidl_trace(DidHLCPPEncode, &::test::union_::_internal::test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable, _encoder->GetPtr<const char>(0), _encoder->CurrentLength(), _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage FlexibleXUnionHenceResponseMustBeHeapAllocated(::fidl::MessageEncoder* _encoder, ::test::union_::OlderSimpleUnion* xu) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, xu, 0 + sizeof(fidl_message_header_t));

    fidl_trace(DidHLCPPEncode, &::test::union_::_internal::test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable, _encoder->GetPtr<const char>(0), _encoder->CurrentLength(), _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

class NullableUnionStruct final {
 public:
  static const fidl_type_t* FidlType;

  ::std::unique_ptr<::test::union_::Union> the_union{};

  static inline ::std::unique_ptr<NullableUnionStruct> New() { return ::std::make_unique<NullableUnionStruct>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, NullableUnionStruct* value, size_t _offset);
  zx_status_t Clone(NullableUnionStruct* result) const;
};

inline zx_status_t Clone(const ::test::union_::NullableUnionStruct& _value,
                         ::test::union_::NullableUnionStruct* _result) {
  return _value.Clone(_result);
}

using NullableUnionStructPtr = ::std::unique_ptr<NullableUnionStruct>;

class NewerSimpleUnion final {
 public:
  static const fidl_type_t* FidlType;

  NewerSimpleUnion();
  ~NewerSimpleUnion();

  NewerSimpleUnion(NewerSimpleUnion&&);
  NewerSimpleUnion& operator=(NewerSimpleUnion&&);

  static NewerSimpleUnion WithI(int64_t&&);
  static NewerSimpleUnion WithS(::std::string&&);
  static NewerSimpleUnion WithV(::std::vector<::std::string>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kI = 1,  // 0x1
    kS = 2,  // 0x2
    kV = 3,  // 0x3
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<NewerSimpleUnion> New() { return ::std::make_unique<NewerSimpleUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, NewerSimpleUnion* value, size_t offset);
  zx_status_t Clone(NewerSimpleUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_i() const { return tag_ == ::test::union_::NewerSimpleUnion::Tag::kI; }

  int64_t& i() {
    EnsureStorageInitialized(::test::union_::NewerSimpleUnion::Tag::kI);
    return i_;
  }

  const int64_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  NewerSimpleUnion& set_i(int64_t value);

  bool is_s() const { return tag_ == ::test::union_::NewerSimpleUnion::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::union_::NewerSimpleUnion::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  NewerSimpleUnion& set_s(::std::string value);

  bool is_v() const { return tag_ == ::test::union_::NewerSimpleUnion::Tag::kV; }

  ::std::vector<::std::string>& v() {
    EnsureStorageInitialized(::test::union_::NewerSimpleUnion::Tag::kV);
    return v_;
  }

  const ::std::vector<::std::string>& v() const {
    ZX_ASSERT(is_v());
    return v_;
  }
  NewerSimpleUnion& set_v(::std::vector<::std::string> value);
  NewerSimpleUnion& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::NewerSimpleUnion::Tag Which() const {
    switch (tag_) {
      case ::test::union_::NewerSimpleUnion::Tag::Invalid:
      case ::test::union_::NewerSimpleUnion::Tag::kI:
      case ::test::union_::NewerSimpleUnion::Tag::kS:
      case ::test::union_::NewerSimpleUnion::Tag::kV:
        return ::test::union_::NewerSimpleUnion::Tag(tag_);
      default:
        return ::test::union_::NewerSimpleUnion::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::NewerSimpleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::NewerSimpleUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid);
  union {
    int64_t i_;
    ::std::string s_;
    ::std::vector<::std::string> v_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::NewerSimpleUnion& value,
                         ::test::union_::NewerSimpleUnion* result) {
  return value.Clone(result);
}

using NewerSimpleUnionPtr = ::std::unique_ptr<NewerSimpleUnion>;

class FlexibleUnion final {
 public:
  static const fidl_type_t* FidlType;

  FlexibleUnion();
  ~FlexibleUnion();

  FlexibleUnion(FlexibleUnion&&);
  FlexibleUnion& operator=(FlexibleUnion&&);

  static FlexibleUnion WithPrimitive(int32_t&&);
  static FlexibleUnion WithStringNeedsConstructor(::std::string&&);
  static FlexibleUnion WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kPrimitive = 1,                         // 0x1
    kStringNeedsConstructor = 2,            // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<FlexibleUnion> New() { return ::std::make_unique<FlexibleUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, FlexibleUnion* value, size_t offset);
  zx_status_t Clone(FlexibleUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_Primitive() const { return tag_ == ::test::union_::FlexibleUnion::Tag::kPrimitive; }

  int32_t& Primitive() {
    EnsureStorageInitialized(::test::union_::FlexibleUnion::Tag::kPrimitive);
    return Primitive_;
  }

  const int32_t& Primitive() const {
    ZX_ASSERT(is_Primitive());
    return Primitive_;
  }
  FlexibleUnion& set_Primitive(int32_t value);

  bool is_StringNeedsConstructor() const { return tag_ == ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor; }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor);
    return StringNeedsConstructor_;
  }

  const ::std::string& StringNeedsConstructor() const {
    ZX_ASSERT(is_StringNeedsConstructor());
    return StringNeedsConstructor_;
  }
  FlexibleUnion& set_StringNeedsConstructor(::std::string value);

  bool is_VectorStringAlsoNeedsConstructor() const { return tag_ == ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor; }

  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor);
    return VectorStringAlsoNeedsConstructor_;
  }

  const ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() const {
    ZX_ASSERT(is_VectorStringAlsoNeedsConstructor());
    return VectorStringAlsoNeedsConstructor_;
  }
  FlexibleUnion& set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value);
  FlexibleUnion& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::FlexibleUnion::Tag Which() const {
    switch (tag_) {
      case ::test::union_::FlexibleUnion::Tag::Invalid:
      case ::test::union_::FlexibleUnion::Tag::kPrimitive:
      case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
      case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        return ::test::union_::FlexibleUnion::Tag(tag_);
      default:
        return ::test::union_::FlexibleUnion::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::FlexibleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::FlexibleUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid);
  union {
    int32_t Primitive_;
    ::std::string StringNeedsConstructor_;
    ::std::vector<::std::string> VectorStringAlsoNeedsConstructor_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::FlexibleUnion& value,
                         ::test::union_::FlexibleUnion* result) {
  return value.Clone(result);
}

using FlexibleUnionPtr = ::std::unique_ptr<FlexibleUnion>;

class FlexibleFoo final {
 public:
  static const fidl_type_t* FidlType;

  FlexibleFoo();
  ~FlexibleFoo();

  FlexibleFoo(FlexibleFoo&&);
  FlexibleFoo& operator=(FlexibleFoo&&);

  static FlexibleFoo WithS(::std::string&&);
  static FlexibleFoo WithI(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kS = 1,  // 0x1
    kI = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<FlexibleFoo> New() { return ::std::make_unique<FlexibleFoo>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, FlexibleFoo* value, size_t offset);
  zx_status_t Clone(FlexibleFoo* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_s() const { return tag_ == ::test::union_::FlexibleFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::union_::FlexibleFoo::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  FlexibleFoo& set_s(::std::string value);

  bool is_i() const { return tag_ == ::test::union_::FlexibleFoo::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::union_::FlexibleFoo::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  FlexibleFoo& set_i(int32_t value);
  FlexibleFoo& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::FlexibleFoo::Tag Which() const {
    switch (tag_) {
      case ::test::union_::FlexibleFoo::Tag::Invalid:
      case ::test::union_::FlexibleFoo::Tag::kS:
      case ::test::union_::FlexibleFoo::Tag::kI:
        return ::test::union_::FlexibleFoo::Tag(tag_);
      default:
        return ::test::union_::FlexibleFoo::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::FlexibleFoo::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::FlexibleFoo>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid);
  union {
    ::std::string s_;
    int32_t i_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::FlexibleFoo& value,
                         ::test::union_::FlexibleFoo* result) {
  return value.Clone(result);
}

using FlexibleFooPtr = ::std::unique_ptr<FlexibleFoo>;

class FieldCollision final {
 public:
  static const fidl_type_t* FidlType;

  FieldCollision();
  ~FieldCollision();

  FieldCollision(FieldCollision&&);
  FieldCollision& operator=(FieldCollision&&);

  static FieldCollision WithFieldCollisionTag(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kFieldCollisionTag = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<FieldCollision> New() { return ::std::make_unique<FieldCollision>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, FieldCollision* value, size_t offset);
  zx_status_t Clone(FieldCollision* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_field_collision_tag() const { return tag_ == ::test::union_::FieldCollision::Tag::kFieldCollisionTag; }

  int32_t& field_collision_tag() {
    EnsureStorageInitialized(::test::union_::FieldCollision::Tag::kFieldCollisionTag);
    return field_collision_tag_;
  }

  const int32_t& field_collision_tag() const {
    ZX_ASSERT(is_field_collision_tag());
    return field_collision_tag_;
  }
  FieldCollision& set_field_collision_tag(int32_t value);

  ::test::union_::FieldCollision::Tag Which() const {
    return ::test::union_::FieldCollision::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::FieldCollision>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid);
  union {
    int32_t field_collision_tag_;
  };
};

inline zx_status_t Clone(const ::test::union_::FieldCollision& value,
                         ::test::union_::FieldCollision* result) {
  return value.Clone(result);
}

using FieldCollisionPtr = ::std::unique_ptr<FieldCollision>;

class ExplicitXUnion final {
 public:
  static const fidl_type_t* FidlType;

  ExplicitXUnion();
  ~ExplicitXUnion();

  ExplicitXUnion(ExplicitXUnion&&);
  ExplicitXUnion& operator=(ExplicitXUnion&&);

  static ExplicitXUnion WithI(int64_t&&);
  static ExplicitXUnion WithF(float&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kI = 1,  // 0x1
    kF = 4,  // 0x4
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ExplicitXUnion> New() { return ::std::make_unique<ExplicitXUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExplicitXUnion* value, size_t offset);
  zx_status_t Clone(ExplicitXUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_i() const { return tag_ == ::test::union_::ExplicitXUnion::Tag::kI; }

  int64_t& i() {
    EnsureStorageInitialized(::test::union_::ExplicitXUnion::Tag::kI);
    return i_;
  }

  const int64_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  ExplicitXUnion& set_i(int64_t value);

  bool is_f() const { return tag_ == ::test::union_::ExplicitXUnion::Tag::kF; }

  float& f() {
    EnsureStorageInitialized(::test::union_::ExplicitXUnion::Tag::kF);
    return f_;
  }

  const float& f() const {
    ZX_ASSERT(is_f());
    return f_;
  }
  ExplicitXUnion& set_f(float value);
  ExplicitXUnion& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::ExplicitXUnion::Tag Which() const {
    switch (tag_) {
      case ::test::union_::ExplicitXUnion::Tag::Invalid:
      case ::test::union_::ExplicitXUnion::Tag::kI:
      case ::test::union_::ExplicitXUnion::Tag::kF:
        return ::test::union_::ExplicitXUnion::Tag(tag_);
      default:
        return ::test::union_::ExplicitXUnion::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::ExplicitXUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::ExplicitXUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid);
  union {
    int64_t i_;
    float f_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::ExplicitXUnion& value,
                         ::test::union_::ExplicitXUnion* result) {
  return value.Clone(result);
}

using ExplicitXUnionPtr = ::std::unique_ptr<ExplicitXUnion>;

class UnionSandwich final {
 public:
  static const fidl_type_t* FidlType;

  uint32_t a{};

  ::test::union_::ExplicitXUnion u{};

  uint32_t b{};

  static inline ::std::unique_ptr<UnionSandwich> New() { return ::std::make_unique<UnionSandwich>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, UnionSandwich* value, size_t _offset);
  zx_status_t Clone(UnionSandwich* result) const;
};

inline zx_status_t Clone(const ::test::union_::UnionSandwich& _value,
                         ::test::union_::UnionSandwich* _result) {
  return _value.Clone(_result);
}

using UnionSandwichPtr = ::std::unique_ptr<UnionSandwich>;

class ExplicitUnion final {
 public:
  static const fidl_type_t* FidlType;

  ExplicitUnion();
  ~ExplicitUnion();

  ExplicitUnion(ExplicitUnion&&);
  ExplicitUnion& operator=(ExplicitUnion&&);

  static ExplicitUnion WithPrimitive(int32_t&&);
  static ExplicitUnion WithStringNeedsConstructor(::std::string&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kPrimitive = 1,               // 0x1
    kStringNeedsConstructor = 3,  // 0x3
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ExplicitUnion> New() { return ::std::make_unique<ExplicitUnion>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExplicitUnion* value, size_t offset);
  zx_status_t Clone(ExplicitUnion* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_Primitive() const { return tag_ == ::test::union_::ExplicitUnion::Tag::kPrimitive; }

  int32_t& Primitive() {
    EnsureStorageInitialized(::test::union_::ExplicitUnion::Tag::kPrimitive);
    return Primitive_;
  }

  const int32_t& Primitive() const {
    ZX_ASSERT(is_Primitive());
    return Primitive_;
  }
  ExplicitUnion& set_Primitive(int32_t value);

  bool is_StringNeedsConstructor() const { return tag_ == ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor; }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor);
    return StringNeedsConstructor_;
  }

  const ::std::string& StringNeedsConstructor() const {
    ZX_ASSERT(is_StringNeedsConstructor());
    return StringNeedsConstructor_;
  }
  ExplicitUnion& set_StringNeedsConstructor(::std::string value);

  ::test::union_::ExplicitUnion::Tag Which() const {
    return ::test::union_::ExplicitUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::ExplicitUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid);
  union {
    int32_t Primitive_;
    ::std::string StringNeedsConstructor_;
  };
};

inline zx_status_t Clone(const ::test::union_::ExplicitUnion& value,
                         ::test::union_::ExplicitUnion* result) {
  return value.Clone(result);
}

using ExplicitUnionPtr = ::std::unique_ptr<ExplicitUnion>;

class ExplicitStrictFoo final {
 public:
  static const fidl_type_t* FidlType;

  ExplicitStrictFoo();
  ~ExplicitStrictFoo();

  ExplicitStrictFoo(ExplicitStrictFoo&&);
  ExplicitStrictFoo& operator=(ExplicitStrictFoo&&);

  static ExplicitStrictFoo WithS(::std::string&&);
  static ExplicitStrictFoo WithI(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kS = 3,  // 0x3
    kI = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ExplicitStrictFoo> New() { return ::std::make_unique<ExplicitStrictFoo>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExplicitStrictFoo* value, size_t offset);
  zx_status_t Clone(ExplicitStrictFoo* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_s() const { return tag_ == ::test::union_::ExplicitStrictFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::union_::ExplicitStrictFoo::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  ExplicitStrictFoo& set_s(::std::string value);

  bool is_i() const { return tag_ == ::test::union_::ExplicitStrictFoo::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::union_::ExplicitStrictFoo::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  ExplicitStrictFoo& set_i(int32_t value);

  ::test::union_::ExplicitStrictFoo::Tag Which() const {
    return ::test::union_::ExplicitStrictFoo::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::union_::ExplicitStrictFoo>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid);
  union {
    ::std::string s_;
    int32_t i_;
  };
};

inline zx_status_t Clone(const ::test::union_::ExplicitStrictFoo& value,
                         ::test::union_::ExplicitStrictFoo* result) {
  return value.Clone(result);
}

using ExplicitStrictFooPtr = ::std::unique_ptr<ExplicitStrictFoo>;

class ExplicitFoo final {
 public:
  static const fidl_type_t* FidlType;

  ExplicitFoo();
  ~ExplicitFoo();

  ExplicitFoo(ExplicitFoo&&);
  ExplicitFoo& operator=(ExplicitFoo&&);

  static ExplicitFoo WithS(::std::string&&);
  static ExplicitFoo WithI(int32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kS = 2,  // 0x2
    kI = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ExplicitFoo> New() { return ::std::make_unique<ExplicitFoo>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExplicitFoo* value, size_t offset);
  zx_status_t Clone(ExplicitFoo* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_s() const { return tag_ == ::test::union_::ExplicitFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::union_::ExplicitFoo::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  ExplicitFoo& set_s(::std::string value);

  bool is_i() const { return tag_ == ::test::union_::ExplicitFoo::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::union_::ExplicitFoo::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  ExplicitFoo& set_i(int32_t value);
  ExplicitFoo& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::ExplicitFoo::Tag Which() const {
    switch (tag_) {
      case ::test::union_::ExplicitFoo::Tag::Invalid:
      case ::test::union_::ExplicitFoo::Tag::kS:
      case ::test::union_::ExplicitFoo::Tag::kI:
        return ::test::union_::ExplicitFoo::Tag(tag_);
      default:
        return ::test::union_::ExplicitFoo::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::ExplicitFoo::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::ExplicitFoo>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid);
  union {
    ::std::string s_;
    int32_t i_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::ExplicitFoo& value,
                         ::test::union_::ExplicitFoo* result) {
  return value.Clone(result);
}

using ExplicitFooPtr = ::std::unique_ptr<ExplicitFoo>;

class Empty final {
 public:
  static const fidl_type_t* FidlType;

  uint8_t __reserved = 0u;

  static inline ::std::unique_ptr<Empty> New() { return ::std::make_unique<Empty>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Empty* value, size_t _offset);
  zx_status_t Clone(Empty* result) const;
};

inline zx_status_t Clone(const ::test::union_::Empty& _value,
                         ::test::union_::Empty* _result) {
  return _value.Clone(_result);
}

using EmptyPtr = ::std::unique_ptr<Empty>;

class XUnionContainingEmptyStruct final {
 public:
  static const fidl_type_t* FidlType;

  XUnionContainingEmptyStruct();
  ~XUnionContainingEmptyStruct();

  XUnionContainingEmptyStruct(XUnionContainingEmptyStruct&&);
  XUnionContainingEmptyStruct& operator=(XUnionContainingEmptyStruct&&);

  static XUnionContainingEmptyStruct WithEmpty(::test::union_::Empty&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kEmpty = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<XUnionContainingEmptyStruct> New() { return ::std::make_unique<XUnionContainingEmptyStruct>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, XUnionContainingEmptyStruct* value, size_t offset);
  zx_status_t Clone(XUnionContainingEmptyStruct* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_empty() const { return tag_ == ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty; }

  ::test::union_::Empty& empty() {
    EnsureStorageInitialized(::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty);
    return empty_;
  }

  const ::test::union_::Empty& empty() const {
    ZX_ASSERT(is_empty());
    return empty_;
  }
  XUnionContainingEmptyStruct& set_empty(::test::union_::Empty value);
  XUnionContainingEmptyStruct& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::union_::XUnionContainingEmptyStruct::Tag Which() const {
    switch (tag_) {
      case ::test::union_::XUnionContainingEmptyStruct::Tag::Invalid:
      case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
        return ::test::union_::XUnionContainingEmptyStruct::Tag(tag_);
      default:
        return ::test::union_::XUnionContainingEmptyStruct::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::union_::XUnionContainingEmptyStruct::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::union_::XUnionContainingEmptyStruct>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid);
  union {
    ::test::union_::Empty empty_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::union_::XUnionContainingEmptyStruct& value,
                         ::test::union_::XUnionContainingEmptyStruct* result) {
  return value.Clone(result);
}

using XUnionContainingEmptyStructPtr = ::std::unique_ptr<XUnionContainingEmptyStruct>;

}  // namespace union_
}  // namespace test
namespace fidl {
template <>
struct IsFidlXUnion<::test::union_::UnionWithAttributes> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::UnionWithAttributes>
    : public EncodableCodingTraits<::test::union_::UnionWithAttributes, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::UnionWithAttributes>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::UnionWithAttributes>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::UnionWithAttributes>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::UnionWithAttributes);

    ::test::union_::UnionWithAttributes::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::UnionWithAttributes& value,
                         ::test::union_::UnionWithAttributes* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::UnionWithAttributes> {
  bool operator()(const ::test::union_::UnionWithAttributes& _lhs, const ::test::union_::UnionWithAttributes& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid):
        return true;
      case ::test::union_::UnionWithAttributes::Tag::kX:
        return ::fidl::Equals(_lhs.x_, _rhs.x_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::Union> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::Union>
    : public EncodableCodingTraits<::test::union_::Union, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::Union>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::Union>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::Union>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::Union);

    ::test::union_::Union::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::Union& value,
                         ::test::union_::Union* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::Union> {
  bool operator()(const ::test::union_::Union& _lhs, const ::test::union_::Union& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid):
        return true;
      case ::test::union_::Union::Tag::kPrimitive:
        return ::fidl::Equals(_lhs.Primitive_, _rhs.Primitive_);
      case ::test::union_::Union::Tag::kStringNeedsConstructor:
        return ::fidl::Equals(_lhs.StringNeedsConstructor_, _rhs.StringNeedsConstructor_);
      case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
        return ::fidl::Equals(_lhs.VectorStringAlsoNeedsConstructor_, _rhs.VectorStringAlsoNeedsConstructor_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::union_::StructWithNullableXUnion>
    : public EncodableCodingTraits<::test::union_::StructWithNullableXUnion, 16> {};

template <>
struct HasPadding<::test::union_::StructWithNullableXUnion> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::StructWithNullableXUnion> : public internal::BoolConstant<
                                                                          !HasPadding<::test::union_::StructWithNullableXUnion>::value && IsMemcpyCompatible<::std::unique_ptr<::test::union_::OlderSimpleUnion>>::value> {};

inline zx_status_t Clone(const ::test::union_::StructWithNullableXUnion& value,
                         ::test::union_::StructWithNullableXUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::StructWithNullableXUnion> {
  bool operator()(const ::test::union_::StructWithNullableXUnion& _lhs, const ::test::union_::StructWithNullableXUnion& _rhs) const {
    if (!::fidl::Equals(_lhs.x1, _rhs.x1)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::union_::StrictUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::StrictUnion>
    : public EncodableCodingTraits<::test::union_::StrictUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::StrictUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::StrictUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::StrictUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::StrictUnion);

    ::test::union_::StrictUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::StrictUnion& value,
                         ::test::union_::StrictUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::StrictUnion> {
  bool operator()(const ::test::union_::StrictUnion& _lhs, const ::test::union_::StrictUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid):
        return true;
      case ::test::union_::StrictUnion::Tag::kPrimitive:
        return ::fidl::Equals(_lhs.Primitive_, _rhs.Primitive_);
      case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
        return ::fidl::Equals(_lhs.StringNeedsConstructor_, _rhs.StringNeedsConstructor_);
      case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
        return ::fidl::Equals(_lhs.VectorStringAlsoNeedsConstructor_, _rhs.VectorStringAlsoNeedsConstructor_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::StrictSimpleXUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::StrictSimpleXUnion>
    : public EncodableCodingTraits<::test::union_::StrictSimpleXUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::StrictSimpleXUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::StrictSimpleXUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::StrictSimpleXUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::StrictSimpleXUnion);

    ::test::union_::StrictSimpleXUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::StrictSimpleXUnion& value,
                         ::test::union_::StrictSimpleXUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::StrictSimpleXUnion> {
  bool operator()(const ::test::union_::StrictSimpleXUnion& _lhs, const ::test::union_::StrictSimpleXUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid):
        return true;
      case ::test::union_::StrictSimpleXUnion::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      case ::test::union_::StrictSimpleXUnion::Tag::kF:
        return ::fidl::Equals(_lhs.f_, _rhs.f_);
      case ::test::union_::StrictSimpleXUnion::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::StrictFoo> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::StrictFoo>
    : public EncodableCodingTraits<::test::union_::StrictFoo, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::StrictFoo>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::StrictFoo>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::StrictFoo>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::StrictFoo);

    ::test::union_::StrictFoo::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::StrictFoo& value,
                         ::test::union_::StrictFoo* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::StrictFoo> {
  bool operator()(const ::test::union_::StrictFoo& _lhs, const ::test::union_::StrictFoo& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid):
        return true;
      case ::test::union_::StrictFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::union_::StrictFoo::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::StrictBoundedXUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::StrictBoundedXUnion>
    : public EncodableCodingTraits<::test::union_::StrictBoundedXUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::StrictBoundedXUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::StrictBoundedXUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::StrictBoundedXUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::StrictBoundedXUnion);

    ::test::union_::StrictBoundedXUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::StrictBoundedXUnion& value,
                         ::test::union_::StrictBoundedXUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::StrictBoundedXUnion> {
  bool operator()(const ::test::union_::StrictBoundedXUnion& _lhs, const ::test::union_::StrictBoundedXUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid):
        return true;
      case ::test::union_::StrictBoundedXUnion::Tag::kV:
        return ::fidl::Equals(_lhs.v_, _rhs.v_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>
    : public EncodableCodingTraits<::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse, 16> {};

template <>
struct HasPadding<::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse> : public internal::BoolConstant<
                                                                                                                     !HasPadding<::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>::value && IsMemcpyCompatible<::test::union_::StrictBoundedXUnion>::value> {};

inline zx_status_t Clone(const ::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse& value,
                         ::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse> {
  bool operator()(const ::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse& _lhs, const ::test::union_::TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.xu, _rhs.xu)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::union_::ReverseOrdinalUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::ReverseOrdinalUnion>
    : public EncodableCodingTraits<::test::union_::ReverseOrdinalUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::ReverseOrdinalUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::ReverseOrdinalUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::ReverseOrdinalUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::ReverseOrdinalUnion);

    ::test::union_::ReverseOrdinalUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::ReverseOrdinalUnion& value,
                         ::test::union_::ReverseOrdinalUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::ReverseOrdinalUnion> {
  bool operator()(const ::test::union_::ReverseOrdinalUnion& _lhs, const ::test::union_::ReverseOrdinalUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid):
        return true;
      case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
        return ::fidl::Equals(_lhs.second_, _rhs.second_);
      case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
        return ::fidl::Equals(_lhs.first_, _rhs.first_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::union_::Pizza>
    : public EncodableCodingTraits<::test::union_::Pizza, 16> {};

template <>
struct HasPadding<::test::union_::Pizza> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::Pizza> : public internal::BoolConstant<
                                                       !HasPadding<::test::union_::Pizza>::value && IsMemcpyCompatible<::std::vector<::std::string>>::value> {};

inline zx_status_t Clone(const ::test::union_::Pizza& value,
                         ::test::union_::Pizza* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::Pizza> {
  bool operator()(const ::test::union_::Pizza& _lhs, const ::test::union_::Pizza& _rhs) const {
    if (!::fidl::Equals(_lhs.toppings, _rhs.toppings)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::union_::Pasta>
    : public EncodableCodingTraits<::test::union_::Pasta, 16> {};

template <>
struct HasPadding<::test::union_::Pasta> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::Pasta> : public internal::BoolConstant<
                                                       !HasPadding<::test::union_::Pasta>::value && IsMemcpyCompatible<::std::string>::value> {};

inline zx_status_t Clone(const ::test::union_::Pasta& value,
                         ::test::union_::Pasta* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::Pasta> {
  bool operator()(const ::test::union_::Pasta& _lhs, const ::test::union_::Pasta& _rhs) const {
    if (!::fidl::Equals(_lhs.sauce, _rhs.sauce)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::union_::StrictPizzaOrPasta> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::StrictPizzaOrPasta>
    : public EncodableCodingTraits<::test::union_::StrictPizzaOrPasta, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::StrictPizzaOrPasta>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::StrictPizzaOrPasta>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::StrictPizzaOrPasta>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::StrictPizzaOrPasta);

    ::test::union_::StrictPizzaOrPasta::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::StrictPizzaOrPasta& value,
                         ::test::union_::StrictPizzaOrPasta* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::StrictPizzaOrPasta> {
  bool operator()(const ::test::union_::StrictPizzaOrPasta& _lhs, const ::test::union_::StrictPizzaOrPasta& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid):
        return true;
      case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
        return ::fidl::Equals(_lhs.pizza_, _rhs.pizza_);
      case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
        return ::fidl::Equals(_lhs.pasta_, _rhs.pasta_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::PizzaOrPasta> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::PizzaOrPasta>
    : public EncodableCodingTraits<::test::union_::PizzaOrPasta, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::PizzaOrPasta>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::PizzaOrPasta>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::PizzaOrPasta>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::PizzaOrPasta);

    ::test::union_::PizzaOrPasta::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::PizzaOrPasta& value,
                         ::test::union_::PizzaOrPasta* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::PizzaOrPasta> {
  bool operator()(const ::test::union_::PizzaOrPasta& _lhs, const ::test::union_::PizzaOrPasta& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid):
        return true;
      case ::test::union_::PizzaOrPasta::Tag::kPizza:
        return ::fidl::Equals(_lhs.pizza_, _rhs.pizza_);
      case ::test::union_::PizzaOrPasta::Tag::kPasta:
        return ::fidl::Equals(_lhs.pasta_, _rhs.pasta_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::FlexiblePizzaOrPasta> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::FlexiblePizzaOrPasta>
    : public EncodableCodingTraits<::test::union_::FlexiblePizzaOrPasta, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::FlexiblePizzaOrPasta>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::FlexiblePizzaOrPasta>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::FlexiblePizzaOrPasta>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::FlexiblePizzaOrPasta);

    ::test::union_::FlexiblePizzaOrPasta::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::FlexiblePizzaOrPasta& value,
                         ::test::union_::FlexiblePizzaOrPasta* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::FlexiblePizzaOrPasta> {
  bool operator()(const ::test::union_::FlexiblePizzaOrPasta& _lhs, const ::test::union_::FlexiblePizzaOrPasta& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
        return true;
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
        return ::fidl::Equals(_lhs.pizza_, _rhs.pizza_);
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
        return ::fidl::Equals(_lhs.pasta_, _rhs.pasta_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::ExplicitPizzaOrPasta> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::ExplicitPizzaOrPasta>
    : public EncodableCodingTraits<::test::union_::ExplicitPizzaOrPasta, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::ExplicitPizzaOrPasta>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::ExplicitPizzaOrPasta>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::ExplicitPizzaOrPasta>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::ExplicitPizzaOrPasta);

    ::test::union_::ExplicitPizzaOrPasta::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::ExplicitPizzaOrPasta& value,
                         ::test::union_::ExplicitPizzaOrPasta* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::ExplicitPizzaOrPasta> {
  bool operator()(const ::test::union_::ExplicitPizzaOrPasta& _lhs, const ::test::union_::ExplicitPizzaOrPasta& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid):
        return true;
      case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
        return ::fidl::Equals(_lhs.pizza_, _rhs.pizza_);
      case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
        return ::fidl::Equals(_lhs.pasta_, _rhs.pasta_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::OlderSimpleUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::OlderSimpleUnion>
    : public EncodableCodingTraits<::test::union_::OlderSimpleUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::OlderSimpleUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::OlderSimpleUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::OlderSimpleUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::OlderSimpleUnion);

    ::test::union_::OlderSimpleUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::OlderSimpleUnion& value,
                         ::test::union_::OlderSimpleUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::OlderSimpleUnion> {
  bool operator()(const ::test::union_::OlderSimpleUnion& _lhs, const ::test::union_::OlderSimpleUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid):
        return true;
      case ::test::union_::OlderSimpleUnion::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      case ::test::union_::OlderSimpleUnion::Tag::kF:
        return ::fidl::Equals(_lhs.f_, _rhs.f_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>
    : public EncodableCodingTraits<::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse, 16> {};

template <>
struct HasPadding<::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse> : public internal::BoolConstant<
                                                                                                                       !HasPadding<::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>::value && IsMemcpyCompatible<::test::union_::OlderSimpleUnion>::value> {};

inline zx_status_t Clone(const ::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse& value,
                         ::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse> {
  bool operator()(const ::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse& _lhs, const ::test::union_::TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.xu, _rhs.xu)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::union_::NullableUnionStruct>
    : public EncodableCodingTraits<::test::union_::NullableUnionStruct, 16> {};

template <>
struct HasPadding<::test::union_::NullableUnionStruct> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::NullableUnionStruct> : public internal::BoolConstant<
                                                                     !HasPadding<::test::union_::NullableUnionStruct>::value && IsMemcpyCompatible<::std::unique_ptr<::test::union_::Union>>::value> {};

inline zx_status_t Clone(const ::test::union_::NullableUnionStruct& value,
                         ::test::union_::NullableUnionStruct* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::NullableUnionStruct> {
  bool operator()(const ::test::union_::NullableUnionStruct& _lhs, const ::test::union_::NullableUnionStruct& _rhs) const {
    if (!::fidl::Equals(_lhs.the_union, _rhs.the_union)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::union_::NewerSimpleUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::NewerSimpleUnion>
    : public EncodableCodingTraits<::test::union_::NewerSimpleUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::NewerSimpleUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::NewerSimpleUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::NewerSimpleUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::NewerSimpleUnion);

    ::test::union_::NewerSimpleUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::NewerSimpleUnion& value,
                         ::test::union_::NewerSimpleUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::NewerSimpleUnion> {
  bool operator()(const ::test::union_::NewerSimpleUnion& _lhs, const ::test::union_::NewerSimpleUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid):
        return true;
      case ::test::union_::NewerSimpleUnion::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      case ::test::union_::NewerSimpleUnion::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::union_::NewerSimpleUnion::Tag::kV:
        return ::fidl::Equals(_lhs.v_, _rhs.v_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::FlexibleUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::FlexibleUnion>
    : public EncodableCodingTraits<::test::union_::FlexibleUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::FlexibleUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::FlexibleUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::FlexibleUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::FlexibleUnion);

    ::test::union_::FlexibleUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::FlexibleUnion& value,
                         ::test::union_::FlexibleUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::FlexibleUnion> {
  bool operator()(const ::test::union_::FlexibleUnion& _lhs, const ::test::union_::FlexibleUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid):
        return true;
      case ::test::union_::FlexibleUnion::Tag::kPrimitive:
        return ::fidl::Equals(_lhs.Primitive_, _rhs.Primitive_);
      case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
        return ::fidl::Equals(_lhs.StringNeedsConstructor_, _rhs.StringNeedsConstructor_);
      case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        return ::fidl::Equals(_lhs.VectorStringAlsoNeedsConstructor_, _rhs.VectorStringAlsoNeedsConstructor_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::FlexibleFoo> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::FlexibleFoo>
    : public EncodableCodingTraits<::test::union_::FlexibleFoo, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::FlexibleFoo>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::FlexibleFoo>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::FlexibleFoo>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::FlexibleFoo);

    ::test::union_::FlexibleFoo::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::FlexibleFoo& value,
                         ::test::union_::FlexibleFoo* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::FlexibleFoo> {
  bool operator()(const ::test::union_::FlexibleFoo& _lhs, const ::test::union_::FlexibleFoo& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid):
        return true;
      case ::test::union_::FlexibleFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::union_::FlexibleFoo::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::FieldCollision> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::FieldCollision>
    : public EncodableCodingTraits<::test::union_::FieldCollision, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::FieldCollision>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::FieldCollision>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::FieldCollision>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::FieldCollision);

    ::test::union_::FieldCollision::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::FieldCollision& value,
                         ::test::union_::FieldCollision* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::FieldCollision> {
  bool operator()(const ::test::union_::FieldCollision& _lhs, const ::test::union_::FieldCollision& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid):
        return true;
      case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
        return ::fidl::Equals(_lhs.field_collision_tag_, _rhs.field_collision_tag_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::ExplicitXUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::ExplicitXUnion>
    : public EncodableCodingTraits<::test::union_::ExplicitXUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::ExplicitXUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::ExplicitXUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::ExplicitXUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::ExplicitXUnion);

    ::test::union_::ExplicitXUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::ExplicitXUnion& value,
                         ::test::union_::ExplicitXUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::ExplicitXUnion> {
  bool operator()(const ::test::union_::ExplicitXUnion& _lhs, const ::test::union_::ExplicitXUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid):
        return true;
      case ::test::union_::ExplicitXUnion::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      case ::test::union_::ExplicitXUnion::Tag::kF:
        return ::fidl::Equals(_lhs.f_, _rhs.f_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::union_::UnionSandwich>
    : public EncodableCodingTraits<::test::union_::UnionSandwich, 32> {};

template <>
struct HasPadding<::test::union_::UnionSandwich> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::union_::UnionSandwich> : public internal::BoolConstant<
                                                               !HasPadding<::test::union_::UnionSandwich>::value && IsMemcpyCompatible<uint32_t>::value && IsMemcpyCompatible<::test::union_::ExplicitXUnion>::value> {};

inline zx_status_t Clone(const ::test::union_::UnionSandwich& value,
                         ::test::union_::UnionSandwich* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::UnionSandwich> {
  bool operator()(const ::test::union_::UnionSandwich& _lhs, const ::test::union_::UnionSandwich& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.u, _rhs.u)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::union_::ExplicitUnion> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::ExplicitUnion>
    : public EncodableCodingTraits<::test::union_::ExplicitUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::ExplicitUnion>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::ExplicitUnion>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::ExplicitUnion>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::ExplicitUnion);

    ::test::union_::ExplicitUnion::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::ExplicitUnion& value,
                         ::test::union_::ExplicitUnion* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::ExplicitUnion> {
  bool operator()(const ::test::union_::ExplicitUnion& _lhs, const ::test::union_::ExplicitUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid):
        return true;
      case ::test::union_::ExplicitUnion::Tag::kPrimitive:
        return ::fidl::Equals(_lhs.Primitive_, _rhs.Primitive_);
      case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
        return ::fidl::Equals(_lhs.StringNeedsConstructor_, _rhs.StringNeedsConstructor_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::ExplicitStrictFoo> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::ExplicitStrictFoo>
    : public EncodableCodingTraits<::test::union_::ExplicitStrictFoo, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::ExplicitStrictFoo>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::ExplicitStrictFoo>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::ExplicitStrictFoo>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::ExplicitStrictFoo);

    ::test::union_::ExplicitStrictFoo::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::ExplicitStrictFoo& value,
                         ::test::union_::ExplicitStrictFoo* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::ExplicitStrictFoo> {
  bool operator()(const ::test::union_::ExplicitStrictFoo& _lhs, const ::test::union_::ExplicitStrictFoo& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid):
        return true;
      case ::test::union_::ExplicitStrictFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::union_::ExplicitStrictFoo::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::test::union_::ExplicitFoo> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::ExplicitFoo>
    : public EncodableCodingTraits<::test::union_::ExplicitFoo, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::ExplicitFoo>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::ExplicitFoo>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::ExplicitFoo>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::ExplicitFoo);

    ::test::union_::ExplicitFoo::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::ExplicitFoo& value,
                         ::test::union_::ExplicitFoo* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::ExplicitFoo> {
  bool operator()(const ::test::union_::ExplicitFoo& _lhs, const ::test::union_::ExplicitFoo& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid):
        return true;
      case ::test::union_::ExplicitFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::union_::ExplicitFoo::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::union_::Empty>
    : public EncodableCodingTraits<::test::union_::Empty, 1> {};

template <>
struct IsMemcpyCompatible<::test::union_::Empty> : public internal::BoolConstant<
                                                       !HasPadding<::test::union_::Empty>::value && IsMemcpyCompatible<uint8_t>::value> {};

inline zx_status_t Clone(const ::test::union_::Empty& value,
                         ::test::union_::Empty* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::Empty> {
  bool operator()(const ::test::union_::Empty& _lhs, const ::test::union_::Empty& _rhs) const {
    if (!::fidl::Equals(_lhs.__reserved, _rhs.__reserved)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::union_::XUnionContainingEmptyStruct> : public std::true_type {};

template <>
struct CodingTraits<::test::union_::XUnionContainingEmptyStruct>
    : public EncodableCodingTraits<::test::union_::XUnionContainingEmptyStruct, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::union_::XUnionContainingEmptyStruct>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::union_::XUnionContainingEmptyStruct>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::union_::XUnionContainingEmptyStruct>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::union_::XUnionContainingEmptyStruct);

    ::test::union_::XUnionContainingEmptyStruct::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::union_::XUnionContainingEmptyStruct& value,
                         ::test::union_::XUnionContainingEmptyStruct* result) {
  return ::test::union_::Clone(value, result);
}

template <>
struct Equality<::test::union_::XUnionContainingEmptyStruct> {
  bool operator()(const ::test::union_::XUnionContainingEmptyStruct& _lhs, const ::test::union_::XUnionContainingEmptyStruct& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid):
        return true;
      case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
        return ::fidl::Equals(_lhs.empty_, _rhs.empty_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace union_ {
#ifdef __Fuchsia__

using TestProtocolPtr = ::fidl::InterfacePtr<TestProtocol>;
class TestProtocol_Proxy;
class TestProtocol_Stub;
class TestProtocol_EventSender;
class TestProtocol_Sync;
using TestProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<TestProtocol>;
class TestProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal = 0x816ec730baa90ddlu;
constexpr ::fidl::MessageDynamicFlags kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal = 0x6ad517317388ea05lu;
constexpr ::fidl::MessageDynamicFlags kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class TestProtocol {
 public:
  using Proxy_ = ::test::union_::TestProtocol_Proxy;
  using Stub_ = ::test::union_::TestProtocol_Stub;
  using EventSender_ = ::test::union_::TestProtocol_EventSender;
  using Sync_ = ::test::union_::TestProtocol_Sync;
  virtual ~TestProtocol();
  using StrictXUnionHenceResponseMayBeStackAllocatedCallback =
      fit::function<void(::test::union_::StrictBoundedXUnion)>;

  virtual void StrictXUnionHenceResponseMayBeStackAllocated(StrictXUnionHenceResponseMayBeStackAllocatedCallback callback) = 0;
  using FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback =
      fit::function<void(::test::union_::OlderSimpleUnion)>;

  virtual void FlexibleXUnionHenceResponseMustBeHeapAllocated(FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback callback) = 0;
};

class TestProtocol_RequestDecoder {
 public:
  TestProtocol_RequestDecoder() = default;
  virtual ~TestProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void StrictXUnionHenceResponseMayBeStackAllocated() = 0;
  virtual void FlexibleXUnionHenceResponseMustBeHeapAllocated() = 0;
};

class TestProtocol_ResponseDecoder {
 public:
  TestProtocol_ResponseDecoder() = default;
  virtual ~TestProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void StrictXUnionHenceResponseMayBeStackAllocated(::test::union_::StrictBoundedXUnion xu) = 0;
  virtual void FlexibleXUnionHenceResponseMustBeHeapAllocated(::test::union_::OlderSimpleUnion xu) = 0;
};

class TestProtocol_EventSender {
 public:
  virtual ~TestProtocol_EventSender();
};

class TestProtocol_Sync {
 public:
  using Proxy_ = ::test::union_::TestProtocol_SyncProxy;
  virtual ~TestProtocol_Sync();
  virtual zx_status_t StrictXUnionHenceResponseMayBeStackAllocated(::test::union_::StrictBoundedXUnion* out_xu) = 0;
  virtual zx_status_t FlexibleXUnionHenceResponseMustBeHeapAllocated(::test::union_::OlderSimpleUnion* out_xu) = 0;
};

class TestProtocol_Proxy final : public ::fidl::internal::Proxy, public TestProtocol {
 public:
  explicit TestProtocol_Proxy(::fidl::internal::ProxyController* controller);
  ~TestProtocol_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.union/TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated
  void StrictXUnionHenceResponseMayBeStackAllocated(StrictXUnionHenceResponseMayBeStackAllocatedCallback callback) override;
  // cts-coverage-fidl-name:test.union/TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated
  void FlexibleXUnionHenceResponseMustBeHeapAllocated(FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback callback) override;

 private:
  TestProtocol_Proxy(const ::test::union_::TestProtocol_Proxy&) = delete;
  TestProtocol_Proxy& operator=(const ::test::union_::TestProtocol_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class TestProtocol_Stub final : public ::fidl::internal::Stub, public ::test::union_::TestProtocol_EventSender {
 public:
  typedef class ::test::union_::TestProtocol TestProtocol_clazz;
  explicit TestProtocol_Stub(::test::union_::TestProtocol_Stub::TestProtocol_clazz* impl);
  ~TestProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::test::union_::TestProtocol_Stub::TestProtocol_clazz* impl_;
};

class TestProtocol_SyncProxy : public ::test::union_::TestProtocol_Sync {
 public:
  explicit TestProtocol_SyncProxy(::zx::channel channel);
  ~TestProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.union/TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated
  zx_status_t StrictXUnionHenceResponseMayBeStackAllocated(::test::union_::StrictBoundedXUnion* out_xu) override;
  // cts-coverage-fidl-name:test.union/TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated
  zx_status_t FlexibleXUnionHenceResponseMustBeHeapAllocated(::test::union_::OlderSimpleUnion* out_xu) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<TestProtocol>;
};
#endif  // __Fuchsia__

}  // namespace union_
}  // namespace test
