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

#pragma once

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

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace union_ {
class Union;

class StructWithNullableXUnion;

class StrictUnion;

class StrictSimpleXUnion;

class StrictFoo;

class StrictBoundedXUnion;

class ReverseOrdinalUnion;

class Pizza;

class Pasta;

class StrictPizzaOrPasta;

class PizzaOrPasta;

class FlexiblePizzaOrPasta;

class ExplicitPizzaOrPasta;

class OlderSimpleUnion;

#ifdef __Fuchsia__

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

class NullableUnionStruct;

class NewerSimpleUnion;

class FlexibleUnion;

class FlexibleFoo;

class FieldCollision;

class ExplicitXUnion;

class ExplicitUnion;

class ExplicitStrictFoo;

class ExplicitFoo;

class Empty;

class XUnionContainingEmptyStruct;

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_ == ::fidl::test::union_::Union::Tag::kPrimitive;
  }

  int32_t& Primitive() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::Union::Tag::kStringNeedsConstructor;
  }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(
        ::fidl::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_ ==
           ::fidl::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor;
  }

  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    EnsureStorageInitialized(
        ::fidl::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);

  ::fidl::test::union_::Union::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::Union>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::Union& value,
                         ::fidl::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<::fidl::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 ::fidl::test::union_::StructWithNullableXUnion& _value,
    ::fidl::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_ == ::fidl::test::union_::StrictUnion::Tag::kPrimitive;
  }

  int32_t& Primitive() {
    EnsureStorageInitialized(
        ::fidl::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_ ==
           ::fidl::test::union_::StrictUnion::Tag::kStringNeedsConstructor;
  }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(
        ::fidl::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_ == ::fidl::test::union_::StrictUnion::Tag::
                       kVectorStringAlsoNeedsConstructor;
  }

  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::StrictUnion::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::StrictUnion>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::StrictUnion& value,
                         ::fidl::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_ == ::fidl::test::union_::StrictSimpleXUnion::Tag::kI;
  }

  int32_t& i() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::StrictSimpleXUnion::Tag::kF;
  }

  float& f() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::StrictSimpleXUnion::Tag::kS;
  }

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

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

  ::fidl::test::union_::StrictSimpleXUnion::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::StrictSimpleXUnion>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::StrictSimpleXUnion& value,
                         ::fidl::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_ == ::fidl::test::union_::StrictFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::StrictFoo::Tag::kI; }

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

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

  ::fidl::test::union_::StrictFoo::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::StrictFoo>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::StrictFoo& value,
                         ::fidl::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_ == ::fidl::test::union_::StrictBoundedXUnion::Tag::kV;
  }

  ::std::vector<uint8_t>& v() {
    EnsureStorageInitialized(
        ::fidl::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);

  ::fidl::test::union_::StrictBoundedXUnion::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::StrictBoundedXUnion>;

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

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

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

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

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_ == ::fidl::test::union_::ReverseOrdinalUnion::Tag::kSecond;
  }

  uint32_t& second() {
    EnsureStorageInitialized(
        ::fidl::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_ == ::fidl::test::union_::ReverseOrdinalUnion::Tag::kFirst;
  }

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

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

  ::fidl::test::union_::ReverseOrdinalUnion::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::ReverseOrdinalUnion>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::ReverseOrdinalUnion& value,
                         ::fidl::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 ::fidl::test::union_::Pizza& _value,
                         ::fidl::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 ::fidl::test::union_::Pasta& _value,
                         ::fidl::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(::fidl::test::union_::Pizza&&);
  static StrictPizzaOrPasta WithPasta(::fidl::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_ == ::fidl::test::union_::StrictPizzaOrPasta::Tag::kPizza;
  }

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

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

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

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

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

  ::fidl::test::union_::StrictPizzaOrPasta::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::StrictPizzaOrPasta>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::StrictPizzaOrPasta& value,
                         ::fidl::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(::fidl::test::union_::Pizza&&);
  static PizzaOrPasta WithPasta(::fidl::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_ == ::fidl::test::union_::PizzaOrPasta::Tag::kPizza;
  }

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

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

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

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

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

  ::fidl::test::union_::PizzaOrPasta::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::PizzaOrPasta>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::PizzaOrPasta& value,
                         ::fidl::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(::fidl::test::union_::Pizza&&);
  static FlexiblePizzaOrPasta WithPasta(::fidl::test::union_::Pasta&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::kPizza;
  }

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

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

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

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

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

  ::fidl::test::union_::FlexiblePizzaOrPasta::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::Invalid:
      case ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
      case ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
        return ::fidl::test::union_::FlexiblePizzaOrPasta::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

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

inline zx_status_t Clone(
    const ::fidl::test::union_::FlexiblePizzaOrPasta& value,
    ::fidl::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(::fidl::test::union_::Pizza&&);
  static ExplicitPizzaOrPasta WithPasta(::fidl::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_ == ::fidl::test::union_::ExplicitPizzaOrPasta::Tag::kPizza;
  }

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

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

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

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

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

  ::fidl::test::union_::ExplicitPizzaOrPasta::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::ExplicitPizzaOrPasta>;

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

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

inline zx_status_t Clone(
    const ::fidl::test::union_::ExplicitPizzaOrPasta& value,
    ::fidl::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,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::OlderSimpleUnion::Tag::kI;
  }

  int64_t& i() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::OlderSimpleUnion::Tag::kF;
  }

  float& f() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::OlderSimpleUnion::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::OlderSimpleUnion::Tag::Invalid:
      case ::fidl::test::union_::OlderSimpleUnion::Tag::kI:
      case ::fidl::test::union_::OlderSimpleUnion::Tag::kF:
        return ::fidl::test::union_::OlderSimpleUnion::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::OlderSimpleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

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

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

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

#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable;

}  // namespace _internal
class TestProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage
  StrictXUnionHenceResponseMayBeStackAllocated(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage
  FlexibleXUnionHenceResponseMustBeHeapAllocated(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
namespace _internal {
extern "C" const fidl_type_t
    fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable;

extern "C" const fidl_type_t
    fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable;

}  // namespace _internal
class TestProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage
  StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::Encoder* _encoder,
      ::fidl::test::union_::StrictBoundedXUnion* xu) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(40 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, xu, 16);

    fidl_trace(
        DidHLCPPEncode,
        &::fidl::test::union_::_internal::
            fidl_test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage
  FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::Encoder* _encoder, ::fidl::test::union_::OlderSimpleUnion* xu) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(40 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, xu, 16);

    fidl_trace(
        DidHLCPPEncode,
        &::fidl::test::union_::_internal::
            fidl_test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable,
        _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<::fidl::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 ::fidl::test::union_::NullableUnionStruct& _value,
    ::fidl::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,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::NewerSimpleUnion::Tag::kI;
  }

  int64_t& i() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::NewerSimpleUnion::Tag::kS;
  }

  ::std::string& s() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::NewerSimpleUnion::Tag::kV;
  }

  ::std::vector<::std::string>& v() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::NewerSimpleUnion::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::NewerSimpleUnion::Tag::Invalid:
      case ::fidl::test::union_::NewerSimpleUnion::Tag::kI:
      case ::fidl::test::union_::NewerSimpleUnion::Tag::kS:
      case ::fidl::test::union_::NewerSimpleUnion::Tag::kV:
        return ::fidl::test::union_::NewerSimpleUnion::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::NewerSimpleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(
      ::fidl::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 ::fidl::test::union_::NewerSimpleUnion& value,
                         ::fidl::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,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::FlexibleUnion::Tag::kPrimitive;
  }

  int32_t& Primitive() {
    EnsureStorageInitialized(
        ::fidl::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_ ==
           ::fidl::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor;
  }

  ::std::string& StringNeedsConstructor() {
    EnsureStorageInitialized(
        ::fidl::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_ == ::fidl::test::union_::FlexibleUnion::Tag::
                       kVectorStringAlsoNeedsConstructor;
  }

  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::FlexibleUnion::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::FlexibleUnion::Tag::Invalid:
      case ::fidl::test::union_::FlexibleUnion::Tag::kPrimitive:
      case ::fidl::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
      case ::fidl::test::union_::FlexibleUnion::Tag::
          kVectorStringAlsoNeedsConstructor:
        return ::fidl::test::union_::FlexibleUnion::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::FlexibleUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(
      ::fidl::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 ::fidl::test::union_::FlexibleUnion& value,
                         ::fidl::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,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::FlexibleFoo::Tag::kS;
  }

  ::std::string& s() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::FlexibleFoo::Tag::kI;
  }

  int32_t& i() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::FlexibleFoo::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::FlexibleFoo::Tag::Invalid:
      case ::fidl::test::union_::FlexibleFoo::Tag::kS:
      case ::fidl::test::union_::FlexibleFoo::Tag::kI:
        return ::fidl::test::union_::FlexibleFoo::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::FlexibleFoo::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

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

inline zx_status_t Clone(const ::fidl::test::union_::FlexibleFoo& value,
                         ::fidl::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_ ==
           ::fidl::test::union_::FieldCollision::Tag::kFieldCollisionTag;
  }

  int32_t& field_collision_tag() {
    EnsureStorageInitialized(
        ::fidl::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);

  ::fidl::test::union_::FieldCollision::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::FieldCollision>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::FieldCollision& value,
                         ::fidl::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,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::ExplicitXUnion::Tag::kI;
  }

  int64_t& i() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::ExplicitXUnion::Tag::kF;
  }

  float& f() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::ExplicitXUnion::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::ExplicitXUnion::Tag::Invalid:
      case ::fidl::test::union_::ExplicitXUnion::Tag::kI:
      case ::fidl::test::union_::ExplicitXUnion::Tag::kF:
        return ::fidl::test::union_::ExplicitXUnion::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::ExplicitXUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

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

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

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

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_ == ::fidl::test::union_::ExplicitUnion::Tag::kPrimitive;
  }

  int32_t& Primitive() {
    EnsureStorageInitialized(
        ::fidl::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_ ==
           ::fidl::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor;
  }

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

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

  ::fidl::test::union_::ExplicitUnion::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::ExplicitUnion>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::ExplicitUnion& value,
                         ::fidl::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_ == ::fidl::test::union_::ExplicitStrictFoo::Tag::kS;
  }

  ::std::string& s() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::ExplicitStrictFoo::Tag::kI;
  }

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

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

  ::fidl::test::union_::ExplicitStrictFoo::Tag Which() const {
    return ::fidl::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<::fidl::test::union_::ExplicitStrictFoo>;

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

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

inline zx_status_t Clone(const ::fidl::test::union_::ExplicitStrictFoo& value,
                         ::fidl::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,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ == ::fidl::test::union_::ExplicitFoo::Tag::kS;
  }

  ::std::string& s() {
    EnsureStorageInitialized(::fidl::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_ == ::fidl::test::union_::ExplicitFoo::Tag::kI;
  }

  int32_t& i() {
    EnsureStorageInitialized(::fidl::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);

  ::fidl::test::union_::ExplicitFoo::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::ExplicitFoo::Tag::Invalid:
      case ::fidl::test::union_::ExplicitFoo::Tag::kS:
      case ::fidl::test::union_::ExplicitFoo::Tag::kI:
        return ::fidl::test::union_::ExplicitFoo::Tag(tag_);
      default:
        return ::fidl::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() != ::fidl::test::union_::ExplicitFoo::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

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

inline zx_status_t Clone(const ::fidl::test::union_::ExplicitFoo& value,
                         ::fidl::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 ::fidl::test::union_::Empty& _value,
                         ::fidl::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(::fidl::test::union_::Empty&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    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_ ==
           ::fidl::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty;
  }

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

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

  ::fidl::test::union_::XUnionContainingEmptyStruct::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::union_::XUnionContainingEmptyStruct::Tag::Invalid:
      case ::fidl::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
        return ::fidl::test::union_::XUnionContainingEmptyStruct::Tag(tag_);
      default:
        return ::fidl::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() !=
        ::fidl::test::union_::XUnionContainingEmptyStruct::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

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

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::Union>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(Decoder* decoder,
                     std::unique_ptr<::fidl::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 ::fidl::test::union_::Union);

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

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

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

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

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::StrictUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(Decoder* decoder,
                     std::unique_ptr<::fidl::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 ::fidl::test::union_::StrictUnion);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::StrictSimpleXUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::StrictSimpleXUnion);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::StrictFoo>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(Decoder* decoder,
                     std::unique_ptr<::fidl::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 ::fidl::test::union_::StrictFoo);

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

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

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

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

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

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

template <>
struct CodingTraits<
    std::unique_ptr<::fidl::test::union_::StrictBoundedXUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::StrictBoundedXUnion);

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

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

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

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

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

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

template <>
struct CodingTraits<
    std::unique_ptr<::fidl::test::union_::ReverseOrdinalUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::ReverseOrdinalUnion);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::StrictPizzaOrPasta>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::StrictPizzaOrPasta);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::PizzaOrPasta>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(Decoder* decoder,
                     std::unique_ptr<::fidl::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 ::fidl::test::union_::PizzaOrPasta);

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

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

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

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

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

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

template <>
struct CodingTraits<
    std::unique_ptr<::fidl::test::union_::FlexiblePizzaOrPasta>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::FlexiblePizzaOrPasta);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
        return true;
      case ::fidl::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
        return ::fidl::Equals(_lhs.pizza_, _rhs.pizza_);
      case ::fidl::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<::fidl::test::union_::ExplicitPizzaOrPasta>
    : public std::true_type {};

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

template <>
struct CodingTraits<
    std::unique_ptr<::fidl::test::union_::ExplicitPizzaOrPasta>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::ExplicitPizzaOrPasta);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::OlderSimpleUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::OlderSimpleUnion);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::OlderSimpleUnion::Tag::Invalid):
        return true;
      case ::fidl::test::union_::OlderSimpleUnion::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      case ::fidl::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<::fidl::test::union_::NullableUnionStruct>
    : public EncodableCodingTraits<::fidl::test::union_::NullableUnionStruct,
                                   24> {};

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::NewerSimpleUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::NewerSimpleUnion);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::NewerSimpleUnion::Tag::Invalid):
        return true;
      case ::fidl::test::union_::NewerSimpleUnion::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      case ::fidl::test::union_::NewerSimpleUnion::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::fidl::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<::fidl::test::union_::FlexibleUnion>
    : public std::true_type {};

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::FlexibleUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::FlexibleUnion);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::FlexibleUnion::Tag::Invalid):
        return true;
      case ::fidl::test::union_::FlexibleUnion::Tag::kPrimitive:
        return ::fidl::Equals(_lhs.Primitive_, _rhs.Primitive_);
      case ::fidl::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
        return ::fidl::Equals(_lhs.StringNeedsConstructor_,
                              _rhs.StringNeedsConstructor_);
      case ::fidl::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<::fidl::test::union_::FlexibleFoo> : public std::true_type {
};

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::FlexibleFoo>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(Decoder* decoder,
                     std::unique_ptr<::fidl::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 ::fidl::test::union_::FlexibleFoo);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::FlexibleFoo::Tag::Invalid):
        return true;
      case ::fidl::test::union_::FlexibleFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::fidl::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<::fidl::test::union_::FieldCollision>
    : public std::true_type {};

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::FieldCollision>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::FieldCollision);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::ExplicitXUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::ExplicitXUnion);

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::ExplicitUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::ExplicitUnion);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::ExplicitStrictFoo>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::ExplicitStrictFoo);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::union_::ExplicitFoo>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(Decoder* decoder,
                     std::unique_ptr<::fidl::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 ::fidl::test::union_::ExplicitFoo);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::ExplicitFoo::Tag::Invalid):
        return true;
      case ::fidl::test::union_::ExplicitFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::fidl::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<::fidl::test::union_::Empty>
    : public EncodableCodingTraits<::fidl::test::union_::Empty, 1> {};

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

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

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

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

template <>
struct CodingTraits<
    std::unique_ptr<::fidl::test::union_::XUnionContainingEmptyStruct>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

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

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::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 ::fidl::test::union_::XUnionContainingEmptyStruct);

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

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::union_::XUnionContainingEmptyStruct::Tag::Invalid):
        return true;
      case ::fidl::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 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 =
        0x747b084a44f0dc3elu;
constexpr uint64_t
    kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal =
        0x57615a25c2a785d2lu;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  virtual void StrictXUnionHenceResponseMayBeStackAllocated(
      StrictXUnionHenceResponseMayBeStackAllocatedCallback callback) = 0;
  using FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback =
      fit::function<void(::fidl::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(
      ::fidl::test::union_::StrictBoundedXUnion xu) = 0;
  virtual void FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::test::union_::OlderSimpleUnion xu) = 0;
};

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

class TestProtocol_Sync {
 public:
  using Proxy_ = ::fidl::test::union_::TestProtocol_SyncProxy;
  virtual ~TestProtocol_Sync();
  virtual zx_status_t StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::test::union_::StrictBoundedXUnion* out_xu) = 0;
  virtual zx_status_t FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::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;
  void StrictXUnionHenceResponseMayBeStackAllocated(
      StrictXUnionHenceResponseMayBeStackAllocatedCallback callback) override;
  void FlexibleXUnionHenceResponseMustBeHeapAllocated(
      FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback callback) override;

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

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

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

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

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

class TestProtocol_SyncProxy : public ::fidl::test::union_::TestProtocol_Sync {
 public:
  explicit TestProtocol_SyncProxy(::zx::channel channel);
  ~TestProtocol_SyncProxy() override;
  zx_status_t StrictXUnionHenceResponseMayBeStackAllocated(
      ::fidl::test::union_::StrictBoundedXUnion* out_xu) override;
  zx_status_t FlexibleXUnionHenceResponseMustBeHeapAllocated(
      ::fidl::test::union_::OlderSimpleUnion* out_xu) override;

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

}  // namespace union_
}  // namespace test
}  // namespace fidl
