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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace unionsandwich {

extern "C" const fidl_type_t test_unionsandwich_UnionSize8Alignment4Table;
const fidl_type_t* UnionSize8Alignment4::FidlType = &test_unionsandwich_UnionSize8Alignment4Table;

UnionSize8Alignment4::UnionSize8Alignment4() {}

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

UnionSize8Alignment4::UnionSize8Alignment4(UnionSize8Alignment4&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant:
      variant_ = std::move(other.variant_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize8Alignment4::Tag::Invalid):
      break;
  }
}

UnionSize8Alignment4& UnionSize8Alignment4::operator=(UnionSize8Alignment4&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant:
        variant_ = std::move(other.variant_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize8Alignment4::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnionSize8Alignment4 UnionSize8Alignment4::WithVariant(uint32_t&& val) {
  UnionSize8Alignment4 result;
  result.set_variant(std::move(val));
  return result;
}

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

  switch (Which()) {
    case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &variant_, offset + offsetof(fidl_union_t, envelope));

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

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

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant: {
      ::fidl::Decode(_decoder, &value->variant_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t UnionSize8Alignment4::Clone(UnionSize8Alignment4* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unionsandwich::UnionSize8Alignment4::Tag::Invalid:
      return ZX_OK;
    case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant:
      return ::fidl::Clone(variant_, &result->variant_);
    default:
      return ZX_OK;
  }
}

UnionSize8Alignment4& UnionSize8Alignment4::set_variant(uint32_t value) {
  EnsureStorageInitialized(::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant);
  variant_ = std::move(value);
  return *this;
}

void UnionSize8Alignment4::Destroy() {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant:
      break;

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

void UnionSize8Alignment4::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize8Alignment4::Tag::Invalid):
        break;
      case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant:
        new (&variant_) uint32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_unionsandwich_SandwichUnionSize8Alignment4Table;
const fidl_type_t* SandwichUnionSize8Alignment4::FidlType = &test_unionsandwich_SandwichUnionSize8Alignment4Table;

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

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

zx_status_t SandwichUnionSize8Alignment4::Clone(SandwichUnionSize8Alignment4* _result) const {
  zx_status_t _status = ::fidl::Clone(before, &_result->before);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(union_, &_result->union_);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(after, &_result->after);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_unionsandwich_UnionSize12Alignment4Table;
const fidl_type_t* UnionSize12Alignment4::FidlType = &test_unionsandwich_UnionSize12Alignment4Table;

UnionSize12Alignment4::UnionSize12Alignment4() {}

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

UnionSize12Alignment4::UnionSize12Alignment4(UnionSize12Alignment4&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant:
      new (&variant_)::std::array<uint8_t, 6>();
      variant_ = std::move(other.variant_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize12Alignment4::Tag::Invalid):
      break;
  }
}

UnionSize12Alignment4& UnionSize12Alignment4::operator=(UnionSize12Alignment4&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant:
        new (&variant_)::std::array<uint8_t, 6>();
        variant_ = std::move(other.variant_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize12Alignment4::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnionSize12Alignment4 UnionSize12Alignment4::WithVariant(::std::array<uint8_t, 6>&& val) {
  UnionSize12Alignment4 result;
  result.set_variant(std::move(val));
  return result;
}

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

  switch (Which()) {
    case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant: {
      if (::fidl::EncodingInlineSize<::std::array<uint8_t, 6>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &variant_, offset + offsetof(fidl_union_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &variant_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::array<uint8_t, 6>, ::fidl::Encoder>(encoder)));

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant: {
      value->variant_.~decltype(value->variant_)();
      new (&value->variant_)::std::array<uint8_t, 6>();
      ::fidl::Decode(_decoder, &value->variant_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t UnionSize12Alignment4::Clone(UnionSize12Alignment4* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unionsandwich::UnionSize12Alignment4::Tag::Invalid:
      return ZX_OK;
    case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant:
      new (&result->variant_)::std::array<uint8_t, 6>();
      return ::fidl::Clone(variant_, &result->variant_);
    default:
      return ZX_OK;
  }
}

UnionSize12Alignment4& UnionSize12Alignment4::set_variant(::std::array<uint8_t, 6> value) {
  EnsureStorageInitialized(::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant);
  variant_ = std::move(value);
  return *this;
}

void UnionSize12Alignment4::Destroy() {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant:
      variant_.~decltype(variant_)();
      break;

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

void UnionSize12Alignment4::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize12Alignment4::Tag::Invalid):
        break;
      case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant:
        new (&variant_)::std::array<uint8_t, 6>();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_unionsandwich_SandwichUnionSize12Alignment4Table;
const fidl_type_t* SandwichUnionSize12Alignment4::FidlType = &test_unionsandwich_SandwichUnionSize12Alignment4Table;

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

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

zx_status_t SandwichUnionSize12Alignment4::Clone(SandwichUnionSize12Alignment4* _result) const {
  zx_status_t _status = ::fidl::Clone(before, &_result->before);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(union_, &_result->union_);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(after, &_result->after);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_unionsandwich_StructSize16Alignment8Table;
const fidl_type_t* StructSize16Alignment8::FidlType = &test_unionsandwich_StructSize16Alignment8Table;

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

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

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

extern "C" const fidl_type_t test_unionsandwich_UnionSize24Alignment8Table;
const fidl_type_t* UnionSize24Alignment8::FidlType = &test_unionsandwich_UnionSize24Alignment8Table;

UnionSize24Alignment8::UnionSize24Alignment8() {}

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

UnionSize24Alignment8::UnionSize24Alignment8(UnionSize24Alignment8&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant:
      new (&variant_)::test::unionsandwich::StructSize16Alignment8();
      variant_ = std::move(other.variant_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize24Alignment8::Tag::Invalid):
      break;
  }
}

UnionSize24Alignment8& UnionSize24Alignment8::operator=(UnionSize24Alignment8&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant:
        new (&variant_)::test::unionsandwich::StructSize16Alignment8();
        variant_ = std::move(other.variant_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize24Alignment8::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnionSize24Alignment8 UnionSize24Alignment8::WithVariant(::test::unionsandwich::StructSize16Alignment8&& val) {
  UnionSize24Alignment8 result;
  result.set_variant(std::move(val));
  return result;
}

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

  switch (Which()) {
    case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant: {
      if (::fidl::EncodingInlineSize<::test::unionsandwich::StructSize16Alignment8>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &variant_, offset + offsetof(fidl_union_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &variant_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::unionsandwich::StructSize16Alignment8, ::fidl::Encoder>(encoder)));

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant: {
      value->variant_.~decltype(value->variant_)();
      new (&value->variant_)::test::unionsandwich::StructSize16Alignment8();
      ::fidl::Decode(_decoder, &value->variant_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t UnionSize24Alignment8::Clone(UnionSize24Alignment8* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unionsandwich::UnionSize24Alignment8::Tag::Invalid:
      return ZX_OK;
    case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant:
      new (&result->variant_)::test::unionsandwich::StructSize16Alignment8();
      return ::fidl::Clone(variant_, &result->variant_);
    default:
      return ZX_OK;
  }
}

UnionSize24Alignment8& UnionSize24Alignment8::set_variant(::test::unionsandwich::StructSize16Alignment8 value) {
  EnsureStorageInitialized(::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant);
  variant_ = std::move(value);
  return *this;
}

void UnionSize24Alignment8::Destroy() {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant:
      variant_.~decltype(variant_)();
      break;

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

void UnionSize24Alignment8::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize24Alignment8::Tag::Invalid):
        break;
      case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant:
        new (&variant_)::test::unionsandwich::StructSize16Alignment8();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_unionsandwich_SandwichUnionSize24Alignment8Table;
const fidl_type_t* SandwichUnionSize24Alignment8::FidlType = &test_unionsandwich_SandwichUnionSize24Alignment8Table;

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

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

zx_status_t SandwichUnionSize24Alignment8::Clone(SandwichUnionSize24Alignment8* _result) const {
  zx_status_t _status = ::fidl::Clone(before, &_result->before);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(union_, &_result->union_);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(after, &_result->after);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

extern "C" const fidl_type_t test_unionsandwich_UnionSize36Alignment4Table;
const fidl_type_t* UnionSize36Alignment4::FidlType = &test_unionsandwich_UnionSize36Alignment4Table;

UnionSize36Alignment4::UnionSize36Alignment4() {}

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

UnionSize36Alignment4::UnionSize36Alignment4(UnionSize36Alignment4&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant:
      new (&variant_)::std::array<uint8_t, 32>();
      variant_ = std::move(other.variant_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize36Alignment4::Tag::Invalid):
      break;
  }
}

UnionSize36Alignment4& UnionSize36Alignment4::operator=(UnionSize36Alignment4&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant:
        new (&variant_)::std::array<uint8_t, 32>();
        variant_ = std::move(other.variant_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize36Alignment4::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnionSize36Alignment4 UnionSize36Alignment4::WithVariant(::std::array<uint8_t, 32>&& val) {
  UnionSize36Alignment4 result;
  result.set_variant(std::move(val));
  return result;
}

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

  switch (Which()) {
    case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant: {
      if (::fidl::EncodingInlineSize<::std::array<uint8_t, 32>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &variant_, offset + offsetof(fidl_union_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &variant_,
          encoder->Alloc(::fidl::EncodingInlineSize<::std::array<uint8_t, 32>, ::fidl::Encoder>(encoder)));

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant: {
      value->variant_.~decltype(value->variant_)();
      new (&value->variant_)::std::array<uint8_t, 32>();
      ::fidl::Decode(_decoder, &value->variant_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

zx_status_t UnionSize36Alignment4::Clone(UnionSize36Alignment4* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unionsandwich::UnionSize36Alignment4::Tag::Invalid:
      return ZX_OK;
    case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant:
      new (&result->variant_)::std::array<uint8_t, 32>();
      return ::fidl::Clone(variant_, &result->variant_);
    default:
      return ZX_OK;
  }
}

UnionSize36Alignment4& UnionSize36Alignment4::set_variant(::std::array<uint8_t, 32> value) {
  EnsureStorageInitialized(::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant);
  variant_ = std::move(value);
  return *this;
}

void UnionSize36Alignment4::Destroy() {
  switch (tag_) {
    case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant:
      variant_.~decltype(variant_)();
      break;

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

void UnionSize36Alignment4::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize36Alignment4::Tag::Invalid):
        break;
      case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant:
        new (&variant_)::std::array<uint8_t, 32>();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_unionsandwich_SandwichUnionSize36Alignment4Table;
const fidl_type_t* SandwichUnionSize36Alignment4::FidlType = &test_unionsandwich_SandwichUnionSize36Alignment4Table;

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

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

zx_status_t SandwichUnionSize36Alignment4::Clone(SandwichUnionSize36Alignment4* _result) const {
  zx_status_t _status = ::fidl::Clone(before, &_result->before);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(union_, &_result->union_);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(after, &_result->after);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

//
// Proxies and stubs definitions
//
}  // namespace unionsandwich
}  // namespace test
