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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace union_ {

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

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

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

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


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

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

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

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


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

PizzaOrPasta::PizzaOrPasta() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::PizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_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,
        &pizza_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::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;
    }
    case ::test::union_::PizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_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,
        &pasta_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::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 PizzaOrPasta::Decode(::fidl::Decoder* _decoder, PizzaOrPasta* 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::union_::PizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void PizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::PizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::PizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::PizzaOrPasta::Tag::Invalid);
}

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


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

ExplicitPizzaOrPasta::ExplicitPizzaOrPasta() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_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,
        &pizza_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::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;
    }
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_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,
        &pasta_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::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 ExplicitPizzaOrPasta::Decode(::fidl::Decoder* _decoder, ExplicitPizzaOrPasta* 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::union_::ExplicitPizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void ExplicitPizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::ExplicitPizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitPizzaOrPasta::Tag::Invalid);
}

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


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

FlexiblePizzaOrPasta::FlexiblePizzaOrPasta() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_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,
        &pizza_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::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;
    }
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_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,
        &pasta_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::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;
    }
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void FlexiblePizzaOrPasta::Decode(::fidl::Decoder* _decoder, FlexiblePizzaOrPasta* 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::union_::FlexiblePizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void FlexiblePizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::FlexiblePizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexiblePizzaOrPasta::Tag::Invalid);
}

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


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

StrictPizzaOrPasta::StrictPizzaOrPasta() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza: {
      if (::fidl::EncodingInlineSize<::test::union_::Pizza>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pizza_, offset + offsetof(fidl_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,
        &pizza_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pizza, ::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;
    }
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta: {
      if (::fidl::EncodingInlineSize<::test::union_::Pasta>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &pasta_, offset + offsetof(fidl_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,
        &pasta_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Pasta, ::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 StrictPizzaOrPasta::Decode(::fidl::Decoder* _decoder, StrictPizzaOrPasta* 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::union_::StrictPizzaOrPasta::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void StrictPizzaOrPasta::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictPizzaOrPasta::Tag::kPizza:
      pizza_.~decltype(pizza_)();
      break;
    case ::test::union_::StrictPizzaOrPasta::Tag::kPasta:
      pasta_.~decltype(pasta_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictPizzaOrPasta::Tag::Invalid);
}

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


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

Union::Union() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::Union::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_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,
        &Primitive_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::Union::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, 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,
        &StringNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_, offset + offsetof(fidl_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,
        &VectorStringAlsoNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::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 Union::Decode(::fidl::Decoder* _decoder, Union* 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::union_::Union::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

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

void Union::Destroy() {
  switch (tag_) {
    case ::test::union_::Union::Tag::kPrimitive:
      break;
    case ::test::union_::Union::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
    case ::test::union_::Union::Tag::kVectorStringAlsoNeedsConstructor:
      VectorStringAlsoNeedsConstructor_.~decltype(VectorStringAlsoNeedsConstructor_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::Union::Tag::Invalid);
}

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


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

FlexibleUnion::FlexibleUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::FlexibleUnion::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_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,
        &Primitive_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, 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,
        &StringNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_, offset + offsetof(fidl_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,
        &VectorStringAlsoNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::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;
    }
    case ::test::union_::FlexibleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void FlexibleUnion::Decode(::fidl::Decoder* _decoder, FlexibleUnion* 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::union_::FlexibleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

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

void FlexibleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::FlexibleUnion::Tag::kPrimitive:
      break;
    case ::test::union_::FlexibleUnion::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
    case ::test::union_::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor:
      VectorStringAlsoNeedsConstructor_.~decltype(VectorStringAlsoNeedsConstructor_)();
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleUnion::Tag::Invalid);
}

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


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

StrictUnion::StrictUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::StrictUnion::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_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,
        &Primitive_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, 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,
        &StringNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &VectorStringAlsoNeedsConstructor_, offset + offsetof(fidl_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,
        &VectorStringAlsoNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::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 StrictUnion::Decode(::fidl::Decoder* _decoder, StrictUnion* 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::union_::StrictUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

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

void StrictUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictUnion::Tag::kPrimitive:
      break;
    case ::test::union_::StrictUnion::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
    case ::test::union_::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor:
      VectorStringAlsoNeedsConstructor_.~decltype(VectorStringAlsoNeedsConstructor_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictUnion::Tag::Invalid);
}

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


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

FieldCollision::FieldCollision() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &field_collision_tag_, offset + offsetof(fidl_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,
        &field_collision_tag_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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 FieldCollision::Decode(::fidl::Decoder* _decoder, FieldCollision* 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::union_::FieldCollision::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

void FieldCollision::Destroy() {
  switch (tag_) {
    case ::test::union_::FieldCollision::Tag::kFieldCollisionTag:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FieldCollision::Tag::Invalid);
}

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


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

ExplicitUnion::ExplicitUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::ExplicitUnion::Tag::kPrimitive: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &Primitive_, offset + offsetof(fidl_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,
        &Primitive_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &StringNeedsConstructor_, 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,
        &StringNeedsConstructor_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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 ExplicitUnion::Decode(::fidl::Decoder* _decoder, ExplicitUnion* 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::union_::ExplicitUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void ExplicitUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitUnion::Tag::kPrimitive:
      break;
    case ::test::union_::ExplicitUnion::Tag::kStringNeedsConstructor:
      StringNeedsConstructor_.~decltype(StringNeedsConstructor_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitUnion::Tag::Invalid);
}

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


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

ReverseOrdinalUnion::ReverseOrdinalUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &first_, 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,
        &first_,
        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;
    }
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &second_, 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,
        &second_,
        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 ReverseOrdinalUnion::Decode(::fidl::Decoder* _decoder, ReverseOrdinalUnion* 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::union_::ReverseOrdinalUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void ReverseOrdinalUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::ReverseOrdinalUnion::Tag::kFirst:
      break;
    case ::test::union_::ReverseOrdinalUnion::Tag::kSecond:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ReverseOrdinalUnion::Tag::Invalid);
}

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


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

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

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

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


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

FlexibleFoo::FlexibleFoo() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::FlexibleFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_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,
        &s_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::FlexibleFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, 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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::FlexibleFoo::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void FlexibleFoo::Decode(::fidl::Decoder* _decoder, FlexibleFoo* 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::union_::FlexibleFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void FlexibleFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::FlexibleFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::FlexibleFoo::Tag::kI:
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::FlexibleFoo::Tag::Invalid);
}

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


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

StrictFoo::StrictFoo() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::StrictFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, offset + offsetof(fidl_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,
        &s_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::StrictFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, 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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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 StrictFoo::Decode(::fidl::Decoder* _decoder, StrictFoo* 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::union_::StrictFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void StrictFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::StrictFoo::Tag::kI:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictFoo::Tag::Invalid);
}

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


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

ExplicitFoo::ExplicitFoo() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::ExplicitFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, 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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::ExplicitFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, 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,
        &s_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::ExplicitFoo::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void ExplicitFoo::Decode(::fidl::Decoder* _decoder, ExplicitFoo* 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::union_::ExplicitFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

ExplicitFoo& ExplicitFoo::set_s(::std::string value) {
  EnsureStorageInitialized(::test::union_::ExplicitFoo::Tag::kS);
  s_ = std::move(value);
  return *this;
}
ExplicitFoo& ExplicitFoo::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void ExplicitFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitFoo::Tag::kI:
      break;
    case ::test::union_::ExplicitFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFoo::Tag::Invalid);
}

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


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

ExplicitStrictFoo::ExplicitStrictFoo() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::ExplicitStrictFoo::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, 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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::ExplicitStrictFoo::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, 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,
        &s_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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 ExplicitStrictFoo::Decode(::fidl::Decoder* _decoder, ExplicitStrictFoo* 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::union_::ExplicitStrictFoo::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void ExplicitStrictFoo::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitStrictFoo::Tag::kI:
      break;
    case ::test::union_::ExplicitStrictFoo::Tag::kS:
      s_.~decltype(s_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitStrictFoo::Tag::Invalid);
}

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


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

OlderSimpleUnion::OlderSimpleUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::OlderSimpleUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int64_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;
    }
    case ::test::union_::OlderSimpleUnion::Tag::kF: {
      if (::fidl::EncodingInlineSize<float>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &f_, 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,
        &f_,
        encoder->Alloc(::fidl::EncodingInlineSize<float, ::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;
    }
    case ::test::union_::OlderSimpleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void OlderSimpleUnion::Decode(::fidl::Decoder* _decoder, OlderSimpleUnion* 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::union_::OlderSimpleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void OlderSimpleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::OlderSimpleUnion::Tag::kI:
      break;
    case ::test::union_::OlderSimpleUnion::Tag::kF:
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::OlderSimpleUnion::Tag::Invalid);
}

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


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

NewerSimpleUnion::NewerSimpleUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::NewerSimpleUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, offset + offsetof(fidl_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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int64_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;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, 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,
        &s_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kV: {
      if (::fidl::EncodingInlineSize<::std::vector<::std::string>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &v_, offset + offsetof(fidl_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,
        &v_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<::std::string>, ::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;
    }
    case ::test::union_::NewerSimpleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void NewerSimpleUnion::Decode(::fidl::Decoder* _decoder, NewerSimpleUnion* 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::union_::NewerSimpleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

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

void NewerSimpleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::NewerSimpleUnion::Tag::kI:
      break;
    case ::test::union_::NewerSimpleUnion::Tag::kS:
      s_.~decltype(s_)();
      break;
    case ::test::union_::NewerSimpleUnion::Tag::kV:
      v_.~decltype(v_)();
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::NewerSimpleUnion::Tag::Invalid);
}

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


extern "C" const fidl_type_t test_union_StrictSimpleUnionTable;
const fidl_type_t* StrictSimpleUnion::FidlType = &test_union_StrictSimpleUnionTable;

StrictSimpleUnion::StrictSimpleUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::StrictSimpleUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, 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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int32_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;
    }
    case ::test::union_::StrictSimpleUnion::Tag::kF: {
      if (::fidl::EncodingInlineSize<float>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &f_, 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,
        &f_,
        encoder->Alloc(::fidl::EncodingInlineSize<float, ::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;
    }
    case ::test::union_::StrictSimpleUnion::Tag::kS: {
      if (::fidl::EncodingInlineSize<::std::string>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &s_, 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,
        &s_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::string, ::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 StrictSimpleUnion::Decode(::fidl::Decoder* _decoder, StrictSimpleUnion* 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::union_::StrictSimpleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

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

void StrictSimpleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictSimpleUnion::Tag::kI:
      break;
    case ::test::union_::StrictSimpleUnion::Tag::kF:
      break;
    case ::test::union_::StrictSimpleUnion::Tag::kS:
      s_.~decltype(s_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictSimpleUnion::Tag::Invalid);
}

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


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

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

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

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


extern "C" const fidl_type_t test_union_UnionContainingEmptyStructTable;
const fidl_type_t* UnionContainingEmptyStruct::FidlType = &test_union_UnionContainingEmptyStructTable;

UnionContainingEmptyStruct::UnionContainingEmptyStruct() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::UnionContainingEmptyStruct::Tag::kEmpty: {
      if (::fidl::EncodingInlineSize<::test::union_::Empty>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &empty_, 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,
        &empty_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::union_::Empty, ::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;
    }
    case ::test::union_::UnionContainingEmptyStruct::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void UnionContainingEmptyStruct::Decode(::fidl::Decoder* _decoder, UnionContainingEmptyStruct* 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::union_::UnionContainingEmptyStruct::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

void UnionContainingEmptyStruct::Destroy() {
  switch (tag_) {
    case ::test::union_::UnionContainingEmptyStruct::Tag::kEmpty:
      empty_.~decltype(empty_)();
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::UnionContainingEmptyStruct::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::UnionContainingEmptyStruct::Tag::Invalid);
}

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


extern "C" const fidl_type_t test_union_StrictBoundedUnionTable;
const fidl_type_t* StrictBoundedUnion::FidlType = &test_union_StrictBoundedUnionTable;

StrictBoundedUnion::StrictBoundedUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::StrictBoundedUnion::Tag::kV: {
      if (::fidl::EncodingInlineSize<::std::vector<uint8_t>>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &v_, 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,
        &v_,
        encoder->Alloc(::fidl::EncodingInlineSize<::std::vector<uint8_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 StrictBoundedUnion::Decode(::fidl::Decoder* _decoder, StrictBoundedUnion* 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::union_::StrictBoundedUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

void StrictBoundedUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::StrictBoundedUnion::Tag::kV:
      v_.~decltype(v_)();
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::StrictBoundedUnion::Tag::Invalid);
}

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


extern "C" const fidl_type_t test_union_TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponseTable;
const fidl_type_t* TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::FidlType = &test_union_TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponseTable;

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

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

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


extern "C" const fidl_type_t test_union_TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponseTable;
const fidl_type_t* TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::FidlType = &test_union_TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponseTable;

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

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

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


extern "C" const fidl_type_t test_union_StructWithNullableUnionTable;
const fidl_type_t* StructWithNullableUnion::FidlType = &test_union_StructWithNullableUnionTable;

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

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

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


extern "C" const fidl_type_t test_union_ExplicitFlexibleUnionTable;
const fidl_type_t* ExplicitFlexibleUnion::FidlType = &test_union_ExplicitFlexibleUnionTable;

ExplicitFlexibleUnion::ExplicitFlexibleUnion() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::ExplicitFlexibleUnion::Tag::kI: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &i_, 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,
        &i_,
        encoder->Alloc(::fidl::EncodingInlineSize<int64_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;
    }
    case ::test::union_::ExplicitFlexibleUnion::Tag::kF: {
      if (::fidl::EncodingInlineSize<float>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &f_, 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,
        &f_,
        encoder->Alloc(::fidl::EncodingInlineSize<float, ::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;
    }
    case ::test::union_::ExplicitFlexibleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void ExplicitFlexibleUnion::Decode(::fidl::Decoder* _decoder, ExplicitFlexibleUnion* 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::union_::ExplicitFlexibleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

void ExplicitFlexibleUnion::Destroy() {
  switch (tag_) {
    case ::test::union_::ExplicitFlexibleUnion::Tag::kI:
      break;
    case ::test::union_::ExplicitFlexibleUnion::Tag::kF:
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFlexibleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::ExplicitFlexibleUnion::Tag::Invalid);
}

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


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

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

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

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


extern "C" const fidl_type_t test_union_UnionWithAttributesTable;
const fidl_type_t* UnionWithAttributes::FidlType = &test_union_UnionWithAttributesTable;

UnionWithAttributes::UnionWithAttributes() {}

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

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

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

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


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

  switch (Which()) {
    case ::test::union_::UnionWithAttributes::Tag::kX: {
      if (::fidl::EncodingInlineSize<int64_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &x_, offset + offsetof(fidl_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,
        &x_,
        encoder->Alloc(::fidl::EncodingInlineSize<int64_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;
    }
    case ::test::union_::UnionWithAttributes::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void UnionWithAttributes::Decode(::fidl::Decoder* _decoder, UnionWithAttributes* 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::union_::UnionWithAttributes::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

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

}

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

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

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

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


extern "C" const fidl_type_t test_union_EmptyFlexibleUnionTable;
const fidl_type_t* EmptyFlexibleUnion::FidlType = &test_union_EmptyFlexibleUnionTable;

EmptyFlexibleUnion::EmptyFlexibleUnion() {}

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

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

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



void EmptyFlexibleUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {

  switch (Which()) {
    case ::test::union_::EmptyFlexibleUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void EmptyFlexibleUnion::Decode(::fidl::Decoder* _decoder, EmptyFlexibleUnion* 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::union_::EmptyFlexibleUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


}

zx_status_t EmptyFlexibleUnion::Clone(EmptyFlexibleUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::union_::EmptyFlexibleUnion::Tag::Invalid:
      return ZX_OK;
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}
EmptyFlexibleUnion& EmptyFlexibleUnion::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void EmptyFlexibleUnion::Destroy() {
  switch (tag_) {
  
    case static_cast<fidl_xunion_tag_t>(::test::union_::EmptyFlexibleUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::union_::EmptyFlexibleUnion::Tag::Invalid);
}

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

//
// Proxies and stubs definitions
//

#ifdef __Fuchsia__

  
  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_union_TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_union_TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponseTable;

}  // namespace _internal

TestProtocol::~TestProtocol() = default;

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

const fidl_type_t* TestProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::union_::internal::kTestProtocol_StrictUnionHenceResponseMayBeStackAllocated_Ordinal:
      return &::test::union_::_internal::test_union_TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponseTable;
        ;
    case ::test::union_::internal::kTestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_Ordinal:
      return &::test::union_::_internal::test_union_TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponseTable;
        ;
    default:
      return nullptr;
  }
}

TestProtocol_EventSender::~TestProtocol_EventSender() = default;

TestProtocol_Sync::~TestProtocol_Sync() = default;

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

TestProtocol_Proxy::~TestProtocol_Proxy() = default;

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


namespace {

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

}  // namespace
void TestProtocol_Proxy::StrictUnionHenceResponseMayBeStackAllocated(StrictUnionHenceResponseMayBeStackAllocatedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_StrictUnionHenceResponseMayBeStackAllocated_Ordinal, ::test::union_::internal::kTestProtocol_StrictUnionHenceResponseMayBeStackAllocated_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::union_::TestProtocol_RequestEncoder::StrictUnionHenceResponseMayBeStackAllocated(&_encoder), TestProtocol_StrictUnionHenceResponseMayBeStackAllocated_ResponseHandler(std::move(callback)));
}
namespace {

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

}  // namespace
void TestProtocol_Proxy::FlexibleUnionHenceResponseMustBeHeapAllocated(FlexibleUnionHenceResponseMustBeHeapAllocatedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_Ordinal, ::test::union_::internal::kTestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::union_::TestProtocol_RequestEncoder::FlexibleUnionHenceResponseMustBeHeapAllocated(&_encoder), TestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_ResponseHandler(std::move(callback)));
}

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

TestProtocol_Stub::~TestProtocol_Stub() = default;

namespace {

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

  void operator()(::test::union_::StrictBoundedUnion xu) {
    ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_StrictUnionHenceResponseMayBeStackAllocated_Ordinal, ::test::union_::internal::kTestProtocol_StrictUnionHenceResponseMayBeStackAllocated_DynamicFlags);
    const fidl_type_t* resp_type =&::test::union_::_internal::test_union_TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponseTable;
    response_.Send(resp_type, ::test::union_::TestProtocol_ResponseEncoder::StrictUnionHenceResponseMayBeStackAllocated(&_encoder, &xu));
  }

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

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

  void operator()(::test::union_::OlderSimpleUnion xu) {
    ::fidl::MessageEncoder _encoder(::test::union_::internal::kTestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_Ordinal, ::test::union_::internal::kTestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_DynamicFlags);
    const fidl_type_t* resp_type =&::test::union_::_internal::test_union_TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponseTable;
    response_.Send(resp_type, ::test::union_::TestProtocol_ResponseEncoder::FlexibleUnionHenceResponseMustBeHeapAllocated(&_encoder, &xu));
  }

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

}  // namespace

zx_status_t TestProtocol_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::union_::TestProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (!message.has_only_header()) {
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
      return status;
    }
  }

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::union_::internal::kTestProtocol_StrictUnionHenceResponseMayBeStackAllocated_Ordinal:
    {
      impl_->StrictUnionHenceResponseMayBeStackAllocated(TestProtocol_StrictUnionHenceResponseMayBeStackAllocated_Responder(std::move(response)));
      break;
    }
    case ::test::union_::internal::kTestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_Ordinal:
    {
      impl_->FlexibleUnionHenceResponseMustBeHeapAllocated(TestProtocol_FlexibleUnionHenceResponseMustBeHeapAllocated_Responder(std::move(response)));
      break;
    }
    default: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}

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

TestProtocol_SyncProxy::~TestProtocol_SyncProxy() = default;

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

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

#endif  // __Fuchsia__

}  // namespace union_
}  // namespace test

