// WARNING: This file is machine generated by fidlgen.
  
  // fidl_experiment = output_index_json

  #pragma once

  #include <cinttypes>

  #include <lib/fidl/cpp/wire/internal/framework_err.h>
  #include <lib/fidl/cpp/wire/array.h>
  #include <lib/fidl/cpp/wire/envelope.h>
  #include <lib/fidl/cpp/wire/message_storage.h>
  #include <lib/fidl/cpp/wire/message.h>
  #include <lib/fidl/cpp/wire/object_view.h>
  #include <lib/fidl/cpp/wire/string_view.h>
  #include <lib/fidl/cpp/wire/traits.h>
  #include <lib/fidl/cpp/wire/wire_types.h>
  #include <lib/stdcompat/optional.h>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>
    

#endif  // __Fuchsia__


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

  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wshadow"

  namespace test_union {


  
  
  
namespace wire {

struct Pizza;


struct Pasta;


struct NullableUnionStruct;


struct Empty;


struct TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse;


struct TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse;


struct StructWithNullableUnion;


struct UnionSandwich;
  
  


class PizzaOrPasta;


class ExplicitPizzaOrPasta;


class FlexiblePizzaOrPasta;


class StrictPizzaOrPasta;


class Union;


class FlexibleUnion;


class StrictUnion;


class FieldCollision;


class ExplicitUnion;


class ReverseOrdinalUnion;


class FlexibleFoo;


class StrictFoo;


class ExplicitFoo;


class ExplicitStrictFoo;


class OlderSimpleUnion;


class NewerSimpleUnion;


class StrictSimpleUnion;


class UnionContainingEmptyStruct;


class StrictBoundedUnion;


class ExplicitFlexibleUnion;


class UnionWithAttributes;


class EmptyFlexibleUnion;

  
    
    
    
    




struct Empty {

    uint8_t __reserved = {};
};
    
    
    
    
  
  




class PizzaOrPasta {
  public:

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

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

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

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

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

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


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

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

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


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

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

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




class ExplicitPizzaOrPasta {
  public:

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

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

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

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

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

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


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

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

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


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

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

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




class FlexiblePizzaOrPasta {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::FlexiblePizzaOrPasta::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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

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


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

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

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


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

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

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




class StrictPizzaOrPasta {
  public:

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

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

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

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

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

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


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

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

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


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

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

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




class Union {
  public:

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

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

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

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

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


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

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

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


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

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

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


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

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

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




class FlexibleUnion {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,  // 0x1
    kStringNeedsConstructor = 2,  // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::FlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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


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

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

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


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

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

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


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

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

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




class StrictUnion {
  public:

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

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

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

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

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


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

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

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


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

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

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


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

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

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




class FieldCollision {
  public:

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

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

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

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

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


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

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

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




class ExplicitUnion {
  public:

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

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

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

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

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


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

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

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


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

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

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




class ReverseOrdinalUnion {
  public:

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

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

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

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

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


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

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


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

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

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




class FlexibleFoo {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::FlexibleFoo::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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

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


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

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


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

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

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




class StrictFoo {
  public:

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

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

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

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

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

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


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

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


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

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

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




class ExplicitFoo {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::ExplicitFoo::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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


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

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

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


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

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

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




class ExplicitStrictFoo {
  public:

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

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

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

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

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


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

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

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


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

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

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




class OlderSimpleUnion {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::OlderSimpleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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

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


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

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


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

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

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




class NewerSimpleUnion {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    kV = 3,  // 0x3
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::NewerSimpleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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

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


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

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

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


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

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

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


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

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

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




class StrictSimpleUnion {
  public:

  StrictSimpleUnion() : ordinal_(::test_union::wire::StrictSimpleUnion::Ordinal::Invalid), envelope_{} {}

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

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

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

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


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

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


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

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

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


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

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

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




class UnionContainingEmptyStruct {
  public:

  UnionContainingEmptyStruct() : ordinal_(::test_union::wire::UnionContainingEmptyStruct::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kEmpty = 1,  // 0x1
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::UnionContainingEmptyStruct::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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


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

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

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




class StrictBoundedUnion {
  public:

  StrictBoundedUnion() : ordinal_(::test_union::wire::StrictBoundedUnion::Ordinal::Invalid), envelope_{} {}

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

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

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

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

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


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

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

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




class ExplicitFlexibleUnion {
  public:

  ExplicitFlexibleUnion() : ordinal_(::test_union::wire::ExplicitFlexibleUnion::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 4,  // 0x4
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::ExplicitFlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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

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


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

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


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

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

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




class UnionWithAttributes {
  public:

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

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

  enum class Tag : fidl_xunion_tag_t {
    kX = 1,  // 0x1
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::UnionWithAttributes::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

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

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


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

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

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




class EmptyFlexibleUnion {
  public:

  EmptyFlexibleUnion() : ordinal_(::test_union::wire::EmptyFlexibleUnion::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::wire::EmptyFlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

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

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
  };

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




struct Pizza {

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




struct Pasta {

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




struct NullableUnionStruct {

    ::fidl::WireOptional<::test_union::wire::Union> the_union = {};
};
    
    




struct TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse {

    ::test_union::wire::StrictBoundedUnion xu = {};
};
    




struct TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse {

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




struct StructWithNullableUnion {

    ::fidl::WireOptional<::test_union::wire::OlderSimpleUnion> x1 = {};
};
    




struct UnionSandwich {

    uint32_t a = {};

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

    uint32_t b = {};
};

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


  
  
  


template<>
struct TypeTraits<::test_union::wire::Pizza> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false, 16>, false>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::Pizza, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::Pizza* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::Pizza));
    } else {
      internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false, 16>, false>, IsRecursive>::Encode(encoder, &value->toppings, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false, 16>, false>, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::Pasta> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 16>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::Pasta, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::Pasta* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::Pasta));
    } else {
      internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 16>, IsRecursive>::Encode(encoder, &value->sauce, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 16>, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::NullableUnionStruct> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::NullableUnionStruct, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fidl::WireOptional<::test_union::wire::Union>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::NullableUnionStruct, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::NullableUnionStruct* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::NullableUnionStruct));
    } else {
      internal::WireCodingTraits<::fidl::WireOptional<::test_union::wire::Union>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Encode(encoder, &value->the_union, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fidl::WireOptional<::test_union::wire::Union>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::Empty> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::Empty, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::Empty, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::Empty* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::Empty));
    } else {
      internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->__reserved, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
    if (*position.As<uint8_t>() != 0) {
      decoder->SetError(kCodingErrorInvalidPaddingBytes);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 32;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_union::wire::StrictBoundedUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse));
    } else {
      internal::WireCodingTraits<::test_union::wire::StrictBoundedUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Encode(encoder, &value->xu, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_union::wire::StrictBoundedUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_union::wire::OlderSimpleUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse));
    } else {
      internal::WireCodingTraits<::test_union::wire::OlderSimpleUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Encode(encoder, &value->xu, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_union::wire::OlderSimpleUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::StructWithNullableUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StructWithNullableUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fidl::WireOptional<::test_union::wire::OlderSimpleUnion>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_union::wire::StructWithNullableUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::StructWithNullableUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::StructWithNullableUnion));
    } else {
      internal::WireCodingTraits<::fidl::WireOptional<::test_union::wire::OlderSimpleUnion>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Encode(encoder, &value->x1, position + 0, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fidl::WireOptional<::test_union::wire::OlderSimpleUnion>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
    }
  }
};


template<>
struct TypeTraits<::test_union::wire::UnionSandwich> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 32;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::UnionSandwich, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 32;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>(), ::fidl::internal::WireStructMemberCodingInfo<::test_union::wire::ExplicitFlexibleUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>(), ::fidl::internal::WireStructMemberCodingInfo<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = true;
  using Base = WireStructCodingTraitsBase<::test_union::wire::UnionSandwich, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
    internal::WireEncoder* encoder, ::test_union::wire::UnionSandwich* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_union::wire::UnionSandwich));
    } else {
      internal::WireZeroPadding<uint64_t>(encoder, position + 0);
      internal::WireZeroPadding<uint64_t>(encoder, position + 24);
      internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->a, position + 0, recursion_depth);
      internal::WireCodingTraits<::test_union::wire::ExplicitFlexibleUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Encode(encoder, &value->u, position + 8, recursion_depth);
      internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->b, position + 24, recursion_depth);
    }
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + 0, recursion_depth);
      internal::WireCodingTraits<::test_union::wire::ExplicitFlexibleUnion, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Decode(
        decoder, position + 8, recursion_depth);
      internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + 24, recursion_depth);
    }
    internal::WireCheckPadding<uint64_t>(decoder, position + 0, 0xffffffff00000000);
    internal::WireCheckPadding<uint64_t>(decoder, position + 24, 0xffffffff00000000);
  }
};
  
  


template <>
struct TypeTraits<::test_union::wire::PizzaOrPasta> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::PizzaOrPasta, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::PizzaOrPasta* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::PizzaOrPasta::Tag::kPizza
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::PizzaOrPasta::Tag::kPasta
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::PizzaOrPasta::Tag::kPizza
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::PizzaOrPasta::Tag::kPasta
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::PizzaOrPasta::Tag tag = *position.As<::test_union::wire::PizzaOrPasta::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::PizzaOrPasta::Tag::kPizza:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::PizzaOrPasta::Tag::kPasta:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::PizzaOrPasta::Tag::kPizza:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::PizzaOrPasta::Tag::kPasta:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::PizzaOrPasta, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::PizzaOrPasta, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::ExplicitPizzaOrPasta> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitPizzaOrPasta, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::ExplicitPizzaOrPasta* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPizza
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 4: // ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPasta
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPizza
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 4: // ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPasta
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::ExplicitPizzaOrPasta::Tag tag = *position.As<::test_union::wire::ExplicitPizzaOrPasta::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPizza:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPasta:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPizza:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::ExplicitPizzaOrPasta::Tag::kPasta:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitPizzaOrPasta, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitPizzaOrPasta, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::FlexiblePizzaOrPasta> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FlexiblePizzaOrPasta, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::FlexiblePizzaOrPasta* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPizza
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPasta
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPizza
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPasta
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::FlexiblePizzaOrPasta::Tag tag = *position.As<::test_union::wire::FlexiblePizzaOrPasta::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPizza:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPasta:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPizza:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::FlexiblePizzaOrPasta::Tag::kPasta:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FlexiblePizzaOrPasta, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::FlexiblePizzaOrPasta, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::StrictPizzaOrPasta> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictPizzaOrPasta, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::StrictPizzaOrPasta* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictPizzaOrPasta::Tag::kPizza
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::StrictPizzaOrPasta::Tag::kPasta
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictPizzaOrPasta::Tag::kPizza
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::StrictPizzaOrPasta::Tag::kPasta
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::StrictPizzaOrPasta::Tag tag = *position.As<::test_union::wire::StrictPizzaOrPasta::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::StrictPizzaOrPasta::Tag::kPizza:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::StrictPizzaOrPasta::Tag::kPasta:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::StrictPizzaOrPasta::Tag::kPizza:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pizza, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::StrictPizzaOrPasta::Tag::kPasta:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Pasta, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictPizzaOrPasta, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::StrictPizzaOrPasta, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::Union> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::Union, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::Union* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::Union::Tag::kPrimitive
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::Union::Tag::kStringNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::Union::Tag::kVectorStringAlsoNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::Union::Tag::kPrimitive
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::Union::Tag::kStringNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case 3: // ::test_union::wire::Union::Tag::kVectorStringAlsoNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::Union::Tag tag = *position.As<::test_union::wire::Union::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::Union::Tag::kPrimitive:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::Union::Tag::kStringNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::Union::Tag::kVectorStringAlsoNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::Union::Tag::kPrimitive:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::Union::Tag::kStringNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case ::test_union::wire::Union::Tag::kVectorStringAlsoNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::Union, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::Union, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::FlexibleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FlexibleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::FlexibleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::FlexibleUnion::Tag::kPrimitive
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::FlexibleUnion::Tag::kStringNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::FlexibleUnion::Tag::kPrimitive
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::FlexibleUnion::Tag::kStringNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case 3: // ::test_union::wire::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::FlexibleUnion::Tag tag = *position.As<::test_union::wire::FlexibleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::FlexibleUnion::Tag::kPrimitive:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::FlexibleUnion::Tag::kStringNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::FlexibleUnion::Tag::kPrimitive:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::FlexibleUnion::Tag::kStringNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case ::test_union::wire::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FlexibleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::FlexibleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::StrictUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::StrictUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictUnion::Tag::kPrimitive
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::StrictUnion::Tag::kStringNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictUnion::Tag::kPrimitive
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::StrictUnion::Tag::kStringNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case 3: // ::test_union::wire::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::StrictUnion::Tag tag = *position.As<::test_union::wire::StrictUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::StrictUnion::Tag::kPrimitive:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::StrictUnion::Tag::kStringNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::StrictUnion::Tag::kPrimitive:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::StrictUnion::Tag::kStringNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case ::test_union::wire::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::StrictUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::FieldCollision> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FieldCollision, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::FieldCollision* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::FieldCollision::Tag::kFieldCollisionTag
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::FieldCollision::Tag::kFieldCollisionTag
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::FieldCollision::Tag tag = *position.As<::test_union::wire::FieldCollision::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::FieldCollision::Tag::kFieldCollisionTag:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::FieldCollision::Tag::kFieldCollisionTag:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FieldCollision, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::FieldCollision, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::ExplicitUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::ExplicitUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitUnion::Tag::kPrimitive
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::ExplicitUnion::Tag::kStringNeedsConstructor
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitUnion::Tag::kPrimitive
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 3: // ::test_union::wire::ExplicitUnion::Tag::kStringNeedsConstructor
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::ExplicitUnion::Tag tag = *position.As<::test_union::wire::ExplicitUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::ExplicitUnion::Tag::kPrimitive:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::ExplicitUnion::Tag::kStringNeedsConstructor:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::ExplicitUnion::Tag::kPrimitive:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::ExplicitUnion::Tag::kStringNeedsConstructor:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::ReverseOrdinalUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ReverseOrdinalUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::ReverseOrdinalUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::ReverseOrdinalUnion::Tag::kFirst
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::ReverseOrdinalUnion::Tag::kSecond
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::ReverseOrdinalUnion::Tag::kFirst
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::ReverseOrdinalUnion::Tag::kSecond
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::ReverseOrdinalUnion::Tag tag = *position.As<::test_union::wire::ReverseOrdinalUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::ReverseOrdinalUnion::Tag::kFirst:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::ReverseOrdinalUnion::Tag::kSecond:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::ReverseOrdinalUnion::Tag::kFirst:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::ReverseOrdinalUnion::Tag::kSecond:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ReverseOrdinalUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::ReverseOrdinalUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::FlexibleFoo> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FlexibleFoo, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::FlexibleFoo* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::FlexibleFoo::Tag::kS
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::FlexibleFoo::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::FlexibleFoo::Tag::kS
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case 2: // ::test_union::wire::FlexibleFoo::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::FlexibleFoo::Tag tag = *position.As<::test_union::wire::FlexibleFoo::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::FlexibleFoo::Tag::kS:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::FlexibleFoo::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::FlexibleFoo::Tag::kS:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case ::test_union::wire::FlexibleFoo::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::FlexibleFoo, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::FlexibleFoo, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::StrictFoo> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictFoo, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::StrictFoo* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictFoo::Tag::kS
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::StrictFoo::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictFoo::Tag::kS
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case 2: // ::test_union::wire::StrictFoo::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::StrictFoo::Tag tag = *position.As<::test_union::wire::StrictFoo::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::StrictFoo::Tag::kS:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::StrictFoo::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::StrictFoo::Tag::kS:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case ::test_union::wire::StrictFoo::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictFoo, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::StrictFoo, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::ExplicitFoo> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitFoo, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::ExplicitFoo* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitFoo::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::ExplicitFoo::Tag::kS
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitFoo::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::ExplicitFoo::Tag::kS
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::ExplicitFoo::Tag tag = *position.As<::test_union::wire::ExplicitFoo::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::ExplicitFoo::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::ExplicitFoo::Tag::kS:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::ExplicitFoo::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::ExplicitFoo::Tag::kS:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitFoo, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitFoo, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::ExplicitStrictFoo> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitStrictFoo, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::ExplicitStrictFoo* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 2: // ::test_union::wire::ExplicitStrictFoo::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::ExplicitStrictFoo::Tag::kS
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 2: // ::test_union::wire::ExplicitStrictFoo::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 3: // ::test_union::wire::ExplicitStrictFoo::Tag::kS
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::ExplicitStrictFoo::Tag tag = *position.As<::test_union::wire::ExplicitStrictFoo::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::ExplicitStrictFoo::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::ExplicitStrictFoo::Tag::kS:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::ExplicitStrictFoo::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::ExplicitStrictFoo::Tag::kS:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitStrictFoo, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitStrictFoo, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::OlderSimpleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::OlderSimpleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::OlderSimpleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::OlderSimpleUnion::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::OlderSimpleUnion::Tag::kF
        encode_inline_size = ::fidl::internal::WireCodingTraits<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::OlderSimpleUnion::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::OlderSimpleUnion::Tag::kF
        encode_fn = ::fidl::internal::MakeEncodeFn<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::OlderSimpleUnion::Tag tag = *position.As<::test_union::wire::OlderSimpleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::OlderSimpleUnion::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::OlderSimpleUnion::Tag::kF:
        decode_inline_size = ::fidl::internal::WireCodingTraits<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::OlderSimpleUnion::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::OlderSimpleUnion::Tag::kF:
        decode_fn = ::fidl::internal::MakeDecodeFn<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::OlderSimpleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::OlderSimpleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::NewerSimpleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::NewerSimpleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::NewerSimpleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::NewerSimpleUnion::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::NewerSimpleUnion::Tag::kS
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::NewerSimpleUnion::Tag::kV
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::NewerSimpleUnion::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::NewerSimpleUnion::Tag::kS
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case 3: // ::test_union::wire::NewerSimpleUnion::Tag::kV
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::NewerSimpleUnion::Tag tag = *position.As<::test_union::wire::NewerSimpleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::NewerSimpleUnion::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::NewerSimpleUnion::Tag::kS:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::NewerSimpleUnion::Tag::kV:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::NewerSimpleUnion::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::NewerSimpleUnion::Tag::kS:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      case ::test_union::wire::NewerSimpleUnion::Tag::kV:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<::fidl::StringView>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintString<false>, false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::NewerSimpleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::NewerSimpleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::StrictSimpleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictSimpleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::StrictSimpleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictSimpleUnion::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2: // ::test_union::wire::StrictSimpleUnion::Tag::kF
        encode_inline_size = ::fidl::internal::WireCodingTraits<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 3: // ::test_union::wire::StrictSimpleUnion::Tag::kS
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictSimpleUnion::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2: // ::test_union::wire::StrictSimpleUnion::Tag::kF
        encode_fn = ::fidl::internal::MakeEncodeFn<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 3: // ::test_union::wire::StrictSimpleUnion::Tag::kS
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::StrictSimpleUnion::Tag tag = *position.As<::test_union::wire::StrictSimpleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::StrictSimpleUnion::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::StrictSimpleUnion::Tag::kF:
        decode_inline_size = ::fidl::internal::WireCodingTraits<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::StrictSimpleUnion::Tag::kS:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::StrictSimpleUnion::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::StrictSimpleUnion::Tag::kF:
        decode_fn = ::fidl::internal::MakeDecodeFn<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::StrictSimpleUnion::Tag::kS:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictSimpleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::StrictSimpleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::UnionContainingEmptyStruct> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::UnionContainingEmptyStruct, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::UnionContainingEmptyStruct* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::UnionContainingEmptyStruct::Tag::kEmpty
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::UnionContainingEmptyStruct::Tag::kEmpty
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_union::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::UnionContainingEmptyStruct::Tag tag = *position.As<::test_union::wire::UnionContainingEmptyStruct::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::UnionContainingEmptyStruct::Tag::kEmpty:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_union::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::UnionContainingEmptyStruct::Tag::kEmpty:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_union::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::UnionContainingEmptyStruct, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::UnionContainingEmptyStruct, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::StrictBoundedUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 32;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictBoundedUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::StrictBoundedUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictBoundedUnion::Tag::kV
        encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<uint8_t>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::StrictBoundedUnion::Tag::kV
        encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<uint8_t>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::StrictBoundedUnion::Tag tag = *position.As<::test_union::wire::StrictBoundedUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::StrictBoundedUnion::Tag::kV:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<uint8_t>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::StrictBoundedUnion::Tag::kV:
        decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<uint8_t>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::StrictBoundedUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::StrictBoundedUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::ExplicitFlexibleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitFlexibleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::ExplicitFlexibleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitFlexibleUnion::Tag::kI
        encode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 4: // ::test_union::wire::ExplicitFlexibleUnion::Tag::kF
        encode_inline_size = ::fidl::internal::WireCodingTraits<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::ExplicitFlexibleUnion::Tag::kI
        encode_fn = ::fidl::internal::MakeEncodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 4: // ::test_union::wire::ExplicitFlexibleUnion::Tag::kF
        encode_fn = ::fidl::internal::MakeEncodeFn<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::ExplicitFlexibleUnion::Tag tag = *position.As<::test_union::wire::ExplicitFlexibleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::ExplicitFlexibleUnion::Tag::kI:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_union::wire::ExplicitFlexibleUnion::Tag::kF:
        decode_inline_size = ::fidl::internal::WireCodingTraits<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::ExplicitFlexibleUnion::Tag::kI:
        decode_fn = ::fidl::internal::MakeDecodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_union::wire::ExplicitFlexibleUnion::Tag::kF:
        decode_fn = ::fidl::internal::MakeDecodeFn<float, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitFlexibleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::ExplicitFlexibleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::UnionWithAttributes> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::UnionWithAttributes, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::UnionWithAttributes* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      case 1: // ::test_union::wire::UnionWithAttributes::Tag::kX
        encode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1: // ::test_union::wire::UnionWithAttributes::Tag::kX
        encode_fn = ::fidl::internal::MakeEncodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::UnionWithAttributes::Tag tag = *position.As<::test_union::wire::UnionWithAttributes::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      case ::test_union::wire::UnionWithAttributes::Tag::kX:
        decode_inline_size = ::fidl::internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      case ::test_union::wire::UnionWithAttributes::Tag::kX:
        decode_fn = ::fidl::internal::MakeDecodeFn<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::UnionWithAttributes, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::UnionWithAttributes, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};


template <>
struct TypeTraits<::test_union::wire::EmptyFlexibleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = false;
};

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

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::EmptyFlexibleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_union::wire::EmptyFlexibleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    
    size_t encode_inline_size;
    switch (u->tag) {
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_union::wire::EmptyFlexibleUnion::Tag tag = *position.As<::test_union::wire::EmptyFlexibleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    
    size_t decode_inline_size;
    switch (tag) {
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch(tag) {
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_union::wire::EmptyFlexibleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<::test_union::wire::EmptyFlexibleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

  #pragma clang diagnostic pop

  }  // namespace fidl

