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

#include <union.test.json.h>

#include "lib/fidl/cpp/internal/implementation.h"
namespace fidl {
namespace test {
namespace json {

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

Union::Union() {}

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

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

Union& Union::operator=(Union&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        VectorStringAlsoNeedsConstructor_ =
            std::move(other.VectorStringAlsoNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPrimitive: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &Primitive_, envelope_offset);
      break;
    }
    case Tag::kStringNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &StringNeedsConstructor_, envelope_offset);
      break;
    }
    case Tag::kVectorStringAlsoNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::vector<::std::string>,
                                     ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_,
                     envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPrimitive:
      ::fidl::Decode(decoder, &value->Primitive_, envelope_offset);
      break;
    case Tag::kStringNeedsConstructor:
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(decoder, &value->StringNeedsConstructor_, envelope_offset);
      break;
    case Tag::kVectorStringAlsoNeedsConstructor:
      new (&value->VectorStringAlsoNeedsConstructor_)::std::vector<
          ::std::string>();
      ::fidl::Decode(decoder, &value->VectorStringAlsoNeedsConstructor_,
                     envelope_offset);
      break;
  }
}

zx_status_t Union::Clone(Union* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case Tag::kStringNeedsConstructor:
      new (&result->StringNeedsConstructor_)::std::string();
      return ::fidl::Clone(StringNeedsConstructor_,
                           &result->StringNeedsConstructor_);
    case 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(Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      case Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_StructWithNullableXUnionTable;
const fidl_type_t* StructWithNullableXUnion::FidlType =
    &v1_fidl_test_json_StructWithNullableXUnionTable;

void StructWithNullableXUnion::Encode(::fidl::Encoder* _encoder,
                                      size_t _offset) {
  ::fidl::Encode(_encoder, &x1, _offset + 0);
}

void StructWithNullableXUnion::Decode(::fidl::Decoder* _decoder,
                                      StructWithNullableXUnion* value,
                                      size_t _offset) {
  ::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 v1_fidl_test_json_StrictUnionTable;
const fidl_type_t* StrictUnion::FidlType = &v1_fidl_test_json_StrictUnionTable;

StrictUnion::StrictUnion() {}

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

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

StrictUnion& StrictUnion::operator=(StrictUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        VectorStringAlsoNeedsConstructor_ =
            std::move(other.VectorStringAlsoNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPrimitive: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &Primitive_, envelope_offset);
      break;
    }
    case Tag::kStringNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &StringNeedsConstructor_, envelope_offset);
      break;
    }
    case Tag::kVectorStringAlsoNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::vector<::std::string>,
                                     ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_,
                     envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPrimitive:
      ::fidl::Decode(decoder, &value->Primitive_, envelope_offset);
      break;
    case Tag::kStringNeedsConstructor:
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(decoder, &value->StringNeedsConstructor_, envelope_offset);
      break;
    case Tag::kVectorStringAlsoNeedsConstructor:
      new (&value->VectorStringAlsoNeedsConstructor_)::std::vector<
          ::std::string>();
      ::fidl::Decode(decoder, &value->VectorStringAlsoNeedsConstructor_,
                     envelope_offset);
      break;
  }
}

zx_status_t StrictUnion::Clone(StrictUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case Tag::kStringNeedsConstructor:
      new (&result->StringNeedsConstructor_)::std::string();
      return ::fidl::Clone(StringNeedsConstructor_,
                           &result->StringNeedsConstructor_);
    case 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(Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      case Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_StrictSimpleXUnionTable;
const fidl_type_t* StrictSimpleXUnion::FidlType =
    &v1_fidl_test_json_StrictSimpleXUnionTable;

StrictSimpleXUnion::StrictSimpleXUnion() {}

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

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

StrictSimpleXUnion& StrictSimpleXUnion::operator=(StrictSimpleXUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kI:
        i_ = std::move(other.i_);
        break;
      case Tag::kF:
        f_ = std::move(other.f_);
        break;
      case Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    case Tag::kF: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<float, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &f_, envelope_offset);
      break;
    }
    case Tag::kS: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &s_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
    case Tag::kF:
      ::fidl::Decode(decoder, &value->f_, envelope_offset);
      break;
    case Tag::kS:
      new (&value->s_)::std::string();
      ::fidl::Decode(decoder, &value->s_, envelope_offset);
      break;
  }
}

zx_status_t StrictSimpleXUnion::Clone(StrictSimpleXUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case Tag::kI:
      return ::fidl::Clone(i_, &result->i_);
    case Tag::kF:
      return ::fidl::Clone(f_, &result->f_);
    case 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(Tag::kI);
  i_ = std::move(value);
  return *this;
}

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kI:
        new (&i_) int32_t();
        break;
      case Tag::kF:
        new (&f_) float();
        break;
      case Tag::kS:
        new (&s_)::std::string();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_StrictFooTable;
const fidl_type_t* StrictFoo::FidlType = &v1_fidl_test_json_StrictFooTable;

StrictFoo::StrictFoo() {}

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

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

StrictFoo& StrictFoo::operator=(StrictFoo&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kS: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &s_, envelope_offset);
      break;
    }
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kS:
      new (&value->s_)::std::string();
      ::fidl::Decode(decoder, &value->s_, envelope_offset);
      break;
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
  }
}

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

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kS:
        new (&s_)::std::string();
        break;
      case Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_StrictBoundedXUnionTable;
const fidl_type_t* StrictBoundedXUnion::FidlType =
    &v1_fidl_test_json_StrictBoundedXUnionTable;

StrictBoundedXUnion::StrictBoundedXUnion() {}

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

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

StrictBoundedXUnion& StrictBoundedXUnion::operator=(
    StrictBoundedXUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kV:
        new (&v_)::std::vector<uint8_t>();
        v_ = std::move(other.v_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kV: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::vector<uint8_t>, ::fidl::Encoder>(
              encoder));
      ::fidl::Encode(encoder, &v_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kV:
      new (&value->v_)::std::vector<uint8_t>();
      ::fidl::Decode(decoder, &value->v_, envelope_offset);
      break;
  }
}

zx_status_t StrictBoundedXUnion::Clone(StrictBoundedXUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case 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(Tag::kV);
  v_ = std::move(value);
  return *this;
}

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kV:
        new (&v_)::std::vector<uint8_t>();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_ReverseOrdinalUnionTable;
const fidl_type_t* ReverseOrdinalUnion::FidlType =
    &v1_fidl_test_json_ReverseOrdinalUnionTable;

ReverseOrdinalUnion::ReverseOrdinalUnion() {}

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

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

ReverseOrdinalUnion& ReverseOrdinalUnion::operator=(
    ReverseOrdinalUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kSecond:
        second_ = std::move(other.second_);
        break;
      case Tag::kFirst:
        first_ = std::move(other.first_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kSecond: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &second_, envelope_offset);
      break;
    }
    case Tag::kFirst: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &first_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kSecond:
      ::fidl::Decode(decoder, &value->second_, envelope_offset);
      break;
    case Tag::kFirst:
      ::fidl::Decode(decoder, &value->first_, envelope_offset);
      break;
  }
}

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

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kSecond:
        new (&second_) uint32_t();
        break;
      case Tag::kFirst:
        new (&first_) uint32_t();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_PizzaTable;
const fidl_type_t* Pizza::FidlType = &v1_fidl_test_json_PizzaTable;

void Pizza::Encode(::fidl::Encoder* _encoder, size_t _offset) {
  ::fidl::Encode(_encoder, &toppings, _offset + 0);
}

void Pizza::Decode(::fidl::Decoder* _decoder, Pizza* value, size_t _offset) {
  ::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 v1_fidl_test_json_PastaTable;
const fidl_type_t* Pasta::FidlType = &v1_fidl_test_json_PastaTable;

void Pasta::Encode(::fidl::Encoder* _encoder, size_t _offset) {
  ::fidl::Encode(_encoder, &sauce, _offset + 0);
}

void Pasta::Decode(::fidl::Decoder* _decoder, Pasta* value, size_t _offset) {
  ::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 v1_fidl_test_json_StrictPizzaOrPastaTable;
const fidl_type_t* StrictPizzaOrPasta::FidlType =
    &v1_fidl_test_json_StrictPizzaOrPastaTable;

StrictPizzaOrPasta::StrictPizzaOrPasta() {}

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

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

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

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

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

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPizza: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pizza, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pizza_, envelope_offset);
      break;
    }
    case Tag::kPasta: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pasta, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pasta_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPizza:
      new (&value->pizza_) class Pizza();
      ::fidl::Decode(decoder, &value->pizza_, envelope_offset);
      break;
    case Tag::kPasta:
      new (&value->pasta_) class Pasta();
      ::fidl::Decode(decoder, &value->pasta_, envelope_offset);
      break;
  }
}

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

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPizza:
        new (&pizza_) class Pizza();
        break;
      case Tag::kPasta:
        new (&pasta_) class Pasta();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_PizzaOrPastaTable;
const fidl_type_t* PizzaOrPasta::FidlType =
    &v1_fidl_test_json_PizzaOrPastaTable;

PizzaOrPasta::PizzaOrPasta() {}

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

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

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

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

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

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPizza: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pizza, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pizza_, envelope_offset);
      break;
    }
    case Tag::kPasta: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pasta, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pasta_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPizza:
      new (&value->pizza_) class Pizza();
      ::fidl::Decode(decoder, &value->pizza_, envelope_offset);
      break;
    case Tag::kPasta:
      new (&value->pasta_) class Pasta();
      ::fidl::Decode(decoder, &value->pasta_, envelope_offset);
      break;
  }
}

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

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPizza:
        new (&pizza_) class Pizza();
        break;
      case Tag::kPasta:
        new (&pasta_) class Pasta();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_FlexiblePizzaOrPastaTable;
const fidl_type_t* FlexiblePizzaOrPasta::FidlType =
    &v1_fidl_test_json_FlexiblePizzaOrPastaTable;

FlexiblePizzaOrPasta::FlexiblePizzaOrPasta() {}

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

FlexiblePizzaOrPasta::FlexiblePizzaOrPasta(FlexiblePizzaOrPasta&& other)
    : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kPizza:
      new (&pizza_) class Pizza();
      pizza_ = std::move(other.pizza_);
      break;
    case Tag::kPasta:
      new (&pasta_) class Pasta();
      pasta_ = std::move(other.pasta_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kPizza:
        new (&pizza_) class Pizza();
        pizza_ = std::move(other.pizza_);
        break;
      case Tag::kPasta:
        new (&pasta_) class Pasta();
        pasta_ = std::move(other.pasta_);
        break;
      case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

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

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

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPizza: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pizza, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pizza_, envelope_offset);
      break;
    }
    case Tag::kPasta: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pasta, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pasta_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPizza:
      new (&value->pizza_) class Pizza();
      ::fidl::Decode(decoder, &value->pizza_, envelope_offset);
      break;
    case Tag::kPasta:
      new (&value->pasta_) class Pasta();
      ::fidl::Decode(decoder, &value->pasta_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPizza:
        new (&pizza_) class Pizza();
        break;
      case Tag::kPasta:
        new (&pasta_) class Pasta();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_ExplicitPizzaOrPastaTable;
const fidl_type_t* ExplicitPizzaOrPasta::FidlType =
    &v1_fidl_test_json_ExplicitPizzaOrPastaTable;

ExplicitPizzaOrPasta::ExplicitPizzaOrPasta() {}

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

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

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

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

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

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPizza: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pizza, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pizza_, envelope_offset);
      break;
    }
    case Tag::kPasta: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Pasta, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &pasta_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPizza:
      new (&value->pizza_) class Pizza();
      ::fidl::Decode(decoder, &value->pizza_, envelope_offset);
      break;
    case Tag::kPasta:
      new (&value->pasta_) class Pasta();
      ::fidl::Decode(decoder, &value->pasta_, envelope_offset);
      break;
  }
}

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

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPizza:
        new (&pizza_) class Pizza();
        break;
      case Tag::kPasta:
        new (&pasta_) class Pasta();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_OlderSimpleUnionTable;
const fidl_type_t* OlderSimpleUnion::FidlType =
    &v1_fidl_test_json_OlderSimpleUnionTable;

OlderSimpleUnion::OlderSimpleUnion() {}

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

OlderSimpleUnion::OlderSimpleUnion(OlderSimpleUnion&& other)
    : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kI:
      i_ = std::move(other.i_);
      break;
    case Tag::kF:
      f_ = std::move(other.f_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kI:
        i_ = std::move(other.i_);
        break;
      case Tag::kF:
        f_ = std::move(other.f_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    case Tag::kF: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<float, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &f_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
    case Tag::kF:
      ::fidl::Decode(decoder, &value->f_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kI:
        new (&i_) int64_t();
        break;
      case Tag::kF:
        new (&f_) float();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
#ifdef __Fuchsia__
namespace {

extern "C" const fidl_type_t
    v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable;
extern "C" const fidl_type_t
    v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable;

extern "C" const fidl_type_t
    v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable;
extern "C" const fidl_type_t
    v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable;

}  // namespace

TestProtocol::~TestProtocol() = default;

const fidl_type_t* TestProtocol_RequestDecoder::GetType(
    uint64_t ordinal, bool* out_needs_response) {
  switch (ordinal) {
    case internal::
        kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
    case internal::
        kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_GenOrdinal:
      *out_needs_response = true;
      return &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable;
    case internal::
        kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
    case internal::
        kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_GenOrdinal:
      *out_needs_response = true;
      return &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable;
    default:
      *out_needs_response = false;
      return nullptr;
  }
}

const fidl_type_t* TestProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case internal::
        kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
    case internal::
        kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_GenOrdinal:
      return &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable;
    case internal::
        kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
    case internal::
        kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_GenOrdinal:
      return &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable;
    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::Message message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

namespace {

class TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler
    final : public ::fidl::internal::MessageHandler {
 public:
  TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler(
      TestProtocol::StrictXUnionHenceResponseMayBeStackAllocatedCallback
          callback)
      : callback_(std::move(callback)) {
    ZX_DEBUG_ASSERT_MSG(
        callback_,
        "Callback must not be empty for "
        "TestProtocol::StrictXUnionHenceResponseMayBeStackAllocated\n");
  }

  zx_status_t OnMessage(::fidl::Message message) override {
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(
        &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable,
        &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(
          message,
          &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable,
          error_msg);
      return status;
    }
    ::fidl::Decoder decoder(std::move(message));
    auto arg0 = ::fidl::DecodeAs<StrictBoundedXUnion>(&decoder, 16);
    callback_(std::move(arg0));
    return ZX_OK;
  }

 private:
  TestProtocol::StrictXUnionHenceResponseMayBeStackAllocatedCallback callback_;

  TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler(
      const TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler&) =
      delete;
  TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler&
  operator=(
      const TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler&) =
      delete;
};

}  // namespace
void TestProtocol_Proxy::StrictXUnionHenceResponseMayBeStackAllocated(
    StrictXUnionHenceResponseMayBeStackAllocatedCallback callback) {
  ::fidl::Encoder _encoder(
      internal::
          kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_GenOrdinal);
  controller_->Send(
      &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable,
      TestProtocol_RequestEncoder::StrictXUnionHenceResponseMayBeStackAllocated(
          &_encoder),
      std::make_unique<
          TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_ResponseHandler>(
          std::move(callback)));
}
namespace {

class
    TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler
        final : public ::fidl::internal::MessageHandler {
 public:
  TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler(
      TestProtocol::FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback
          callback)
      : callback_(std::move(callback)) {
    ZX_DEBUG_ASSERT_MSG(
        callback_,
        "Callback must not be empty for "
        "TestProtocol::FlexibleXUnionHenceResponseMustBeHeapAllocated\n");
  }

  zx_status_t OnMessage(::fidl::Message message) override {
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(
        &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable,
        &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(
          message,
          &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable,
          error_msg);
      return status;
    }
    ::fidl::Decoder decoder(std::move(message));
    auto arg0 = ::fidl::DecodeAs<OlderSimpleUnion>(&decoder, 16);
    callback_(std::move(arg0));
    return ZX_OK;
  }

 private:
  TestProtocol::FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback
      callback_;

  TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler(
      const TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler&) =
      delete;
  TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler&
  operator=(
      const TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler&) =
      delete;
};

}  // namespace
void TestProtocol_Proxy::FlexibleXUnionHenceResponseMustBeHeapAllocated(
    FlexibleXUnionHenceResponseMustBeHeapAllocatedCallback callback) {
  ::fidl::Encoder _encoder(
      internal::
          kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_GenOrdinal);
  controller_->Send(
      &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable,
      TestProtocol_RequestEncoder::
          FlexibleXUnionHenceResponseMustBeHeapAllocated(&_encoder),
      std::make_unique<
          TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_ResponseHandler>(
          std::move(callback)));
}

TestProtocol_Stub::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()(StrictBoundedXUnion xu) {
    ::fidl::Encoder _encoder(
        internal::
            kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_GenOrdinal);
    response_.Send(
        &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable,
        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()(OlderSimpleUnion xu) {
    ::fidl::Encoder _encoder(
        internal::
            kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_GenOrdinal);
    response_.Send(
        &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable,
        TestProtocol_ResponseEncoder::
            FlexibleXUnionHenceResponseMustBeHeapAllocated(&_encoder, &xu));
  }

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

}  // namespace

zx_status_t TestProtocol_Stub::Dispatch_(
    ::fidl::Message message, ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type =
      TestProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response);
  if (request_type == nullptr) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  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;
  }
  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;
  }
  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case internal::
        kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
    case internal::
        kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_GenOrdinal: {
      impl_->StrictXUnionHenceResponseMayBeStackAllocated(
          TestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Responder(
              std::move(response)));
      break;
    }
    case internal::
        kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
    case internal::
        kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_GenOrdinal: {
      impl_->FlexibleXUnionHenceResponseMustBeHeapAllocated(
          TestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Responder(
              std::move(response)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

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

TestProtocol_SyncProxy::~TestProtocol_SyncProxy() = default;

zx_status_t
TestProtocol_SyncProxy::StrictXUnionHenceResponseMayBeStackAllocated(
    StrictBoundedXUnion* out_xu) {
  ::fidl::Encoder _encoder(
      internal::
          kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_GenOrdinal);
  ::fidl::MessageBuffer buffer_;
  ::fidl::Message response_ = buffer_.CreateEmptyMessage();
  zx_status_t status_ = proxy_.Call(
      &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedRequestTable,
      &v1_fidl_test_json_TestProtocolStrictXUnionHenceResponseMayBeStackAllocatedResponseTable,
      TestProtocol_RequestEncoder::StrictXUnionHenceResponseMayBeStackAllocated(
          &_encoder),
      &response_);
  if (status_ != ZX_OK) return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_xu = ::fidl::DecodeAs<StrictBoundedXUnion>(&decoder_, 16);
  return ZX_OK;
}

zx_status_t
TestProtocol_SyncProxy::FlexibleXUnionHenceResponseMustBeHeapAllocated(
    OlderSimpleUnion* out_xu) {
  ::fidl::Encoder _encoder(
      internal::
          kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_GenOrdinal);
  ::fidl::MessageBuffer buffer_;
  ::fidl::Message response_ = buffer_.CreateEmptyMessage();
  zx_status_t status_ = proxy_.Call(
      &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedRequestTable,
      &v1_fidl_test_json_TestProtocolFlexibleXUnionHenceResponseMustBeHeapAllocatedResponseTable,
      TestProtocol_RequestEncoder::
          FlexibleXUnionHenceResponseMustBeHeapAllocated(&_encoder),
      &response_);
  if (status_ != ZX_OK) return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_xu = ::fidl::DecodeAs<OlderSimpleUnion>(&decoder_, 16);
  return ZX_OK;
}

#endif  // __Fuchsia__

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

void NullableUnionStruct::Encode(::fidl::Encoder* _encoder, size_t _offset) {
  ::fidl::Encode(_encoder, &the_union, _offset + 0);
}

void NullableUnionStruct::Decode(::fidl::Decoder* _decoder,
                                 NullableUnionStruct* value, size_t _offset) {
  ::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 v1_fidl_test_json_NewerSimpleUnionTable;
const fidl_type_t* NewerSimpleUnion::FidlType =
    &v1_fidl_test_json_NewerSimpleUnionTable;

NewerSimpleUnion::NewerSimpleUnion() {}

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

NewerSimpleUnion::NewerSimpleUnion(NewerSimpleUnion&& other)
    : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kI:
      i_ = std::move(other.i_);
      break;
    case Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case Tag::kV:
      new (&v_)::std::vector<::std::string>();
      v_ = std::move(other.v_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kI:
        i_ = std::move(other.i_);
        break;
      case Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case Tag::kV:
        new (&v_)::std::vector<::std::string>();
        v_ = std::move(other.v_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    case Tag::kS: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &s_, envelope_offset);
      break;
    }
    case Tag::kV: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::vector<::std::string>,
                                     ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &v_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
    case Tag::kS:
      new (&value->s_)::std::string();
      ::fidl::Decode(decoder, &value->s_, envelope_offset);
      break;
    case Tag::kV:
      new (&value->v_)::std::vector<::std::string>();
      ::fidl::Decode(decoder, &value->v_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

NewerSimpleUnion& NewerSimpleUnion::set_v(::std::vector<::std::string> value) {
  EnsureStorageInitialized(Tag::kV);
  v_ = std::move(value);
  return *this;
}

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kI:
        new (&i_) int64_t();
        break;
      case Tag::kS:
        new (&s_)::std::string();
        break;
      case Tag::kV:
        new (&v_)::std::vector<::std::string>();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_FlexibleUnionTable;
const fidl_type_t* FlexibleUnion::FidlType =
    &v1_fidl_test_json_FlexibleUnionTable;

FlexibleUnion::FlexibleUnion() {}

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

FlexibleUnion::FlexibleUnion(FlexibleUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kPrimitive:
      Primitive_ = std::move(other.Primitive_);
      break;
    case Tag::kStringNeedsConstructor:
      new (&StringNeedsConstructor_)::std::string();
      StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
      break;
    case Tag::kVectorStringAlsoNeedsConstructor:
      new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
      VectorStringAlsoNeedsConstructor_ =
          std::move(other.VectorStringAlsoNeedsConstructor_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        VectorStringAlsoNeedsConstructor_ =
            std::move(other.VectorStringAlsoNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPrimitive: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &Primitive_, envelope_offset);
      break;
    }
    case Tag::kStringNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &StringNeedsConstructor_, envelope_offset);
      break;
    }
    case Tag::kVectorStringAlsoNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::vector<::std::string>,
                                     ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_,
                     envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPrimitive:
      ::fidl::Decode(decoder, &value->Primitive_, envelope_offset);
      break;
    case Tag::kStringNeedsConstructor:
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(decoder, &value->StringNeedsConstructor_, envelope_offset);
      break;
    case Tag::kVectorStringAlsoNeedsConstructor:
      new (&value->VectorStringAlsoNeedsConstructor_)::std::vector<
          ::std::string>();
      ::fidl::Decode(decoder, &value->VectorStringAlsoNeedsConstructor_,
                     envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

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

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      case Tag::kVectorStringAlsoNeedsConstructor:
        new (&VectorStringAlsoNeedsConstructor_)::std::vector<::std::string>();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_FlexibleFooTable;
const fidl_type_t* FlexibleFoo::FidlType = &v1_fidl_test_json_FlexibleFooTable;

FlexibleFoo::FlexibleFoo() {}

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

FlexibleFoo::FlexibleFoo(FlexibleFoo&& other) : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case Tag::kI:
      i_ = std::move(other.i_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kS: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &s_, envelope_offset);
      break;
    }
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kS:
      new (&value->s_)::std::string();
      ::fidl::Decode(decoder, &value->s_, envelope_offset);
      break;
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kS:
        new (&s_)::std::string();
        break;
      case Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_FieldCollisionTable;
const fidl_type_t* FieldCollision::FidlType =
    &v1_fidl_test_json_FieldCollisionTable;

FieldCollision::FieldCollision() {}

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

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

FieldCollision& FieldCollision::operator=(FieldCollision&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kFieldCollisionTag:
        field_collision_tag_ = std::move(other.field_collision_tag_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kFieldCollisionTag: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &field_collision_tag_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kFieldCollisionTag:
      ::fidl::Decode(decoder, &value->field_collision_tag_, envelope_offset);
      break;
  }
}

zx_status_t FieldCollision::Clone(FieldCollision* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case 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(Tag::kFieldCollisionTag);
  field_collision_tag_ = std::move(value);
  return *this;
}

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kFieldCollisionTag:
        new (&field_collision_tag_) int32_t();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_ExplicitXUnionTable;
const fidl_type_t* ExplicitXUnion::FidlType =
    &v1_fidl_test_json_ExplicitXUnionTable;

ExplicitXUnion::ExplicitXUnion() {}

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

ExplicitXUnion::ExplicitXUnion(ExplicitXUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kI:
      i_ = std::move(other.i_);
      break;
    case Tag::kF:
      f_ = std::move(other.f_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kI:
        i_ = std::move(other.i_);
        break;
      case Tag::kF:
        f_ = std::move(other.f_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    case Tag::kF: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<float, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &f_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
    case Tag::kF:
      ::fidl::Decode(decoder, &value->f_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kI:
        new (&i_) int64_t();
        break;
      case Tag::kF:
        new (&f_) float();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_ExplicitUnionTable;
const fidl_type_t* ExplicitUnion::FidlType =
    &v1_fidl_test_json_ExplicitUnionTable;

ExplicitUnion::ExplicitUnion() {}

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

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

ExplicitUnion& ExplicitUnion::operator=(ExplicitUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kPrimitive:
        Primitive_ = std::move(other.Primitive_);
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        StringNeedsConstructor_ = std::move(other.StringNeedsConstructor_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kPrimitive: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &Primitive_, envelope_offset);
      break;
    }
    case Tag::kStringNeedsConstructor: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &StringNeedsConstructor_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kPrimitive:
      ::fidl::Decode(decoder, &value->Primitive_, envelope_offset);
      break;
    case Tag::kStringNeedsConstructor:
      new (&value->StringNeedsConstructor_)::std::string();
      ::fidl::Decode(decoder, &value->StringNeedsConstructor_, envelope_offset);
      break;
  }
}

zx_status_t ExplicitUnion::Clone(ExplicitUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case Tag::kPrimitive:
      return ::fidl::Clone(Primitive_, &result->Primitive_);
    case 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(Tag::kPrimitive);
  Primitive_ = std::move(value);
  return *this;
}

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kPrimitive:
        new (&Primitive_) int32_t();
        break;
      case Tag::kStringNeedsConstructor:
        new (&StringNeedsConstructor_)::std::string();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_ExplicitStrictFooTable;
const fidl_type_t* ExplicitStrictFoo::FidlType =
    &v1_fidl_test_json_ExplicitStrictFooTable;

ExplicitStrictFoo::ExplicitStrictFoo() {}

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

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

ExplicitStrictFoo& ExplicitStrictFoo::operator=(ExplicitStrictFoo&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kS: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &s_, envelope_offset);
      break;
    }
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kS:
      new (&value->s_)::std::string();
      ::fidl::Decode(decoder, &value->s_, envelope_offset);
      break;
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
  }
}

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

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

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

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

    default:
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kS:
        new (&s_)::std::string();
        break;
      case Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_ExplicitFooTable;
const fidl_type_t* ExplicitFoo::FidlType = &v1_fidl_test_json_ExplicitFooTable;

ExplicitFoo::ExplicitFoo() {}

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

ExplicitFoo::ExplicitFoo(ExplicitFoo&& other) : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kS:
      new (&s_)::std::string();
      s_ = std::move(other.s_);
      break;
    case Tag::kI:
      i_ = std::move(other.i_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kS:
        new (&s_)::std::string();
        s_ = std::move(other.s_);
        break;
      case Tag::kI:
        i_ = std::move(other.i_);
        break;
      case static_cast<fidl_xunion_tag_t>(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) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kS: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<::std::string, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &s_, envelope_offset);
      break;
    }
    case Tag::kI: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &i_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kS:
      new (&value->s_)::std::string();
      ::fidl::Decode(decoder, &value->s_, envelope_offset);
      break;
    case Tag::kI:
      ::fidl::Decode(decoder, &value->i_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

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

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

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kS:
        new (&s_)::std::string();
        break;
      case Tag::kI:
        new (&i_) int32_t();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
extern "C" const fidl_type_t v1_fidl_test_json_EmptyTable;
const fidl_type_t* Empty::FidlType = &v1_fidl_test_json_EmptyTable;

void Empty::Encode(::fidl::Encoder* _encoder, size_t _offset) {
  ::fidl::Encode(_encoder, &__reserved, _offset + 0);
}

void Empty::Decode(::fidl::Decoder* _decoder, Empty* value, size_t _offset) {
  ::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 v1_fidl_test_json_XUnionContainingEmptyStructTable;
const fidl_type_t* XUnionContainingEmptyStruct::FidlType =
    &v1_fidl_test_json_XUnionContainingEmptyStructTable;

XUnionContainingEmptyStruct::XUnionContainingEmptyStruct() {}

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

XUnionContainingEmptyStruct::XUnionContainingEmptyStruct(
    XUnionContainingEmptyStruct&& other)
    : tag_(other.tag_) {
  switch (tag_) {
    case Tag::kEmpty:
      new (&empty_) class Empty();
      empty_ = std::move(other.empty_);
      break;
    case static_cast<fidl_xunion_tag_t>(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 Tag::kEmpty:
        new (&empty_) class Empty();
        empty_ = std::move(other.empty_);
        break;
      case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

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

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

  size_t envelope_offset = 0;

  switch (tag_) {
    case Tag::kEmpty: {
      envelope_offset = encoder->Alloc(
          ::fidl::EncodingInlineSize<class Empty, ::fidl::Encoder>(encoder));
      ::fidl::Encode(encoder, &empty_, envelope_offset);
      break;
    }
    case Tag::kUnknown:
    default:
      break;
  }

  fidl_xunion_t* xunion = encoder->GetPtr<fidl_xunion_t>(offset);
  assert(xunion->envelope.presence == FIDL_ALLOC_ABSENT);

  if (envelope_offset) {
    xunion->tag = tag_;
    xunion->envelope.num_bytes = encoder->CurrentLength() - length_before;
    xunion->envelope.num_handles =
        encoder->CurrentHandleCount() - handles_before;
    xunion->envelope.presence = FIDL_ALLOC_PRESENT;
  }
}

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

  if (!xunion->envelope.data) {
    value->EnsureStorageInitialized(
        static_cast<fidl_xunion_tag_t>(Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  const size_t envelope_offset = decoder->GetOffset(xunion->envelope.data);

  switch (value->tag_) {
    case Tag::kEmpty:
      new (&value->empty_) class Empty();
      ::fidl::Decode(decoder, &value->empty_, envelope_offset);
      break;
    default:
      value->unknown_data_.resize(xunion->envelope.num_bytes);
      memcpy(value->unknown_data_.data(), xunion->envelope.data,
             xunion->envelope.num_bytes);
      break;
  }
}

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

XUnionContainingEmptyStruct& XUnionContainingEmptyStruct::set_empty(
    class Empty value) {
  EnsureStorageInitialized(Tag::kEmpty);
  empty_ = std::move(value);
  return *this;
}

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

    case static_cast<fidl_xunion_tag_t>(Tag::Invalid):
      break;
    default:
      unknown_data_.~vector();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(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>(Tag::Invalid):
        break;
      case Tag::kEmpty:
        new (&empty_) class Empty();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}
}  // namespace json
}  // namespace test
}  // namespace fidl
