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

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

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

//
// Domain objects definitions
//
namespace test {
namespace union_ {
extern "C" const fidl_type_t test_union_UnionWithAttributesTable;
const fidl_type_t* UnionWithAttributes::FidlType = &test_union_UnionWithAttributesTable;

UnionWithAttributes::UnionWithAttributes() {}

UnionWithAttributes::~UnionWithAttributes() {
  Destroy();
}

UnionWithAttributes::UnionWithAttributes(UnionWithAttributes&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::UnionWithAttributes::Tag::kX:
      x_ = std::move(other.x_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

UnionWithAttributes& UnionWithAttributes::operator=(UnionWithAttributes&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::UnionWithAttributes::Tag::kX:
        x_ = std::move(other.x_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

UnionWithAttributes UnionWithAttributes::WithX(int64_t&& val) {
  UnionWithAttributes result;
  result.set_x(std::move(val));
  return result;
}

void UnionWithAttributes::Encode(::fidl::Encoder* encoder, size_t offset,
                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::UnionWithAttributes::Tag::kX: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &x_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &x_,
          encoder->Alloc(::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::UnionWithAttributes::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void UnionWithAttributes::Decode(::fidl::Decoder* _decoder, UnionWithAttributes* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::UnionWithAttributes::Tag::kX: {
      ::fidl::Decode(_decoder, &value->x_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t UnionWithAttributes::Clone(UnionWithAttributes* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::UnionWithAttributes::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::UnionWithAttributes::Tag::kX:
      return ::fidl::Clone(x_, &result->x_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

UnionWithAttributes& UnionWithAttributes::set_x(int64_t value) {
  EnsureStorageInitialized(::test::union_::UnionWithAttributes::Tag::kX);
  x_ = std::move(value);
  return *this;
}
UnionWithAttributes& UnionWithAttributes::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void UnionWithAttributes::Destroy() {
  switch (tag_) {
    case ::test::union_::UnionWithAttributes::Tag::kX:
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid);
}

void UnionWithAttributes::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::UnionWithAttributes::Tag::Invalid):
        break;
      case ::test::union_::UnionWithAttributes::Tag::kX:
        new (&x_) int64_t();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_UnionTable;
const fidl_type_t* Union::FidlType = &test_union_UnionTable;

Union::Union() {}

Union::~Union() {
  Destroy();
}

Union::Union(Union&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::Union::Tag::kPrimitive:
      Primitive_ = std::move(other.Primitive_);
      break;
    case ::test::union_::Union::Tag::kStringNeedsConstructor:
      new (&StringNeedsConstructor_)::std::string();
      StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
      break;
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
      new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      VectorStringAlsoNeedsConstructor_ = std::move(other.VectorStringAlsoNeedsConstructor_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid):
      break;
  }
}

Union& Union::operator=(Union&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::Union::Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case ::test::union_::Union::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        VectorStringAlsoNeedsConstructor_ = std::move(other.VectorStringAlsoNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid):
        break;
    }
  }
  return *this;
}

Union Union::WithPrimitive(int32_t&& val) {
  Union result;
  result.set_Primitive(std::move(val));
  return result;
}
Union Union::WithStringNeedsConstructor(::std::string&& val) {
  Union result;
  result.set_StringNeedsConstructor(std::move(val));
  return result;
}
Union Union::WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string>&& val) {
  Union result;
  result.set_VectorStringAlsoNeedsConstructor(std::move(val));
  return result;
}

void Union::Encode(::fidl::Encoder* encoder, size_t offset,
                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::Union::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &Primitive_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::Union::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &StringNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &VectorStringAlsoNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void Union::Decode(::fidl::Decoder* _decoder, Union* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::Union::Tag::kPrimitive: {
      ::fidl::Decode(_decoder, &value->Primitive_, value_offset);
      break;
    }
    case ::test::union_::Union::Tag::kStringNeedsConstructor: {
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(_decoder, &value->StringNeedsConstructor_, value_offset);
      break;
    }
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor: {
      new (&value->VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      ::fidl::Decode(_decoder, &value->VectorStringAlsoNeedsConstructor_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t Union::Clone(Union* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::Union::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::Union::Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case ::test::union_::Union::Tag::kStringNeedsConstructor:
      new (&result->StringNeedsConstructor_)::std::string();
      return ::fidl::Clone(StringNeedsConstructor_, &result->StringNeedsConstructor_);
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
      new (&result->VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      return ::fidl::Clone(VectorStringAlsoNeedsConstructor_, &result->VectorStringAlsoNeedsConstructor_);
    default:
      return ZX_OK;
  }
}

Union& Union::set_Primitive(int32_t value) {
  EnsureStorageInitialized(::test::union_::Union::Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

Union& Union::set_StringNeedsConstructor(::std::string value) {
  EnsureStorageInitialized(::test::union_::Union::Tag::kStringNeedsConstructor);
  StringNeedsConstructor_ = std::move(value);
  return *this;
}

Union& Union::set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value) {
  EnsureStorageInitialized(::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor);
  VectorStringAlsoNeedsConstructor_ = std::move(value);
  return *this;
}

void Union::Destroy() {
  switch (tag_) {
    case ::test::union_::Union::Tag::kPrimitive:
      break;
    case ::test::union_::Union::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
      VectorStringAlsoNeedsConstructor_.~decltype(VectorStringAlsoNeedsConstructor_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid);
}

void Union::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid):
        break;
      case ::test::union_::Union::Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case ::test::union_::Union::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_StructWithNullableXUnionTable;
const fidl_type_t* StructWithNullableXUnion::FidlType = &test_union_StructWithNullableXUnionTable;

void StructWithNullableXUnion::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<StructWithNullableXUnion>::value) {
    memcpy(_encoder->template GetPtr<StructWithNullableXUnion>(_offset), this, sizeof(StructWithNullableXUnion));
  } else {
    ::fidl::Encode(_encoder, &x1, _offset + 0);
  }
}

void StructWithNullableXUnion::Decode(::fidl::Decoder* _decoder, StructWithNullableXUnion* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<StructWithNullableXUnion>::value) {
    memcpy(_value, _decoder->template GetPtr<StructWithNullableXUnion>(_offset), sizeof(StructWithNullableXUnion));
  } else {
    ::fidl::Decode(_decoder, &_value->x1, _offset + 0);
  }
}

zx_status_t StructWithNullableXUnion::Clone(StructWithNullableXUnion* _result) const {
  zx_status_t _status = ::fidl::Clone(x1, &_result->x1);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_StrictUnionTable;
const fidl_type_t* StrictUnion::FidlType = &test_union_StrictUnionTable;

StrictUnion::StrictUnion() {}

StrictUnion::~StrictUnion() {
  Destroy();
}

StrictUnion::StrictUnion(StrictUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::StrictUnion::Tag::kPrimitive:
      Primitive_ = std::move(other.Primitive_);
      break;
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
      new (&StringNeedsConstructor_)::std::string();
      StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
      break;
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
      new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      VectorStringAlsoNeedsConstructor_ = std::move(other.VectorStringAlsoNeedsConstructor_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid):
      break;
  }
}

StrictUnion& StrictUnion::operator=(StrictUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::StrictUnion::Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        VectorStringAlsoNeedsConstructor_ = std::move(other.VectorStringAlsoNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid):
        break;
    }
  }
  return *this;
}

StrictUnion StrictUnion::WithPrimitive(int32_t&& val) {
  StrictUnion result;
  result.set_Primitive(std::move(val));
  return result;
}
StrictUnion StrictUnion::WithStringNeedsConstructor(::std::string&& val) {
  StrictUnion result;
  result.set_StringNeedsConstructor(std::move(val));
  return result;
}
StrictUnion StrictUnion::WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string>&& val) {
  StrictUnion result;
  result.set_VectorStringAlsoNeedsConstructor(std::move(val));
  return result;
}

void StrictUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::StrictUnion::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &Primitive_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &StringNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &VectorStringAlsoNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void StrictUnion::Decode(::fidl::Decoder* _decoder, StrictUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::StrictUnion::Tag::kPrimitive: {
      ::fidl::Decode(_decoder, &value->Primitive_, value_offset);
      break;
    }
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor: {
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(_decoder, &value->StringNeedsConstructor_, value_offset);
      break;
    }
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor: {
      new (&value->VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      ::fidl::Decode(_decoder, &value->VectorStringAlsoNeedsConstructor_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t StrictUnion::Clone(StrictUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::StrictUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::StrictUnion::Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
      new (&result->StringNeedsConstructor_)::std::string();
      return ::fidl::Clone(StringNeedsConstructor_, &result->StringNeedsConstructor_);
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
      new (&result->VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      return ::fidl::Clone(VectorStringAlsoNeedsConstructor_, &result->VectorStringAlsoNeedsConstructor_);
    default:
      return ZX_OK;
  }
}

StrictUnion& StrictUnion::set_Primitive(int32_t value) {
  EnsureStorageInitialized(::test::union_::StrictUnion::Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

StrictUnion& StrictUnion::set_StringNeedsConstructor(::std::string value) {
  EnsureStorageInitialized(::test::union_::StrictUnion::Tag::kStringNeedsConstructor);
  StringNeedsConstructor_ = std::move(value);
  return *this;
}

StrictUnion& StrictUnion::set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value) {
  EnsureStorageInitialized(::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor);
  VectorStringAlsoNeedsConstructor_ = std::move(value);
  return *this;
}

void StrictUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictUnion::Tag::kPrimitive:
      break;
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
      VectorStringAlsoNeedsConstructor_.~decltype(VectorStringAlsoNeedsConstructor_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid);
}

void StrictUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid):
        break;
      case ::test::union_::StrictUnion::Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_StrictSimpleXUnionTable;
const fidl_type_t* StrictSimpleXUnion::FidlType = &test_union_StrictSimpleXUnionTable;

StrictSimpleXUnion::StrictSimpleXUnion() {}

StrictSimpleXUnion::~StrictSimpleXUnion() {
  Destroy();
}

StrictSimpleXUnion::StrictSimpleXUnion(StrictSimpleXUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::StrictSimpleXUnion::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case ::test::union_::StrictSimpleXUnion::Tag::kF:
      f_ = std::move(other.f_);
      break;
    case ::test::union_::StrictSimpleXUnion::Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid):
      break;
  }
}

StrictSimpleXUnion& StrictSimpleXUnion::operator=(StrictSimpleXUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::StrictSimpleXUnion::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case ::test::union_::StrictSimpleXUnion::Tag::kF:
        f_ = std::move(other.f_);
        break;
      case ::test::union_::StrictSimpleXUnion::Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid):
        break;
    }
  }
  return *this;
}

StrictSimpleXUnion StrictSimpleXUnion::WithI(int32_t&& val) {
  StrictSimpleXUnion result;
  result.set_i(std::move(val));
  return result;
}
StrictSimpleXUnion StrictSimpleXUnion::WithF(float&& val) {
  StrictSimpleXUnion result;
  result.set_f(std::move(val));
  return result;
}
StrictSimpleXUnion StrictSimpleXUnion::WithS(::std::string&& val) {
  StrictSimpleXUnion result;
  result.set_s(std::move(val));
  return result;
}

void StrictSimpleXUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::StrictSimpleXUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::StrictSimpleXUnion::Tag::kF: {
      if (::fidl::EncodingInlineSize<float>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &f_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &f_,
          encoder->Alloc(::fidl::EncodingInlineSize<float, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::StrictSimpleXUnion::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &s_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void StrictSimpleXUnion::Decode(::fidl::Decoder* _decoder, StrictSimpleXUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::StrictSimpleXUnion::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    case ::test::union_::StrictSimpleXUnion::Tag::kF: {
      ::fidl::Decode(_decoder, &value->f_, value_offset);
      break;
    }
    case ::test::union_::StrictSimpleXUnion::Tag::kS: {
      new (&value->s_)::std::string();
      ::fidl::Decode(_decoder, &value->s_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t StrictSimpleXUnion::Clone(StrictSimpleXUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::StrictSimpleXUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::StrictSimpleXUnion::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    case ::test::union_::StrictSimpleXUnion::Tag::kF:
      return ::fidl::Clone(f_, &result->f_);
    case ::test::union_::StrictSimpleXUnion::Tag::kS:
      new (&result->s_)::std::string();
      return ::fidl::Clone(s_, &result->s_);
    default:
      return ZX_OK;
  }
}

StrictSimpleXUnion& StrictSimpleXUnion::set_i(int32_t value) {
  EnsureStorageInitialized(::test::union_::StrictSimpleXUnion::Tag::kI);
  i_ = std::move(value);
  return *this;
}

StrictSimpleXUnion& StrictSimpleXUnion::set_f(float value) {
  EnsureStorageInitialized(::test::union_::StrictSimpleXUnion::Tag::kF);
  f_ = std::move(value);
  return *this;
}

StrictSimpleXUnion& StrictSimpleXUnion::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::StrictSimpleXUnion::Tag::kS);
  s_ = std::move(value);
  return *this;
}

void StrictSimpleXUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictSimpleXUnion::Tag::kI:
      break;
    case ::test::union_::StrictSimpleXUnion::Tag::kF:
      break;
    case ::test::union_::StrictSimpleXUnion::Tag::kS:
      s_.~decltype(s_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid);
}

void StrictSimpleXUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleXUnion::Tag::Invalid):
        break;
      case ::test::union_::StrictSimpleXUnion::Tag::kI:
        new (&i_) int32_t();
        break;
      case ::test::union_::StrictSimpleXUnion::Tag::kF:
        new (&f_) float();
        break;
      case ::test::union_::StrictSimpleXUnion::Tag::kS:
        new (&s_)::std::string();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_StrictFooTable;
const fidl_type_t* StrictFoo::FidlType = &test_union_StrictFooTable;

StrictFoo::StrictFoo() {}

StrictFoo::~StrictFoo() {
  Destroy();
}

StrictFoo::StrictFoo(StrictFoo&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::StrictFoo::Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case ::test::union_::StrictFoo::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid):
      break;
  }
}

StrictFoo& StrictFoo::operator=(StrictFoo&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::StrictFoo::Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case ::test::union_::StrictFoo::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid):
        break;
    }
  }
  return *this;
}

StrictFoo StrictFoo::WithS(::std::string&& val) {
  StrictFoo result;
  result.set_s(std::move(val));
  return result;
}
StrictFoo StrictFoo::WithI(int32_t&& val) {
  StrictFoo result;
  result.set_i(std::move(val));
  return result;
}

void StrictFoo::Encode(::fidl::Encoder* encoder, size_t offset,
                       cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::StrictFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &s_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::StrictFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void StrictFoo::Decode(::fidl::Decoder* _decoder, StrictFoo* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::StrictFoo::Tag::kS: {
      new (&value->s_)::std::string();
      ::fidl::Decode(_decoder, &value->s_, value_offset);
      break;
    }
    case ::test::union_::StrictFoo::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t StrictFoo::Clone(StrictFoo* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::StrictFoo::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::StrictFoo::Tag::kS:
      new (&result->s_)::std::string();
      return ::fidl::Clone(s_, &result->s_);
    case ::test::union_::StrictFoo::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    default:
      return ZX_OK;
  }
}

StrictFoo& StrictFoo::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::StrictFoo::Tag::kS);
  s_ = std::move(value);
  return *this;
}

StrictFoo& StrictFoo::set_i(int32_t value) {
  EnsureStorageInitialized(::test::union_::StrictFoo::Tag::kI);
  i_ = std::move(value);
  return *this;
}

void StrictFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::StrictFoo::Tag::kI:
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid);
}

void StrictFoo::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid):
        break;
      case ::test::union_::StrictFoo::Tag::kS:
        new (&s_)::std::string();
        break;
      case ::test::union_::StrictFoo::Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_StrictBoundedXUnionTable;
const fidl_type_t* StrictBoundedXUnion::FidlType = &test_union_StrictBoundedXUnionTable;

StrictBoundedXUnion::StrictBoundedXUnion() {}

StrictBoundedXUnion::~StrictBoundedXUnion() {
  Destroy();
}

StrictBoundedXUnion::StrictBoundedXUnion(StrictBoundedXUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::StrictBoundedXUnion::Tag::kV:
      new (&v_)::std::vector<uint8_t>();
      v_ = std::move(other.v_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid):
      break;
  }
}

StrictBoundedXUnion& StrictBoundedXUnion::operator=(StrictBoundedXUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::StrictBoundedXUnion::Tag::kV:
        new (&v_)::std::vector<uint8_t>();
        v_ = std::move(other.v_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid):
        break;
    }
  }
  return *this;
}

StrictBoundedXUnion StrictBoundedXUnion::WithV(::std::vector<uint8_t>&& val) {
  StrictBoundedXUnion result;
  result.set_v(std::move(val));
  return result;
}

void StrictBoundedXUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::StrictBoundedXUnion::Tag::kV: {
      if (::fidl::EncodingInlineSize<::std::vector<uint8_t>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &v_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &v_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<uint8_t>, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void StrictBoundedXUnion::Decode(::fidl::Decoder* _decoder, StrictBoundedXUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::StrictBoundedXUnion::Tag::kV: {
      new (&value->v_)::std::vector<uint8_t>();
      ::fidl::Decode(_decoder, &value->v_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t StrictBoundedXUnion::Clone(StrictBoundedXUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::StrictBoundedXUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::StrictBoundedXUnion::Tag::kV:
      new (&result->v_)::std::vector<uint8_t>();
      return ::fidl::Clone(v_, &result->v_);
    default:
      return ZX_OK;
  }
}

StrictBoundedXUnion& StrictBoundedXUnion::set_v(::std::vector<uint8_t> value) {
  EnsureStorageInitialized(::test::union_::StrictBoundedXUnion::Tag::kV);
  v_ = std::move(value);
  return *this;
}

void StrictBoundedXUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictBoundedXUnion::Tag::kV:
      v_.~decltype(v_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid);
}

void StrictBoundedXUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedXUnion::Tag::Invalid):
        break;
      case ::test::union_::StrictBoundedXUnion::Tag::kV:
        new (&v_)::std::vector<uint8_t>();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
const fidl_type_t* TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse::FidlType = &test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;

void TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>::value) {
    memcpy(_encoder->template GetPtr<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>(_offset), this, sizeof(TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse));
  } else {
    ::fidl::Encode(_encoder, &xu, _offset + 0);
  }
}

void TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse::Decode(::fidl::Decoder* _decoder, TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>::value) {
    memcpy(_value, _decoder->template GetPtr<TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse>(_offset), sizeof(TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse));
  } else {
    ::fidl::Decode(_decoder, &_value->xu, _offset + 0);
  }
}

zx_status_t TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse::Clone(TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(xu, &_result->xu);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_ReverseOrdinalUnionTable;
const fidl_type_t* ReverseOrdinalUnion::FidlType = &test_union_ReverseOrdinalUnionTable;

ReverseOrdinalUnion::ReverseOrdinalUnion() {}

ReverseOrdinalUnion::~ReverseOrdinalUnion() {
  Destroy();
}

ReverseOrdinalUnion::ReverseOrdinalUnion(ReverseOrdinalUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
      second_ = std::move(other.second_);
      break;
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
      first_ = std::move(other.first_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid):
      break;
  }
}

ReverseOrdinalUnion& ReverseOrdinalUnion::operator=(ReverseOrdinalUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
        second_ = std::move(other.second_);
        break;
      case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
        first_ = std::move(other.first_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ReverseOrdinalUnion ReverseOrdinalUnion::WithSecond(uint32_t&& val) {
  ReverseOrdinalUnion result;
  result.set_second(std::move(val));
  return result;
}
ReverseOrdinalUnion ReverseOrdinalUnion::WithFirst(uint32_t&& val) {
  ReverseOrdinalUnion result;
  result.set_first(std::move(val));
  return result;
}

void ReverseOrdinalUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &second_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &second_,
          encoder->Alloc(::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &first_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &first_,
          encoder->Alloc(::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ReverseOrdinalUnion::Decode(::fidl::Decoder* _decoder, ReverseOrdinalUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond: {
      ::fidl::Decode(_decoder, &value->second_, value_offset);
      break;
    }
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst: {
      ::fidl::Decode(_decoder, &value->first_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t ReverseOrdinalUnion::Clone(ReverseOrdinalUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::ReverseOrdinalUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
      return ::fidl::Clone(second_, &result->second_);
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
      return ::fidl::Clone(first_, &result->first_);
    default:
      return ZX_OK;
  }
}

ReverseOrdinalUnion& ReverseOrdinalUnion::set_second(uint32_t value) {
  EnsureStorageInitialized(::test::union_::ReverseOrdinalUnion::Tag::kSecond);
  second_ = std::move(value);
  return *this;
}

ReverseOrdinalUnion& ReverseOrdinalUnion::set_first(uint32_t value) {
  EnsureStorageInitialized(::test::union_::ReverseOrdinalUnion::Tag::kFirst);
  first_ = std::move(value);
  return *this;
}

void ReverseOrdinalUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
      break;
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid);
}

void ReverseOrdinalUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid):
        break;
      case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
        new (&second_) uint32_t();
        break;
      case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
        new (&first_) uint32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_PizzaTable;
const fidl_type_t* Pizza::FidlType = &test_union_PizzaTable;

void Pizza::Encode(::fidl::Encoder* _encoder, size_t _offset,
                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<Pizza>::value) {
    memcpy(_encoder->template GetPtr<Pizza>(_offset), this, sizeof(Pizza));
  } else {
    ::fidl::Encode(_encoder, &toppings, _offset + 0);
  }
}

void Pizza::Decode(::fidl::Decoder* _decoder, Pizza* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<Pizza>::value) {
    memcpy(_value, _decoder->template GetPtr<Pizza>(_offset), sizeof(Pizza));
  } else {
    ::fidl::Decode(_decoder, &_value->toppings, _offset + 0);
  }
}

zx_status_t Pizza::Clone(Pizza* _result) const {
  zx_status_t _status = ::fidl::Clone(toppings, &_result->toppings);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_PastaTable;
const fidl_type_t* Pasta::FidlType = &test_union_PastaTable;

void Pasta::Encode(::fidl::Encoder* _encoder, size_t _offset,
                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<Pasta>::value) {
    memcpy(_encoder->template GetPtr<Pasta>(_offset), this, sizeof(Pasta));
  } else {
    ::fidl::Encode(_encoder, &sauce, _offset + 0);
  }
}

void Pasta::Decode(::fidl::Decoder* _decoder, Pasta* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<Pasta>::value) {
    memcpy(_value, _decoder->template GetPtr<Pasta>(_offset), sizeof(Pasta));
  } else {
    ::fidl::Decode(_decoder, &_value->sauce, _offset + 0);
  }
}

zx_status_t Pasta::Clone(Pasta* _result) const {
  zx_status_t _status = ::fidl::Clone(sauce, &_result->sauce);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_StrictPizzaOrPastaTable;
const fidl_type_t* StrictPizzaOrPasta::FidlType = &test_union_StrictPizzaOrPastaTable;

StrictPizzaOrPasta::StrictPizzaOrPasta() {}

StrictPizzaOrPasta::~StrictPizzaOrPasta() {
  Destroy();
}

StrictPizzaOrPasta::StrictPizzaOrPasta(StrictPizzaOrPasta&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
      new (&pizza_)::test::union_::Pizza();
      pizza_ = std::move(other.pizza_);
      break;
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
      new (&pasta_)::test::union_::Pasta();
      pasta_ = std::move(other.pasta_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid):
      break;
  }
}

StrictPizzaOrPasta& StrictPizzaOrPasta::operator=(StrictPizzaOrPasta&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        pizza_ = std::move(other.pizza_);
        break;
      case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        pasta_ = std::move(other.pasta_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid):
        break;
    }
  }
  return *this;
}

StrictPizzaOrPasta StrictPizzaOrPasta::WithPizza(::test::union_::Pizza&& val) {
  StrictPizzaOrPasta result;
  result.set_pizza(std::move(val));
  return result;
}
StrictPizzaOrPasta StrictPizzaOrPasta::WithPasta(::test::union_::Pasta&& val) {
  StrictPizzaOrPasta result;
  result.set_pasta(std::move(val));
  return result;
}

void StrictPizzaOrPasta::Encode(::fidl::Encoder* encoder, size_t offset,
                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pizza_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pasta_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void StrictPizzaOrPasta::Decode(::fidl::Decoder* _decoder, StrictPizzaOrPasta* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza: {
      new (&value->pizza_)::test::union_::Pizza();
      ::fidl::Decode(_decoder, &value->pizza_, value_offset);
      break;
    }
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta: {
      new (&value->pasta_)::test::union_::Pasta();
      ::fidl::Decode(_decoder, &value->pasta_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t StrictPizzaOrPasta::Clone(StrictPizzaOrPasta* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::StrictPizzaOrPasta::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
      new (&result->pizza_)::test::union_::Pizza();
      return ::fidl::Clone(pizza_, &result->pizza_);
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
      new (&result->pasta_)::test::union_::Pasta();
      return ::fidl::Clone(pasta_, &result->pasta_);
    default:
      return ZX_OK;
  }
}

StrictPizzaOrPasta& StrictPizzaOrPasta::set_pizza(::test::union_::Pizza value) {
  EnsureStorageInitialized(::test::union_::StrictPizzaOrPasta::Tag::kPizza);
  pizza_ = std::move(value);
  return *this;
}

StrictPizzaOrPasta& StrictPizzaOrPasta::set_pasta(::test::union_::Pasta value) {
  EnsureStorageInitialized(::test::union_::StrictPizzaOrPasta::Tag::kPasta);
  pasta_ = std::move(value);
  return *this;
}

void StrictPizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid);
}

void StrictPizzaOrPasta::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid):
        break;
      case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        break;
      case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_PizzaOrPastaTable;
const fidl_type_t* PizzaOrPasta::FidlType = &test_union_PizzaOrPastaTable;

PizzaOrPasta::PizzaOrPasta() {}

PizzaOrPasta::~PizzaOrPasta() {
  Destroy();
}

PizzaOrPasta::PizzaOrPasta(PizzaOrPasta&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::PizzaOrPasta::Tag::kPizza:
      new (&pizza_)::test::union_::Pizza();
      pizza_ = std::move(other.pizza_);
      break;
    case ::test::union_::PizzaOrPasta::Tag::kPasta:
      new (&pasta_)::test::union_::Pasta();
      pasta_ = std::move(other.pasta_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid):
      break;
  }
}

PizzaOrPasta& PizzaOrPasta::operator=(PizzaOrPasta&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::PizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        pizza_ = std::move(other.pizza_);
        break;
      case ::test::union_::PizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        pasta_ = std::move(other.pasta_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid):
        break;
    }
  }
  return *this;
}

PizzaOrPasta PizzaOrPasta::WithPizza(::test::union_::Pizza&& val) {
  PizzaOrPasta result;
  result.set_pizza(std::move(val));
  return result;
}
PizzaOrPasta PizzaOrPasta::WithPasta(::test::union_::Pasta&& val) {
  PizzaOrPasta result;
  result.set_pasta(std::move(val));
  return result;
}

void PizzaOrPasta::Encode(::fidl::Encoder* encoder, size_t offset,
                          cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::PizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pizza_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::PizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pasta_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void PizzaOrPasta::Decode(::fidl::Decoder* _decoder, PizzaOrPasta* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::PizzaOrPasta::Tag::kPizza: {
      new (&value->pizza_)::test::union_::Pizza();
      ::fidl::Decode(_decoder, &value->pizza_, value_offset);
      break;
    }
    case ::test::union_::PizzaOrPasta::Tag::kPasta: {
      new (&value->pasta_)::test::union_::Pasta();
      ::fidl::Decode(_decoder, &value->pasta_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t PizzaOrPasta::Clone(PizzaOrPasta* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::PizzaOrPasta::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::PizzaOrPasta::Tag::kPizza:
      new (&result->pizza_)::test::union_::Pizza();
      return ::fidl::Clone(pizza_, &result->pizza_);
    case ::test::union_::PizzaOrPasta::Tag::kPasta:
      new (&result->pasta_)::test::union_::Pasta();
      return ::fidl::Clone(pasta_, &result->pasta_);
    default:
      return ZX_OK;
  }
}

PizzaOrPasta& PizzaOrPasta::set_pizza(::test::union_::Pizza value) {
  EnsureStorageInitialized(::test::union_::PizzaOrPasta::Tag::kPizza);
  pizza_ = std::move(value);
  return *this;
}

PizzaOrPasta& PizzaOrPasta::set_pasta(::test::union_::Pasta value) {
  EnsureStorageInitialized(::test::union_::PizzaOrPasta::Tag::kPasta);
  pasta_ = std::move(value);
  return *this;
}

void PizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::PizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::PizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid);
}

void PizzaOrPasta::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid):
        break;
      case ::test::union_::PizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        break;
      case ::test::union_::PizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_FlexiblePizzaOrPastaTable;
const fidl_type_t* FlexiblePizzaOrPasta::FidlType = &test_union_FlexiblePizzaOrPastaTable;

FlexiblePizzaOrPasta::FlexiblePizzaOrPasta() {}

FlexiblePizzaOrPasta::~FlexiblePizzaOrPasta() {
  Destroy();
}

FlexiblePizzaOrPasta::FlexiblePizzaOrPasta(FlexiblePizzaOrPasta&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
      new (&pizza_)::test::union_::Pizza();
      pizza_ = std::move(other.pizza_);
      break;
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
      new (&pasta_)::test::union_::Pasta();
      pasta_ = std::move(other.pasta_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

FlexiblePizzaOrPasta& FlexiblePizzaOrPasta::operator=(FlexiblePizzaOrPasta&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        pizza_ = std::move(other.pizza_);
        break;
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        pasta_ = std::move(other.pasta_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

FlexiblePizzaOrPasta FlexiblePizzaOrPasta::WithPizza(::test::union_::Pizza&& val) {
  FlexiblePizzaOrPasta result;
  result.set_pizza(std::move(val));
  return result;
}
FlexiblePizzaOrPasta FlexiblePizzaOrPasta::WithPasta(::test::union_::Pasta&& val) {
  FlexiblePizzaOrPasta result;
  result.set_pasta(std::move(val));
  return result;
}

void FlexiblePizzaOrPasta::Encode(::fidl::Encoder* encoder, size_t offset,
                                  cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pizza_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pasta_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void FlexiblePizzaOrPasta::Decode(::fidl::Decoder* _decoder, FlexiblePizzaOrPasta* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza: {
      new (&value->pizza_)::test::union_::Pizza();
      ::fidl::Decode(_decoder, &value->pizza_, value_offset);
      break;
    }
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta: {
      new (&value->pasta_)::test::union_::Pasta();
      ::fidl::Decode(_decoder, &value->pasta_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t FlexiblePizzaOrPasta::Clone(FlexiblePizzaOrPasta* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
      new (&result->pizza_)::test::union_::Pizza();
      return ::fidl::Clone(pizza_, &result->pizza_);
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
      new (&result->pasta_)::test::union_::Pasta();
      return ::fidl::Clone(pasta_, &result->pasta_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

FlexiblePizzaOrPasta& FlexiblePizzaOrPasta::set_pizza(::test::union_::Pizza value) {
  EnsureStorageInitialized(::test::union_::FlexiblePizzaOrPasta::Tag::kPizza);
  pizza_ = std::move(value);
  return *this;
}

FlexiblePizzaOrPasta& FlexiblePizzaOrPasta::set_pasta(::test::union_::Pasta value) {
  EnsureStorageInitialized(::test::union_::FlexiblePizzaOrPasta::Tag::kPasta);
  pasta_ = std::move(value);
  return *this;
}
FlexiblePizzaOrPasta& FlexiblePizzaOrPasta::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void FlexiblePizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid);
}

void FlexiblePizzaOrPasta::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
        break;
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        break;
      case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_ExplicitPizzaOrPastaTable;
const fidl_type_t* ExplicitPizzaOrPasta::FidlType = &test_union_ExplicitPizzaOrPastaTable;

ExplicitPizzaOrPasta::ExplicitPizzaOrPasta() {}

ExplicitPizzaOrPasta::~ExplicitPizzaOrPasta() {
  Destroy();
}

ExplicitPizzaOrPasta::ExplicitPizzaOrPasta(ExplicitPizzaOrPasta&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
      new (&pizza_)::test::union_::Pizza();
      pizza_ = std::move(other.pizza_);
      break;
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
      new (&pasta_)::test::union_::Pasta();
      pasta_ = std::move(other.pasta_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid):
      break;
  }
}

ExplicitPizzaOrPasta& ExplicitPizzaOrPasta::operator=(ExplicitPizzaOrPasta&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        pizza_ = std::move(other.pizza_);
        break;
      case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        pasta_ = std::move(other.pasta_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ExplicitPizzaOrPasta ExplicitPizzaOrPasta::WithPizza(::test::union_::Pizza&& val) {
  ExplicitPizzaOrPasta result;
  result.set_pizza(std::move(val));
  return result;
}
ExplicitPizzaOrPasta ExplicitPizzaOrPasta::WithPasta(::test::union_::Pasta&& val) {
  ExplicitPizzaOrPasta result;
  result.set_pasta(std::move(val));
  return result;
}

void ExplicitPizzaOrPasta::Encode(::fidl::Encoder* encoder, size_t offset,
                                  cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pizza_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &pasta_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ExplicitPizzaOrPasta::Decode(::fidl::Decoder* _decoder, ExplicitPizzaOrPasta* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza: {
      new (&value->pizza_)::test::union_::Pizza();
      ::fidl::Decode(_decoder, &value->pizza_, value_offset);
      break;
    }
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta: {
      new (&value->pasta_)::test::union_::Pasta();
      ::fidl::Decode(_decoder, &value->pasta_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t ExplicitPizzaOrPasta::Clone(ExplicitPizzaOrPasta* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
      new (&result->pizza_)::test::union_::Pizza();
      return ::fidl::Clone(pizza_, &result->pizza_);
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
      new (&result->pasta_)::test::union_::Pasta();
      return ::fidl::Clone(pasta_, &result->pasta_);
    default:
      return ZX_OK;
  }
}

ExplicitPizzaOrPasta& ExplicitPizzaOrPasta::set_pizza(::test::union_::Pizza value) {
  EnsureStorageInitialized(::test::union_::ExplicitPizzaOrPasta::Tag::kPizza);
  pizza_ = std::move(value);
  return *this;
}

ExplicitPizzaOrPasta& ExplicitPizzaOrPasta::set_pasta(::test::union_::Pasta value) {
  EnsureStorageInitialized(::test::union_::ExplicitPizzaOrPasta::Tag::kPasta);
  pasta_ = std::move(value);
  return *this;
}

void ExplicitPizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid);
}

void ExplicitPizzaOrPasta::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid):
        break;
      case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
        new (&pizza_)::test::union_::Pizza();
        break;
      case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
        new (&pasta_)::test::union_::Pasta();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_OlderSimpleUnionTable;
const fidl_type_t* OlderSimpleUnion::FidlType = &test_union_OlderSimpleUnionTable;

OlderSimpleUnion::OlderSimpleUnion() {}

OlderSimpleUnion::~OlderSimpleUnion() {
  Destroy();
}

OlderSimpleUnion::OlderSimpleUnion(OlderSimpleUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::OlderSimpleUnion::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case ::test::union_::OlderSimpleUnion::Tag::kF:
      f_ = std::move(other.f_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

OlderSimpleUnion& OlderSimpleUnion::operator=(OlderSimpleUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::OlderSimpleUnion::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case ::test::union_::OlderSimpleUnion::Tag::kF:
        f_ = std::move(other.f_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

OlderSimpleUnion OlderSimpleUnion::WithI(int64_t&& val) {
  OlderSimpleUnion result;
  result.set_i(std::move(val));
  return result;
}
OlderSimpleUnion OlderSimpleUnion::WithF(float&& val) {
  OlderSimpleUnion result;
  result.set_f(std::move(val));
  return result;
}

void OlderSimpleUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                              cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::OlderSimpleUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::OlderSimpleUnion::Tag::kF: {
      if (::fidl::EncodingInlineSize<float>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &f_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &f_,
          encoder->Alloc(::fidl::EncodingInlineSize<float, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::OlderSimpleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void OlderSimpleUnion::Decode(::fidl::Decoder* _decoder, OlderSimpleUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::OlderSimpleUnion::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    case ::test::union_::OlderSimpleUnion::Tag::kF: {
      ::fidl::Decode(_decoder, &value->f_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t OlderSimpleUnion::Clone(OlderSimpleUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::OlderSimpleUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::OlderSimpleUnion::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    case ::test::union_::OlderSimpleUnion::Tag::kF:
      return ::fidl::Clone(f_, &result->f_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

OlderSimpleUnion& OlderSimpleUnion::set_i(int64_t value) {
  EnsureStorageInitialized(::test::union_::OlderSimpleUnion::Tag::kI);
  i_ = std::move(value);
  return *this;
}

OlderSimpleUnion& OlderSimpleUnion::set_f(float value) {
  EnsureStorageInitialized(::test::union_::OlderSimpleUnion::Tag::kF);
  f_ = std::move(value);
  return *this;
}
OlderSimpleUnion& OlderSimpleUnion::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void OlderSimpleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::OlderSimpleUnion::Tag::kI:
      break;
    case ::test::union_::OlderSimpleUnion::Tag::kF:
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid);
}

void OlderSimpleUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid):
        break;
      case ::test::union_::OlderSimpleUnion::Tag::kI:
        new (&i_) int64_t();
        break;
      case ::test::union_::OlderSimpleUnion::Tag::kF:
        new (&f_) float();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;
const fidl_type_t* TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse::FidlType = &test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;

void TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                                                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>::value) {
    memcpy(_encoder->template GetPtr<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>(_offset), this, sizeof(TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse));
  } else {
    ::fidl::Encode(_encoder, &xu, _offset + 0);
  }
}

void TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse::Decode(::fidl::Decoder* _decoder, TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>::value) {
    memcpy(_value, _decoder->template GetPtr<TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse>(_offset), sizeof(TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse));
  } else {
    ::fidl::Decode(_decoder, &_value->xu, _offset + 0);
  }
}

zx_status_t TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse::Clone(TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(xu, &_result->xu);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_NullableUnionStructTable;
const fidl_type_t* NullableUnionStruct::FidlType = &test_union_NullableUnionStructTable;

void NullableUnionStruct::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<NullableUnionStruct>::value) {
    memcpy(_encoder->template GetPtr<NullableUnionStruct>(_offset), this, sizeof(NullableUnionStruct));
  } else {
    ::fidl::Encode(_encoder, &the_union, _offset + 0);
  }
}

void NullableUnionStruct::Decode(::fidl::Decoder* _decoder, NullableUnionStruct* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<NullableUnionStruct>::value) {
    memcpy(_value, _decoder->template GetPtr<NullableUnionStruct>(_offset), sizeof(NullableUnionStruct));
  } else {
    ::fidl::Decode(_decoder, &_value->the_union, _offset + 0);
  }
}

zx_status_t NullableUnionStruct::Clone(NullableUnionStruct* _result) const {
  zx_status_t _status = ::fidl::Clone(the_union, &_result->the_union);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_NewerSimpleUnionTable;
const fidl_type_t* NewerSimpleUnion::FidlType = &test_union_NewerSimpleUnionTable;

NewerSimpleUnion::NewerSimpleUnion() {}

NewerSimpleUnion::~NewerSimpleUnion() {
  Destroy();
}

NewerSimpleUnion::NewerSimpleUnion(NewerSimpleUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::NewerSimpleUnion::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case ::test::union_::NewerSimpleUnion::Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case ::test::union_::NewerSimpleUnion::Tag::kV:
      new (&v_)::std::vector<::std::string>();
      v_ = std::move(other.v_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

NewerSimpleUnion& NewerSimpleUnion::operator=(NewerSimpleUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::NewerSimpleUnion::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case ::test::union_::NewerSimpleUnion::Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case ::test::union_::NewerSimpleUnion::Tag::kV:
        new (&v_)::std::vector<::std::string>();
        v_ = std::move(other.v_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

NewerSimpleUnion NewerSimpleUnion::WithI(int64_t&& val) {
  NewerSimpleUnion result;
  result.set_i(std::move(val));
  return result;
}
NewerSimpleUnion NewerSimpleUnion::WithS(::std::string&& val) {
  NewerSimpleUnion result;
  result.set_s(std::move(val));
  return result;
}
NewerSimpleUnion NewerSimpleUnion::WithV(::std::vector<::std::string>&& val) {
  NewerSimpleUnion result;
  result.set_v(std::move(val));
  return result;
}

void NewerSimpleUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                              cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::NewerSimpleUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &s_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kV: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &v_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &v_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void NewerSimpleUnion::Decode(::fidl::Decoder* _decoder, NewerSimpleUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::NewerSimpleUnion::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kS: {
      new (&value->s_)::std::string();
      ::fidl::Decode(_decoder, &value->s_, value_offset);
      break;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kV: {
      new (&value->v_)::std::vector<::std::string>();
      ::fidl::Decode(_decoder, &value->v_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t NewerSimpleUnion::Clone(NewerSimpleUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::NewerSimpleUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::NewerSimpleUnion::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    case ::test::union_::NewerSimpleUnion::Tag::kS:
      new (&result->s_)::std::string();
      return ::fidl::Clone(s_, &result->s_);
    case ::test::union_::NewerSimpleUnion::Tag::kV:
      new (&result->v_)::std::vector<::std::string>();
      return ::fidl::Clone(v_, &result->v_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

NewerSimpleUnion& NewerSimpleUnion::set_i(int64_t value) {
  EnsureStorageInitialized(::test::union_::NewerSimpleUnion::Tag::kI);
  i_ = std::move(value);
  return *this;
}

NewerSimpleUnion& NewerSimpleUnion::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::NewerSimpleUnion::Tag::kS);
  s_ = std::move(value);
  return *this;
}

NewerSimpleUnion& NewerSimpleUnion::set_v(::std::vector<::std::string> value) {
  EnsureStorageInitialized(::test::union_::NewerSimpleUnion::Tag::kV);
  v_ = std::move(value);
  return *this;
}
NewerSimpleUnion& NewerSimpleUnion::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void NewerSimpleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::NewerSimpleUnion::Tag::kI:
      break;
    case ::test::union_::NewerSimpleUnion::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::NewerSimpleUnion::Tag::kV:
      v_.~decltype(v_)();
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid);
}

void NewerSimpleUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid):
        break;
      case ::test::union_::NewerSimpleUnion::Tag::kI:
        new (&i_) int64_t();
        break;
      case ::test::union_::NewerSimpleUnion::Tag::kS:
        new (&s_)::std::string();
        break;
      case ::test::union_::NewerSimpleUnion::Tag::kV:
        new (&v_)::std::vector<::std::string>();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_FlexibleUnionTable;
const fidl_type_t* FlexibleUnion::FidlType = &test_union_FlexibleUnionTable;

FlexibleUnion::FlexibleUnion() {}

FlexibleUnion::~FlexibleUnion() {
  Destroy();
}

FlexibleUnion::FlexibleUnion(FlexibleUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::FlexibleUnion::Tag::kPrimitive:
      Primitive_ = std::move(other.Primitive_);
      break;
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
      new (&StringNeedsConstructor_)::std::string();
      StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
      break;
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
      new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      VectorStringAlsoNeedsConstructor_ = std::move(other.VectorStringAlsoNeedsConstructor_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

FlexibleUnion& FlexibleUnion::operator=(FlexibleUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::FlexibleUnion::Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        VectorStringAlsoNeedsConstructor_ = std::move(other.VectorStringAlsoNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

FlexibleUnion FlexibleUnion::WithPrimitive(int32_t&& val) {
  FlexibleUnion result;
  result.set_Primitive(std::move(val));
  return result;
}
FlexibleUnion FlexibleUnion::WithStringNeedsConstructor(::std::string&& val) {
  FlexibleUnion result;
  result.set_StringNeedsConstructor(std::move(val));
  return result;
}
FlexibleUnion FlexibleUnion::WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string>&& val) {
  FlexibleUnion result;
  result.set_VectorStringAlsoNeedsConstructor(std::move(val));
  return result;
}

void FlexibleUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                           cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::FlexibleUnion::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &Primitive_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &StringNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &VectorStringAlsoNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexibleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void FlexibleUnion::Decode(::fidl::Decoder* _decoder, FlexibleUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::FlexibleUnion::Tag::kPrimitive: {
      ::fidl::Decode(_decoder, &value->Primitive_, value_offset);
      break;
    }
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor: {
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(_decoder, &value->StringNeedsConstructor_, value_offset);
      break;
    }
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor: {
      new (&value->VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      ::fidl::Decode(_decoder, &value->VectorStringAlsoNeedsConstructor_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t FlexibleUnion::Clone(FlexibleUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::FlexibleUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::FlexibleUnion::Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
      new (&result->StringNeedsConstructor_)::std::string();
      return ::fidl::Clone(StringNeedsConstructor_, &result->StringNeedsConstructor_);
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
      new (&result->VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      return ::fidl::Clone(VectorStringAlsoNeedsConstructor_, &result->VectorStringAlsoNeedsConstructor_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

FlexibleUnion& FlexibleUnion::set_Primitive(int32_t value) {
  EnsureStorageInitialized(::test::union_::FlexibleUnion::Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

FlexibleUnion& FlexibleUnion::set_StringNeedsConstructor(::std::string value) {
  EnsureStorageInitialized(::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor);
  StringNeedsConstructor_ = std::move(value);
  return *this;
}

FlexibleUnion& FlexibleUnion::set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value) {
  EnsureStorageInitialized(::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor);
  VectorStringAlsoNeedsConstructor_ = std::move(value);
  return *this;
}
FlexibleUnion& FlexibleUnion::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void FlexibleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::FlexibleUnion::Tag::kPrimitive:
      break;
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
      VectorStringAlsoNeedsConstructor_.~decltype(VectorStringAlsoNeedsConstructor_)();
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid);
}

void FlexibleUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid):
        break;
      case ::test::union_::FlexibleUnion::Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_FlexibleFooTable;
const fidl_type_t* FlexibleFoo::FidlType = &test_union_FlexibleFooTable;

FlexibleFoo::FlexibleFoo() {}

FlexibleFoo::~FlexibleFoo() {
  Destroy();
}

FlexibleFoo::FlexibleFoo(FlexibleFoo&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::FlexibleFoo::Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case ::test::union_::FlexibleFoo::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

FlexibleFoo& FlexibleFoo::operator=(FlexibleFoo&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::FlexibleFoo::Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case ::test::union_::FlexibleFoo::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

FlexibleFoo FlexibleFoo::WithS(::std::string&& val) {
  FlexibleFoo result;
  result.set_s(std::move(val));
  return result;
}
FlexibleFoo FlexibleFoo::WithI(int32_t&& val) {
  FlexibleFoo result;
  result.set_i(std::move(val));
  return result;
}

void FlexibleFoo::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::FlexibleFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &s_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexibleFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::FlexibleFoo::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void FlexibleFoo::Decode(::fidl::Decoder* _decoder, FlexibleFoo* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::FlexibleFoo::Tag::kS: {
      new (&value->s_)::std::string();
      ::fidl::Decode(_decoder, &value->s_, value_offset);
      break;
    }
    case ::test::union_::FlexibleFoo::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t FlexibleFoo::Clone(FlexibleFoo* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::FlexibleFoo::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::FlexibleFoo::Tag::kS:
      new (&result->s_)::std::string();
      return ::fidl::Clone(s_, &result->s_);
    case ::test::union_::FlexibleFoo::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

FlexibleFoo& FlexibleFoo::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::FlexibleFoo::Tag::kS);
  s_ = std::move(value);
  return *this;
}

FlexibleFoo& FlexibleFoo::set_i(int32_t value) {
  EnsureStorageInitialized(::test::union_::FlexibleFoo::Tag::kI);
  i_ = std::move(value);
  return *this;
}
FlexibleFoo& FlexibleFoo::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void FlexibleFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::FlexibleFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::FlexibleFoo::Tag::kI:
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid);
}

void FlexibleFoo::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid):
        break;
      case ::test::union_::FlexibleFoo::Tag::kS:
        new (&s_)::std::string();
        break;
      case ::test::union_::FlexibleFoo::Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_FieldCollisionTable;
const fidl_type_t* FieldCollision::FidlType = &test_union_FieldCollisionTable;

FieldCollision::FieldCollision() {}

FieldCollision::~FieldCollision() {
  Destroy();
}

FieldCollision::FieldCollision(FieldCollision&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
      field_collision_tag_ = std::move(other.field_collision_tag_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid):
      break;
  }
}

FieldCollision& FieldCollision::operator=(FieldCollision&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
        field_collision_tag_ = std::move(other.field_collision_tag_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid):
        break;
    }
  }
  return *this;
}

FieldCollision FieldCollision::WithFieldCollisionTag(int32_t&& val) {
  FieldCollision result;
  result.set_field_collision_tag(std::move(val));
  return result;
}

void FieldCollision::Encode(::fidl::Encoder* encoder, size_t offset,
                            cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &field_collision_tag_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &field_collision_tag_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void FieldCollision::Decode(::fidl::Decoder* _decoder, FieldCollision* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag: {
      ::fidl::Decode(_decoder, &value->field_collision_tag_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t FieldCollision::Clone(FieldCollision* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::FieldCollision::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
      return ::fidl::Clone(field_collision_tag_, &result->field_collision_tag_);
    default:
      return ZX_OK;
  }
}

FieldCollision& FieldCollision::set_field_collision_tag(int32_t value) {
  EnsureStorageInitialized(::test::union_::FieldCollision::Tag::kFieldCollisionTag);
  field_collision_tag_ = std::move(value);
  return *this;
}

void FieldCollision::Destroy() {
  switch (tag_) {
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid);
}

void FieldCollision::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid):
        break;
      case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
        new (&field_collision_tag_) int32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_ExplicitXUnionTable;
const fidl_type_t* ExplicitXUnion::FidlType = &test_union_ExplicitXUnionTable;

ExplicitXUnion::ExplicitXUnion() {}

ExplicitXUnion::~ExplicitXUnion() {
  Destroy();
}

ExplicitXUnion::ExplicitXUnion(ExplicitXUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::ExplicitXUnion::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case ::test::union_::ExplicitXUnion::Tag::kF:
      f_ = std::move(other.f_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

ExplicitXUnion& ExplicitXUnion::operator=(ExplicitXUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::ExplicitXUnion::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case ::test::union_::ExplicitXUnion::Tag::kF:
        f_ = std::move(other.f_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

ExplicitXUnion ExplicitXUnion::WithI(int64_t&& val) {
  ExplicitXUnion result;
  result.set_i(std::move(val));
  return result;
}
ExplicitXUnion ExplicitXUnion::WithF(float&& val) {
  ExplicitXUnion result;
  result.set_f(std::move(val));
  return result;
}

void ExplicitXUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                            cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::ExplicitXUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitXUnion::Tag::kF: {
      if (::fidl::EncodingInlineSize<float>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &f_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &f_,
          encoder->Alloc(::fidl::EncodingInlineSize<float, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitXUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void ExplicitXUnion::Decode(::fidl::Decoder* _decoder, ExplicitXUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::ExplicitXUnion::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    case ::test::union_::ExplicitXUnion::Tag::kF: {
      ::fidl::Decode(_decoder, &value->f_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t ExplicitXUnion::Clone(ExplicitXUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::ExplicitXUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::ExplicitXUnion::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    case ::test::union_::ExplicitXUnion::Tag::kF:
      return ::fidl::Clone(f_, &result->f_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

ExplicitXUnion& ExplicitXUnion::set_i(int64_t value) {
  EnsureStorageInitialized(::test::union_::ExplicitXUnion::Tag::kI);
  i_ = std::move(value);
  return *this;
}

ExplicitXUnion& ExplicitXUnion::set_f(float value) {
  EnsureStorageInitialized(::test::union_::ExplicitXUnion::Tag::kF);
  f_ = std::move(value);
  return *this;
}
ExplicitXUnion& ExplicitXUnion::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void ExplicitXUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitXUnion::Tag::kI:
      break;
    case ::test::union_::ExplicitXUnion::Tag::kF:
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid);
}

void ExplicitXUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitXUnion::Tag::Invalid):
        break;
      case ::test::union_::ExplicitXUnion::Tag::kI:
        new (&i_) int64_t();
        break;
      case ::test::union_::ExplicitXUnion::Tag::kF:
        new (&f_) float();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_UnionSandwichTable;
const fidl_type_t* UnionSandwich::FidlType = &test_union_UnionSandwichTable;

void UnionSandwich::Encode(::fidl::Encoder* _encoder, size_t _offset,
                           cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<UnionSandwich>::value) {
    memcpy(_encoder->template GetPtr<UnionSandwich>(_offset), this, sizeof(UnionSandwich));
  } else {
    ::fidl::Encode(_encoder, &a, _offset + 0);
    ::fidl::Encode(_encoder, &u, _offset + 8);
    ::fidl::Encode(_encoder, &b, _offset + 24);
  }
}

void UnionSandwich::Decode(::fidl::Decoder* _decoder, UnionSandwich* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<UnionSandwich>::value) {
    memcpy(_value, _decoder->template GetPtr<UnionSandwich>(_offset), sizeof(UnionSandwich));
  } else {
    ::fidl::Decode(_decoder, &_value->a, _offset + 0);
    ::fidl::Decode(_decoder, &_value->u, _offset + 8);
    ::fidl::Decode(_decoder, &_value->b, _offset + 24);
  }
}

zx_status_t UnionSandwich::Clone(UnionSandwich* _result) const {
  zx_status_t _status = ::fidl::Clone(a, &_result->a);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(u, &_result->u);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(b, &_result->b);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_ExplicitUnionTable;
const fidl_type_t* ExplicitUnion::FidlType = &test_union_ExplicitUnionTable;

ExplicitUnion::ExplicitUnion() {}

ExplicitUnion::~ExplicitUnion() {
  Destroy();
}

ExplicitUnion::ExplicitUnion(ExplicitUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::ExplicitUnion::Tag::kPrimitive:
      Primitive_ = std::move(other.Primitive_);
      break;
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
      new (&StringNeedsConstructor_)::std::string();
      StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid):
      break;
  }
}

ExplicitUnion& ExplicitUnion::operator=(ExplicitUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::ExplicitUnion::Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ExplicitUnion ExplicitUnion::WithPrimitive(int32_t&& val) {
  ExplicitUnion result;
  result.set_Primitive(std::move(val));
  return result;
}
ExplicitUnion ExplicitUnion::WithStringNeedsConstructor(::std::string&& val) {
  ExplicitUnion result;
  result.set_StringNeedsConstructor(std::move(val));
  return result;
}

void ExplicitUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                           cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::ExplicitUnion::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &Primitive_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &StringNeedsConstructor_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ExplicitUnion::Decode(::fidl::Decoder* _decoder, ExplicitUnion* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::ExplicitUnion::Tag::kPrimitive: {
      ::fidl::Decode(_decoder, &value->Primitive_, value_offset);
      break;
    }
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor: {
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(_decoder, &value->StringNeedsConstructor_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t ExplicitUnion::Clone(ExplicitUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::ExplicitUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::ExplicitUnion::Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
      new (&result->StringNeedsConstructor_)::std::string();
      return ::fidl::Clone(StringNeedsConstructor_, &result->StringNeedsConstructor_);
    default:
      return ZX_OK;
  }
}

ExplicitUnion& ExplicitUnion::set_Primitive(int32_t value) {
  EnsureStorageInitialized(::test::union_::ExplicitUnion::Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

ExplicitUnion& ExplicitUnion::set_StringNeedsConstructor(::std::string value) {
  EnsureStorageInitialized(::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor);
  StringNeedsConstructor_ = std::move(value);
  return *this;
}

void ExplicitUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitUnion::Tag::kPrimitive:
      break;
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid);
}

void ExplicitUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid):
        break;
      case ::test::union_::ExplicitUnion::Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_ExplicitStrictFooTable;
const fidl_type_t* ExplicitStrictFoo::FidlType = &test_union_ExplicitStrictFooTable;

ExplicitStrictFoo::ExplicitStrictFoo() {}

ExplicitStrictFoo::~ExplicitStrictFoo() {
  Destroy();
}

ExplicitStrictFoo::ExplicitStrictFoo(ExplicitStrictFoo&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::ExplicitStrictFoo::Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case ::test::union_::ExplicitStrictFoo::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid):
      break;
  }
}

ExplicitStrictFoo& ExplicitStrictFoo::operator=(ExplicitStrictFoo&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::ExplicitStrictFoo::Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case ::test::union_::ExplicitStrictFoo::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ExplicitStrictFoo ExplicitStrictFoo::WithS(::std::string&& val) {
  ExplicitStrictFoo result;
  result.set_s(std::move(val));
  return result;
}
ExplicitStrictFoo ExplicitStrictFoo::WithI(int32_t&& val) {
  ExplicitStrictFoo result;
  result.set_i(std::move(val));
  return result;
}

void ExplicitStrictFoo::Encode(::fidl::Encoder* encoder, size_t offset,
                               cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::ExplicitStrictFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &s_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitStrictFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ExplicitStrictFoo::Decode(::fidl::Decoder* _decoder, ExplicitStrictFoo* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::ExplicitStrictFoo::Tag::kS: {
      new (&value->s_)::std::string();
      ::fidl::Decode(_decoder, &value->s_, value_offset);
      break;
    }
    case ::test::union_::ExplicitStrictFoo::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t ExplicitStrictFoo::Clone(ExplicitStrictFoo* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::ExplicitStrictFoo::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::ExplicitStrictFoo::Tag::kS:
      new (&result->s_)::std::string();
      return ::fidl::Clone(s_, &result->s_);
    case ::test::union_::ExplicitStrictFoo::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    default:
      return ZX_OK;
  }
}

ExplicitStrictFoo& ExplicitStrictFoo::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::ExplicitStrictFoo::Tag::kS);
  s_ = std::move(value);
  return *this;
}

ExplicitStrictFoo& ExplicitStrictFoo::set_i(int32_t value) {
  EnsureStorageInitialized(::test::union_::ExplicitStrictFoo::Tag::kI);
  i_ = std::move(value);
  return *this;
}

void ExplicitStrictFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitStrictFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::ExplicitStrictFoo::Tag::kI:
      break;

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid);
}

void ExplicitStrictFoo::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid):
        break;
      case ::test::union_::ExplicitStrictFoo::Tag::kS:
        new (&s_)::std::string();
        break;
      case ::test::union_::ExplicitStrictFoo::Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_ExplicitFooTable;
const fidl_type_t* ExplicitFoo::FidlType = &test_union_ExplicitFooTable;

ExplicitFoo::ExplicitFoo() {}

ExplicitFoo::~ExplicitFoo() {
  Destroy();
}

ExplicitFoo::ExplicitFoo(ExplicitFoo&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::ExplicitFoo::Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case ::test::union_::ExplicitFoo::Tag::kI:
      i_ = std::move(other.i_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

ExplicitFoo& ExplicitFoo::operator=(ExplicitFoo&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::ExplicitFoo::Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case ::test::union_::ExplicitFoo::Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

ExplicitFoo ExplicitFoo::WithS(::std::string&& val) {
  ExplicitFoo result;
  result.set_s(std::move(val));
  return result;
}
ExplicitFoo ExplicitFoo::WithI(int32_t&& val) {
  ExplicitFoo result;
  result.set_i(std::move(val));
  return result;
}

void ExplicitFoo::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::ExplicitFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &s_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &i_,
          encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::ExplicitFoo::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void ExplicitFoo::Decode(::fidl::Decoder* _decoder, ExplicitFoo* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::ExplicitFoo::Tag::kS: {
      new (&value->s_)::std::string();
      ::fidl::Decode(_decoder, &value->s_, value_offset);
      break;
    }
    case ::test::union_::ExplicitFoo::Tag::kI: {
      ::fidl::Decode(_decoder, &value->i_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t ExplicitFoo::Clone(ExplicitFoo* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::ExplicitFoo::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::ExplicitFoo::Tag::kS:
      new (&result->s_)::std::string();
      return ::fidl::Clone(s_, &result->s_);
    case ::test::union_::ExplicitFoo::Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

ExplicitFoo& ExplicitFoo::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::ExplicitFoo::Tag::kS);
  s_ = std::move(value);
  return *this;
}

ExplicitFoo& ExplicitFoo::set_i(int32_t value) {
  EnsureStorageInitialized(::test::union_::ExplicitFoo::Tag::kI);
  i_ = std::move(value);
  return *this;
}
ExplicitFoo& ExplicitFoo::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void ExplicitFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::ExplicitFoo::Tag::kI:
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid);
}

void ExplicitFoo::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid):
        break;
      case ::test::union_::ExplicitFoo::Tag::kS:
        new (&s_)::std::string();
        break;
      case ::test::union_::ExplicitFoo::Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

extern "C" const fidl_type_t test_union_EmptyTable;
const fidl_type_t* Empty::FidlType = &test_union_EmptyTable;

void Empty::Encode(::fidl::Encoder* _encoder, size_t _offset,
                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<Empty>::value) {
    memcpy(_encoder->template GetPtr<Empty>(_offset), this, sizeof(Empty));
  } else {
    ::fidl::Encode(_encoder, &__reserved, _offset + 0);
  }
}

void Empty::Decode(::fidl::Decoder* _decoder, Empty* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<Empty>::value) {
    memcpy(_value, _decoder->template GetPtr<Empty>(_offset), sizeof(Empty));
  } else {
    ::fidl::Decode(_decoder, &_value->__reserved, _offset + 0);
  }
}

zx_status_t Empty::Clone(Empty* _result) const {
  zx_status_t _status = ::fidl::Clone(__reserved, &_result->__reserved);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_union_XUnionContainingEmptyStructTable;
const fidl_type_t* XUnionContainingEmptyStruct::FidlType = &test_union_XUnionContainingEmptyStructTable;

XUnionContainingEmptyStruct::XUnionContainingEmptyStruct() {}

XUnionContainingEmptyStruct::~XUnionContainingEmptyStruct() {
  Destroy();
}

XUnionContainingEmptyStruct::XUnionContainingEmptyStruct(XUnionContainingEmptyStruct&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
      new (&empty_)::test::union_::Empty();
      empty_ = std::move(other.empty_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

XUnionContainingEmptyStruct& XUnionContainingEmptyStruct::operator=(XUnionContainingEmptyStruct&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
        new (&empty_)::test::union_::Empty();
        empty_ = std::move(other.empty_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

XUnionContainingEmptyStruct XUnionContainingEmptyStruct::WithEmpty(::test::union_::Empty&& val) {
  XUnionContainingEmptyStruct result;
  result.set_empty(std::move(val));
  return result;
}

void XUnionContainingEmptyStruct::Encode(::fidl::Encoder* encoder, size_t offset,
                                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty: {
      if (::fidl::EncodingInlineSize<::test::union_::Empty>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &empty_, offset + offsetof(fidl_xunion_v2_t, envelope));

        fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &empty_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Empty, ::fidl::Encoder>(encoder)));

      fidl_xunion_v2_t* xunion = encoder->GetPtr<fidl_xunion_v2_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::union_::XUnionContainingEmptyStruct::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_xunion_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void XUnionContainingEmptyStruct::Decode(::fidl::Decoder* _decoder, XUnionContainingEmptyStruct* value, size_t offset) {
  fidl_xunion_v2_t* xunion = _decoder->GetPtr<fidl_xunion_v2_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty: {
      new (&value->empty_)::test::union_::Empty();
      ::fidl::Decode(_decoder, &value->empty_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t XUnionContainingEmptyStruct::Clone(XUnionContainingEmptyStruct* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::XUnionContainingEmptyStruct::Tag::Invalid:
      return ZX_OK;
    case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
      new (&result->empty_)::test::union_::Empty();
      return ::fidl::Clone(empty_, &result->empty_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

XUnionContainingEmptyStruct& XUnionContainingEmptyStruct::set_empty(::test::union_::Empty value) {
  EnsureStorageInitialized(::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty);
  empty_ = std::move(value);
  return *this;
}
XUnionContainingEmptyStruct& XUnionContainingEmptyStruct::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void XUnionContainingEmptyStruct::Destroy() {
  switch (tag_) {
    case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
      empty_.~decltype(empty_)();
      break;

    case static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid);
}

void XUnionContainingEmptyStruct::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::union_::XUnionContainingEmptyStruct::Tag::Invalid):
        break;
      case ::test::union_::XUnionContainingEmptyStruct::Tag::kEmpty:
        new (&empty_)::test::union_::Empty();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

//
// Proxies and stubs definitions
//
#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;

}  // namespace _internal
TestProtocol::~TestProtocol() = default;

const fidl_type_t* ::test::union_::TestProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* TestProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
      return &::test::union_::_internal::test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
      ;
    case ::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
      return &::test::union_::_internal::test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

TestProtocol_EventSender::~TestProtocol_EventSender() = default;

TestProtocol_Sync::~TestProtocol_Sync() = default;

TestProtocol_Proxy::TestProtocol_Proxy(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

TestProtocol_Proxy::~TestProtocol_Proxy() = default;

zx_status_t TestProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler(TestProtocol::StrictXUnionHenceResponseMayBeStackAllocatedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for TestProtocol::StrictXUnionHenceResponseMayBeStackAllocated\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::union_::StrictBoundedXUnion>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::union_::_internal::test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable);
}

}  // namespace
void TestProtocol_Proxy::StrictXUnionHenceResponseMayBeStackAllocated(StrictXUnionHenceResponseMayBeStackAllocatedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal, ::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::union_::TestProtocol_RequestEncoder::StrictXUnionHenceResponseMayBeStackAllocated(&_encoder), TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler(TestProtocol::FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for TestProtocol::FlexibleXUnionHenceResponseMustBeHeapAllocated\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::union_::OlderSimpleUnion>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::union_::_internal::test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable);
}

}  // namespace
void TestProtocol_Proxy::FlexibleXUnionHenceResponseMustBeHeapAllocated(FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal, ::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::union_::TestProtocol_RequestEncoder::FlexibleXUnionHenceResponseMustBeHeapAllocated(&_encoder), TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler(std::move(callback)));
}

TestProtocol_Stub::TestProtocol_Stub(::test::union_::TestProtocol_Stub::TestProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

TestProtocol_Stub::~TestProtocol_Stub() = default;

namespace {

class TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Responder final {
 public:
  TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::union_::StrictBoundedXUnion xu) {
    ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal, ::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_DynamicFlags);
    const fidl_type_t* resp_type = &::test::union_::_internal::test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
    response_.Send(resp_type, ::test::union_::TestProtocol_ResponseEncoder::StrictXUnionHenceResponseMayBeStackAllocated(&_encoder, &xu));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Responder final {
 public:
  TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::union_::OlderSimpleUnion xu) {
    ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal, ::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_DynamicFlags);
    const fidl_type_t* resp_type = &::test::union_::_internal::test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;
    response_.Send(resp_type, ::test::union_::TestProtocol_ResponseEncoder::FlexibleXUnionHenceResponseMustBeHeapAllocated(&_encoder, &xu));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

}  // namespace

zx_status_t TestProtocol_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type = ::test::union_::TestProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response);
  if (!message.has_only_header()) {
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
      return status;
    }
  }

  if (response.needs_response() != needs_response) {
    if (needs_response) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message needing a response with no txid");
    } else {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid");
    }
    return ZX_ERR_INVALID_ARGS;
  }

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal: {
      impl_->StrictXUnionHenceResponseMayBeStackAllocated(TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Responder(std::move(response)));
      break;
    }
    case ::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal: {
      impl_->FlexibleXUnionHenceResponseMustBeHeapAllocated(TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

TestProtocol_SyncProxy::TestProtocol_SyncProxy(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

TestProtocol_SyncProxy::~TestProtocol_SyncProxy() = default;

zx_status_t TestProtocol_SyncProxy::StrictXUnionHenceResponseMayBeStackAllocated(::test::union_::StrictBoundedXUnion* out_xu) {
  ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal, ::test::union_::internal::kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::union_::_internal::test_union_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::union_::TestProtocol_RequestEncoder::StrictXUnionHenceResponseMayBeStackAllocated(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_xu = ::fidl::DecodeAs<::test::union_::StrictBoundedXUnion>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t TestProtocol_SyncProxy::FlexibleXUnionHenceResponseMustBeHeapAllocated(::test::union_::OlderSimpleUnion* out_xu) {
  ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal, ::test::union_::internal::kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::union_::_internal::test_union_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::union_::TestProtocol_RequestEncoder::FlexibleXUnionHenceResponseMustBeHeapAllocated(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_xu = ::fidl::DecodeAs<::test::union_::OlderSimpleUnion>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

}  // namespace union_
}  // namespace test
