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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace unknowninteractions {

extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable;
const fidl_type_t* UnknownInteractionsProtocolStrictTwoWayFieldsResponse::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable;
const fidl_type_t* UnknownInteractionsProtocolStrictTwoWayUnionResponse::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable;

UnknownInteractionsProtocolStrictTwoWayUnionResponse::UnknownInteractionsProtocolStrictTwoWayUnionResponse() {}

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

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

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

UnknownInteractionsProtocolStrictTwoWayUnionResponse UnknownInteractionsProtocolStrictTwoWayUnionResponse::WithSomeField(int32_t&& val) {
  UnknownInteractionsProtocolStrictTwoWayUnionResponse result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsProtocolStrictTwoWayUnionResponse::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::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsProtocolStrictTwoWayUnionResponse::Clone(UnknownInteractionsProtocolStrictTwoWayUnionResponse* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsProtocolStrictTwoWayUnionResponse& UnknownInteractionsProtocolStrictTwoWayUnionResponse::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsProtocolStrictTwoWayUnionResponse& UnknownInteractionsProtocolStrictTwoWayUnionResponse::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable;
const fidl_type_t* UnknownInteractionsProtocolStrictTwoWayTableResponse::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable;

UnknownInteractionsProtocolStrictTwoWayTableResponse::UnknownInteractionsProtocolStrictTwoWayTableResponse() {}

UnknownInteractionsProtocolStrictTwoWayTableResponse::UnknownInteractionsProtocolStrictTwoWayTableResponse(UnknownInteractionsProtocolStrictTwoWayTableResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsProtocolStrictTwoWayTableResponse::~UnknownInteractionsProtocolStrictTwoWayTableResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsProtocolStrictTwoWayTableResponse& UnknownInteractionsProtocolStrictTwoWayTableResponse::operator=(UnknownInteractionsProtocolStrictTwoWayTableResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsProtocolStrictTwoWayTableResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsProtocolStrictTwoWayTableResponse& UnknownInteractionsProtocolStrictTwoWayTableResponse::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsProtocolStrictTwoWayTableResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsProtocolStrictTwoWayTableResponse::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocolStrictTwoWayTableResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsProtocolStrictTwoWayTableResponse::Clone(UnknownInteractionsProtocolStrictTwoWayTableResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsProtocol_StrictTwoWayErr_Response::Clone(UnknownInteractionsProtocol_StrictTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable;

UnknownInteractionsProtocol_StrictTwoWayErr_Result::UnknownInteractionsProtocol_StrictTwoWayErr_Result() {}

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

UnknownInteractionsProtocol_StrictTwoWayErr_Result::UnknownInteractionsProtocol_StrictTwoWayErr_Result(UnknownInteractionsProtocol_StrictTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_StrictTwoWayErr_Result& UnknownInteractionsProtocol_StrictTwoWayErr_Result::operator=(UnknownInteractionsProtocol_StrictTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayErr_Result UnknownInteractionsProtocol_StrictTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response&& val) {
  UnknownInteractionsProtocol_StrictTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_StrictTwoWayErr_Result UnknownInteractionsProtocol_StrictTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_StrictTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_StrictTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsProtocol_StrictTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_StrictTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_StrictTwoWayErr_Result::Clone(UnknownInteractionsProtocol_StrictTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_StrictTwoWayErr_Result& UnknownInteractionsProtocol_StrictTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayErr_Result& UnknownInteractionsProtocol_StrictTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_StrictTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_StrictTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable;

UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result() {}

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

UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result(UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::operator=(UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Clone(UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResponseTable;

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Clone(UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable;

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result() {}

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

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result(UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::operator=(UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response&& val) {
  UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Clone(UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResponseTable;

UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response() {}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response(UnknownInteractionsProtocol_StrictTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::~UnknownInteractionsProtocol_StrictTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::operator=(UnknownInteractionsProtocol_StrictTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_StrictTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsProtocol_StrictTwoWayTableErr_Response::Clone(UnknownInteractionsProtocol_StrictTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable;

UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result() {}

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

UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result(UnknownInteractionsProtocol_StrictTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::operator=(UnknownInteractionsProtocol_StrictTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Result UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response&& val) {
  UnknownInteractionsProtocol_StrictTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_StrictTwoWayTableErr_Result UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_StrictTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_StrictTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Clone(UnknownInteractionsProtocol_StrictTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWay_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResponseTable;

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

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

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWay_Response::Clone(UnknownInteractionsProtocol_FlexibleTwoWay_Response* _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_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWay_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWay_Result::UnknownInteractionsProtocol_FlexibleTwoWay_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWay_Result::UnknownInteractionsProtocol_FlexibleTwoWay_Result(UnknownInteractionsProtocol_FlexibleTwoWay_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWay_Result& UnknownInteractionsProtocol_FlexibleTwoWay_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWay_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWay_Result UnknownInteractionsProtocol_FlexibleTwoWay_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWay_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWay_Result UnknownInteractionsProtocol_FlexibleTwoWay_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWay_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWay_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWay_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWay_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWay_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWay_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWay_Result& UnknownInteractionsProtocol_FlexibleTwoWay_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWay_Result& UnknownInteractionsProtocol_FlexibleTwoWay_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWay_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWay_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayFields_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result(UnknownInteractionsProtocol_FlexibleTwoWayFields_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayFields_Result& UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayFields_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayFields_Result UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayFields_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayFields_Result UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayFields_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayFields_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayFields_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayFields_Result& UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayFields_Result& UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResponseTable;

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response() {}

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

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

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

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Clone(UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response& UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response& UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result(UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResponseTable;

UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response() {}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response(UnknownInteractionsProtocol_FlexibleTwoWayTable_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::~UnknownInteractionsProtocol_FlexibleTwoWayTable_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Response& UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::operator=(UnknownInteractionsProtocol_FlexibleTwoWayTable_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsProtocol_FlexibleTwoWayTable_Response& UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayTable_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayTable_Response::Clone(UnknownInteractionsProtocol_FlexibleTwoWayTable_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result(UnknownInteractionsProtocol_FlexibleTwoWayTable_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Result& UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayTable_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Result UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayTable_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayTable_Result UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayTable_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayTable_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayTable_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Result& UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayTable_Result& UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayErr_Response::Clone(UnknownInteractionsProtocol_FlexibleTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result(UnknownInteractionsProtocol_FlexibleTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayErr_Result UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayErr_Result UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result(UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResponseTable;

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Clone(UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response& UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response& UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result(UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResponseTable;

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response() {}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::~UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response& UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::operator=(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response& UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response::Clone(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable;

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result() {}

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

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::operator=(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Clone(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable;
const fidl_type_t* UnknownInteractionsProtocolStrictEventFieldsRequest::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable;
const fidl_type_t* UnknownInteractionsProtocolStrictEventUnionRequest::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable;

UnknownInteractionsProtocolStrictEventUnionRequest::UnknownInteractionsProtocolStrictEventUnionRequest() {}

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

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

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

UnknownInteractionsProtocolStrictEventUnionRequest UnknownInteractionsProtocolStrictEventUnionRequest::WithSomeField(int32_t&& val) {
  UnknownInteractionsProtocolStrictEventUnionRequest result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsProtocolStrictEventUnionRequest::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::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsProtocolStrictEventUnionRequest::Clone(UnknownInteractionsProtocolStrictEventUnionRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsProtocolStrictEventUnionRequest& UnknownInteractionsProtocolStrictEventUnionRequest::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsProtocolStrictEventUnionRequest& UnknownInteractionsProtocolStrictEventUnionRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable;
const fidl_type_t* UnknownInteractionsProtocolStrictEventTableRequest::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable;

UnknownInteractionsProtocolStrictEventTableRequest::UnknownInteractionsProtocolStrictEventTableRequest() {}

UnknownInteractionsProtocolStrictEventTableRequest::UnknownInteractionsProtocolStrictEventTableRequest(UnknownInteractionsProtocolStrictEventTableRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsProtocolStrictEventTableRequest::~UnknownInteractionsProtocolStrictEventTableRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsProtocolStrictEventTableRequest& UnknownInteractionsProtocolStrictEventTableRequest::operator=(UnknownInteractionsProtocolStrictEventTableRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsProtocolStrictEventTableRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsProtocolStrictEventTableRequest& UnknownInteractionsProtocolStrictEventTableRequest::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsProtocolStrictEventTableRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsProtocolStrictEventTableRequest::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocolStrictEventTableRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsProtocolStrictEventTableRequest::Clone(UnknownInteractionsProtocolStrictEventTableRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable;
const fidl_type_t* UnknownInteractionsProtocolFlexibleEventFieldsRequest::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable;
const fidl_type_t* UnknownInteractionsProtocolFlexibleEventUnionRequest::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable;

UnknownInteractionsProtocolFlexibleEventUnionRequest::UnknownInteractionsProtocolFlexibleEventUnionRequest() {}

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

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

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

UnknownInteractionsProtocolFlexibleEventUnionRequest UnknownInteractionsProtocolFlexibleEventUnionRequest::WithSomeField(int32_t&& val) {
  UnknownInteractionsProtocolFlexibleEventUnionRequest result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsProtocolFlexibleEventUnionRequest::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::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsProtocolFlexibleEventUnionRequest::Clone(UnknownInteractionsProtocolFlexibleEventUnionRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsProtocolFlexibleEventUnionRequest& UnknownInteractionsProtocolFlexibleEventUnionRequest::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsProtocolFlexibleEventUnionRequest& UnknownInteractionsProtocolFlexibleEventUnionRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable;
const fidl_type_t* UnknownInteractionsProtocolFlexibleEventTableRequest::FidlType = &test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable;

UnknownInteractionsProtocolFlexibleEventTableRequest::UnknownInteractionsProtocolFlexibleEventTableRequest() {}

UnknownInteractionsProtocolFlexibleEventTableRequest::UnknownInteractionsProtocolFlexibleEventTableRequest(UnknownInteractionsProtocolFlexibleEventTableRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsProtocolFlexibleEventTableRequest::~UnknownInteractionsProtocolFlexibleEventTableRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsProtocolFlexibleEventTableRequest& UnknownInteractionsProtocolFlexibleEventTableRequest::operator=(UnknownInteractionsProtocolFlexibleEventTableRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsProtocolFlexibleEventTableRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsProtocolFlexibleEventTableRequest& UnknownInteractionsProtocolFlexibleEventTableRequest::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsProtocolFlexibleEventTableRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsProtocolFlexibleEventTableRequest::Decode(::fidl::Decoder* _decoder, UnknownInteractionsProtocolFlexibleEventTableRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsProtocolFlexibleEventTableRequest::Clone(UnknownInteractionsProtocolFlexibleEventTableRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponse::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable;

UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse() {}

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

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

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

UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::WithSomeField(int32_t&& val) {
  UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::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::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Clone(UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse& UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse& UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable;

UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::UnknownInteractionsAjarProtocolStrictTwoWayTableResponse() {}

UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::UnknownInteractionsAjarProtocolStrictTwoWayTableResponse(UnknownInteractionsAjarProtocolStrictTwoWayTableResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::~UnknownInteractionsAjarProtocolStrictTwoWayTableResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsAjarProtocolStrictTwoWayTableResponse& UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::operator=(UnknownInteractionsAjarProtocolStrictTwoWayTableResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsAjarProtocolStrictTwoWayTableResponse& UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocolStrictTwoWayTableResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsAjarProtocolStrictTwoWayTableResponse::Clone(UnknownInteractionsAjarProtocolStrictTwoWayTableResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable;

UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result() {}

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

UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result(UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::operator=(UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable;

UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result() {}

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

UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result(UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::operator=(UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResponseTable;

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable;

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result() {}

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

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result(UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::operator=(UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResponseTable;

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response() {}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::~UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::operator=(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable;

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result() {}

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

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::operator=(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Clone(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable;
const fidl_type_t* UnknownInteractionsAjarProtocolStrictEventFieldsRequest::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable;
const fidl_type_t* UnknownInteractionsAjarProtocolStrictEventUnionRequest::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable;

UnknownInteractionsAjarProtocolStrictEventUnionRequest::UnknownInteractionsAjarProtocolStrictEventUnionRequest() {}

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

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

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

UnknownInteractionsAjarProtocolStrictEventUnionRequest UnknownInteractionsAjarProtocolStrictEventUnionRequest::WithSomeField(int32_t&& val) {
  UnknownInteractionsAjarProtocolStrictEventUnionRequest result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocolStrictEventUnionRequest::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::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsAjarProtocolStrictEventUnionRequest::Clone(UnknownInteractionsAjarProtocolStrictEventUnionRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsAjarProtocolStrictEventUnionRequest& UnknownInteractionsAjarProtocolStrictEventUnionRequest::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsAjarProtocolStrictEventUnionRequest& UnknownInteractionsAjarProtocolStrictEventUnionRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable;
const fidl_type_t* UnknownInteractionsAjarProtocolStrictEventTableRequest::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable;

UnknownInteractionsAjarProtocolStrictEventTableRequest::UnknownInteractionsAjarProtocolStrictEventTableRequest() {}

UnknownInteractionsAjarProtocolStrictEventTableRequest::UnknownInteractionsAjarProtocolStrictEventTableRequest(UnknownInteractionsAjarProtocolStrictEventTableRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsAjarProtocolStrictEventTableRequest::~UnknownInteractionsAjarProtocolStrictEventTableRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsAjarProtocolStrictEventTableRequest& UnknownInteractionsAjarProtocolStrictEventTableRequest::operator=(UnknownInteractionsAjarProtocolStrictEventTableRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsAjarProtocolStrictEventTableRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsAjarProtocolStrictEventTableRequest& UnknownInteractionsAjarProtocolStrictEventTableRequest::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsAjarProtocolStrictEventTableRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsAjarProtocolStrictEventTableRequest::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocolStrictEventTableRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsAjarProtocolStrictEventTableRequest::Clone(UnknownInteractionsAjarProtocolStrictEventTableRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable;
const fidl_type_t* UnknownInteractionsAjarProtocolFlexibleEventFieldsRequest::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable;
const fidl_type_t* UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable;

UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest() {}

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

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

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

UnknownInteractionsAjarProtocolFlexibleEventUnionRequest UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::WithSomeField(int32_t&& val) {
  UnknownInteractionsAjarProtocolFlexibleEventUnionRequest result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::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::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Clone(UnknownInteractionsAjarProtocolFlexibleEventUnionRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsAjarProtocolFlexibleEventUnionRequest& UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsAjarProtocolFlexibleEventUnionRequest& UnknownInteractionsAjarProtocolFlexibleEventUnionRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable;
const fidl_type_t* UnknownInteractionsAjarProtocolFlexibleEventTableRequest::FidlType = &test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable;

UnknownInteractionsAjarProtocolFlexibleEventTableRequest::UnknownInteractionsAjarProtocolFlexibleEventTableRequest() {}

UnknownInteractionsAjarProtocolFlexibleEventTableRequest::UnknownInteractionsAjarProtocolFlexibleEventTableRequest(UnknownInteractionsAjarProtocolFlexibleEventTableRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsAjarProtocolFlexibleEventTableRequest::~UnknownInteractionsAjarProtocolFlexibleEventTableRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsAjarProtocolFlexibleEventTableRequest& UnknownInteractionsAjarProtocolFlexibleEventTableRequest::operator=(UnknownInteractionsAjarProtocolFlexibleEventTableRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsAjarProtocolFlexibleEventTableRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsAjarProtocolFlexibleEventTableRequest& UnknownInteractionsAjarProtocolFlexibleEventTableRequest::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsAjarProtocolFlexibleEventTableRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsAjarProtocolFlexibleEventTableRequest::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarProtocolFlexibleEventTableRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsAjarProtocolFlexibleEventTableRequest::Clone(UnknownInteractionsAjarProtocolFlexibleEventTableRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponse::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable;

UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse() {}

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

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

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

UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::WithSomeField(int32_t&& val) {
  UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::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::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Clone(UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse& UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse& UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable;

UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::UnknownInteractionsClosedProtocolStrictTwoWayTableResponse() {}

UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::UnknownInteractionsClosedProtocolStrictTwoWayTableResponse(UnknownInteractionsClosedProtocolStrictTwoWayTableResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::~UnknownInteractionsClosedProtocolStrictTwoWayTableResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsClosedProtocolStrictTwoWayTableResponse& UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::operator=(UnknownInteractionsClosedProtocolStrictTwoWayTableResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsClosedProtocolStrictTwoWayTableResponse& UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocolStrictTwoWayTableResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsClosedProtocolStrictTwoWayTableResponse::Clone(UnknownInteractionsClosedProtocolStrictTwoWayTableResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable;

UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result() {}

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

UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result(UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::operator=(UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable;

UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result() {}

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

UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result(UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::operator=(UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResponseTable;

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable;

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result() {}

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

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result(UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::operator=(UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResponseTable;

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response() {}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::~UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::operator=(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable;

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result() {}

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

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::operator=(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Clone(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable;
const fidl_type_t* UnknownInteractionsClosedProtocolStrictEventFieldsRequest::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable;
const fidl_type_t* UnknownInteractionsClosedProtocolStrictEventUnionRequest::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable;

UnknownInteractionsClosedProtocolStrictEventUnionRequest::UnknownInteractionsClosedProtocolStrictEventUnionRequest() {}

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

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

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

UnknownInteractionsClosedProtocolStrictEventUnionRequest UnknownInteractionsClosedProtocolStrictEventUnionRequest::WithSomeField(int32_t&& val) {
  UnknownInteractionsClosedProtocolStrictEventUnionRequest result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsClosedProtocolStrictEventUnionRequest::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::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsClosedProtocolStrictEventUnionRequest::Clone(UnknownInteractionsClosedProtocolStrictEventUnionRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsClosedProtocolStrictEventUnionRequest& UnknownInteractionsClosedProtocolStrictEventUnionRequest::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsClosedProtocolStrictEventUnionRequest& UnknownInteractionsClosedProtocolStrictEventUnionRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable;
const fidl_type_t* UnknownInteractionsClosedProtocolStrictEventTableRequest::FidlType = &test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable;

UnknownInteractionsClosedProtocolStrictEventTableRequest::UnknownInteractionsClosedProtocolStrictEventTableRequest() {}

UnknownInteractionsClosedProtocolStrictEventTableRequest::UnknownInteractionsClosedProtocolStrictEventTableRequest(UnknownInteractionsClosedProtocolStrictEventTableRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsClosedProtocolStrictEventTableRequest::~UnknownInteractionsClosedProtocolStrictEventTableRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsClosedProtocolStrictEventTableRequest& UnknownInteractionsClosedProtocolStrictEventTableRequest::operator=(UnknownInteractionsClosedProtocolStrictEventTableRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsClosedProtocolStrictEventTableRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsClosedProtocolStrictEventTableRequest& UnknownInteractionsClosedProtocolStrictEventTableRequest::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsClosedProtocolStrictEventTableRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsClosedProtocolStrictEventTableRequest::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedProtocolStrictEventTableRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsClosedProtocolStrictEventTableRequest::Clone(UnknownInteractionsClosedProtocolStrictEventTableRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocolStrictTwoWayFieldsResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocolStrictTwoWayFieldsResponse::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocolStrictTwoWayFieldsResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocolStrictTwoWayUnionResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocolStrictTwoWayUnionResponseTable;

UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse() {}

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

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

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

UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::WithSomeField(int32_t&& val) {
  UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::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::unknowninteractions::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Clone(UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse& UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse& UnknownInteractionsDriverProtocolStrictTwoWayUnionResponse::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocolStrictTwoWayTableResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocolStrictTwoWayTableResponseTable;

UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::UnknownInteractionsDriverProtocolStrictTwoWayTableResponse() {}

UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::UnknownInteractionsDriverProtocolStrictTwoWayTableResponse(UnknownInteractionsDriverProtocolStrictTwoWayTableResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::~UnknownInteractionsDriverProtocolStrictTwoWayTableResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsDriverProtocolStrictTwoWayTableResponse& UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::operator=(UnknownInteractionsDriverProtocolStrictTwoWayTableResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsDriverProtocolStrictTwoWayTableResponse& UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocolStrictTwoWayTableResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsDriverProtocolStrictTwoWayTableResponse::Clone(UnknownInteractionsDriverProtocolStrictTwoWayTableResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayErr_ResultTable;

UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result() {}

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

UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result(UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::operator=(UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_ResultTable;

UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result() {}

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

UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result(UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::operator=(UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_ResponseTable;

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_ResultTable;

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result() {}

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

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result(UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::operator=(UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_ResponseTable;

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response() {}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response(UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::~UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::operator=(UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_ResultTable;

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result() {}

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

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result(UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::operator=(UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Clone(UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWay_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWay_ResponseTable;

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

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

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response* _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_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWay_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWay_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWay_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFields_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_ResponseTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response() {}

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

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

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnion_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_ResponseTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response() {}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response(UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::~UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTable_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayFieldsErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_ResponseTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayUnionErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_ResponseTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response() {}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response(UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::~UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response& UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_ResultTable;

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result() {}

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

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result(UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
      framework_err_ = std::move(other.framework_err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::operator=(UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
        framework_err_ = std::move(other.framework_err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}
UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::WithFrameworkErr(::fidl::FrameworkErr&& val) {
  UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result result;
  result.set_framework_err(std::move(val));
  return result;
}


void UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr: {
      if (::fidl::EncodingInlineSize<::fidl::FrameworkErr>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &framework_err_, 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,
        &framework_err_,
        encoder->Alloc(::fidl::EncodingInlineSize<::fidl::FrameworkErr, ::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 UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr: {
      ::fidl::Decode(_decoder, &value->framework_err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Clone(UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
      return ::fidl::Clone(framework_err_, &result->framework_err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result& UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::set_framework_err(::fidl::FrameworkErr value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr);
  framework_err_ = std::move(value);
  return *this;
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
      break;
    case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      case ::test::unknowninteractions::UnknownInteractionsDriverProtocol_FlexibleTwoWayTableErr_Result::Tag::kFrameworkErr:
        new (&framework_err_) ::fidl::FrameworkErr();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocolStrictTwoWayFieldsResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocolStrictTwoWayFieldsResponse::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocolStrictTwoWayFieldsResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponseTable;

UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse() {}

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

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

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

UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::WithSomeField(int32_t&& val) {
  UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::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::unknowninteractions::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Clone(UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse& UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse& UnknownInteractionsAjarDriverProtocolStrictTwoWayUnionResponse::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponseTable;

UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse() {}

UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse(UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::~UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse& UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::operator=(UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse& UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse::Clone(UnknownInteractionsAjarDriverProtocolStrictTwoWayTableResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_ResultTable;

UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result() {}

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

UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result(UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::operator=(UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_ResultTable;

UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result() {}

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

UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result(UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::operator=(UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_ResponseTable;

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_ResultTable;

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result() {}

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

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result(UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::operator=(UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_ResponseTable;

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response() {}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response(UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::~UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::operator=(UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_ResultTable;

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result() {}

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

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result(UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::operator=(UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Clone(UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsAjarDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocolStrictTwoWayFieldsResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocolStrictTwoWayFieldsResponse::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocolStrictTwoWayFieldsResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponseTable;

UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse() {}

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

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

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

UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::WithSomeField(int32_t&& val) {
  UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::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::unknowninteractions::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Clone(UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse& UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse& UnknownInteractionsClosedDriverProtocolStrictTwoWayUnionResponse::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponseTable;

UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse() {}

UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse(UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::~UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse& UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::operator=(UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse& UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse::Clone(UnknownInteractionsClosedDriverProtocolStrictTwoWayTableResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_ResponseTable;

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

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

zx_status_t UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response* _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_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_ResultTable;

UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result() {}

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

UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result(UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::operator=(UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result* 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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_ResponseTable;

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

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_ResultTable;

UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result() {}

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

UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result(UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::operator=(UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result* 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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayFieldsErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_ResponseTable;

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response() {}

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

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

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

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::WithSomeField(int32_t&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response result;
  result.set_some_field(std::move(val));
  return result;
}


void UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &some_field_, 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,
        &some_field_,
        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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

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

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField: {
      ::fidl::Decode(_decoder, &value->some_field_, 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 UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField:
      return ::fidl::Clone(some_field_, &result->some_field_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::set_some_field(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::Tag::kSomeField);
  some_field_ = std::move(value);
  return *this;
}
UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response& UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

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

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


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_ResultTable;

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result() {}

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

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result(UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::operator=(UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result* 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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayUnionErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_ResponseTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_ResponseTable;

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response() {}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response(UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::~UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&some_field_value_.value);
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::operator=(UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      some_field_value_.value = std::move(other.some_field_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&some_field_value_.value, std::move(other.some_field_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&some_field_value_.value);
  }
  return *this;
}

bool UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::IsEmpty() const {
  return field_presence_.IsEmpty();
}
UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response& UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::set_some_field(int32_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&some_field_value_.value, std::move(_value));
  } else {
    some_field_value_.value = std::move(_value);
  }
  return *this;
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<int32_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &some_field_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &some_field_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<int32_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_some_field(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_some_field();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_some_field();
  return;
}

zx_status_t UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(some_field_value_.value, result->mutable_some_field());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_some_field();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_ResultTable;
const fidl_type_t* UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::FidlType = &test_unknowninteractions_UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_ResultTable;

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result() {}

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

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result(UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
      break;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::operator=(UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::WithResponse(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result result;
  result.set_response(std::move(val));
  return result;
}
UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::WithErr(int32_t&& val) {
  UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result result;
  result.set_err(std::move(val));
  return result;
}


void UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, 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,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response, ::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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<int32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, 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,
        &err_,
        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 UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Decode(::fidl::Decoder* _decoder, UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result* 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::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


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

  switch (value->tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Clone(UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      new (&result->response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::set_response(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result& UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::set_err(int32_t value) {
  EnsureStorageInitialized(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Destroy() {
  switch (tag_) {
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid);
}

void UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::Invalid):
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kResponse:
        new (&response_) ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Response();
        break;
      case ::test::unknowninteractions::UnknownInteractionsClosedDriverProtocol_StrictTwoWayTableErr_Result::Tag::kErr:
        new (&err_) int32_t();
        break;
      default:
        break;
    }
  }
}

//
// Proxies and stubs definitions
//

#ifdef __Fuchsia__

  
  
  
  
  
  
  
  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable;
  
  
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable;
  
  
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable;

}  // namespace _internal

UnknownInteractionsProtocol::~UnknownInteractionsProtocol() = default;

const fidl_type_t* ::test::unknowninteractions::UnknownInteractionsProtocol_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::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictOneWay_Ordinal:
      *out_is_known = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleOneWay_Ordinal:
      *out_is_known = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    default:
      return nullptr;
  }
}

const fidl_type_t* UnknownInteractionsProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEvent_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEvent_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable;
        ;
    default:
      return nullptr;
  }
}

UnknownInteractionsProtocol_EventSender::~UnknownInteractionsProtocol_EventSender() = default;

UnknownInteractionsProtocol_Sync::~UnknownInteractionsProtocol_Sync() = default;

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

UnknownInteractionsProtocol_Proxy::~UnknownInteractionsProtocol_Proxy() = default;

zx_status_t UnknownInteractionsProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEvent_Ordinal: {
      if (!StrictEvent) {
        status = ZX_OK;
        break;
      }
      StrictEvent();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventFields_Ordinal: {
      if (!StrictEventFields) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventFields(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventUnion_Ordinal: {
      if (!StrictEventUnion) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventUnion(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventTable_Ordinal: {
      if (!StrictEventTable) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventTable(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocolStrictEventTableRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEvent_Ordinal: {
      if (!FlexibleEvent) {
        status = ZX_OK;
        break;
      }
      FlexibleEvent();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventFields_Ordinal: {
      if (!FlexibleEventFields) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      FlexibleEventFields(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventUnion_Ordinal: {
      if (!FlexibleEventUnion) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      FlexibleEventUnion(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventTable_Ordinal: {
      if (!FlexibleEventTable) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      FlexibleEventTable(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventTableRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      auto txid = message.txid();
      auto is_flexible = message.is_flexible();
      auto ordinal = message.ordinal();
      // To satisfy RFC-0138, move the message so it is destructed before
      // calling the unknown event handler.
      { auto message_ = std::move(message); }
      if (txid == 0 && is_flexible) {
        handle_unknown_event(ordinal);
        break;
      }
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}


void UnknownInteractionsProtocol_Proxy::StrictOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictOneWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictOneWay(&_encoder), nullptr);
}
void UnknownInteractionsProtocol_Proxy::FlexibleOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleOneWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleOneWay(&_encoder), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWay_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWay\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        callback_();
        return ZX_OK;
      }, nullptr);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWay(StrictTwoWayCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWay(&_encoder), UnknownInteractionsProtocol_StrictTwoWay_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayFields_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayFieldsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayFields\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayFields(StrictTwoWayFieldsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayFields(&_encoder), UnknownInteractionsProtocol_StrictTwoWayFields_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayUnion_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayUnionCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayUnion\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::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayUnion(StrictTwoWayUnionCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayUnion(&_encoder), UnknownInteractionsProtocol_StrictTwoWayUnion_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayTable_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayTableCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayTable\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::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayTableResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayTable(StrictTwoWayTableCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayTable(&_encoder), UnknownInteractionsProtocol_StrictTwoWayTable_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayErr_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayErr\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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayErr(StrictTwoWayErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayErr(&_encoder), UnknownInteractionsProtocol_StrictTwoWayErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayFieldsErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayFieldsErr\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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayFieldsErr(StrictTwoWayFieldsErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayFieldsErr(&_encoder), UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayUnionErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayUnionErr\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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayUnionErr(StrictTwoWayUnionErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayUnionErr(&_encoder), UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_StrictTwoWayTableErr_ResponseHandler(UnknownInteractionsProtocol::StrictTwoWayTableErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::StrictTwoWayTableErr\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::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::StrictTwoWayTableErr(StrictTwoWayTableErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayTableErr(&_encoder), UnknownInteractionsProtocol_StrictTwoWayTableErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWay_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWay\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWay(FlexibleTwoWayCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWay(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWay_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayFields_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayFieldsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayFields\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayFields(FlexibleTwoWayFieldsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayFields(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayFields_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayUnionCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayUnion\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayUnion(FlexibleTwoWayUnionCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayUnion(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayTable_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayTableCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayTable\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayTable(FlexibleTwoWayTableCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayTable(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayTable_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayErr_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayErr\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayErr(FlexibleTwoWayErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayErr(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayFieldsErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayFieldsErr\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayFieldsErr(FlexibleTwoWayFieldsErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayFieldsErr(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayUnionErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayUnionErr\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayUnionErr(FlexibleTwoWayUnionErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayUnionErr(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResponseHandler(UnknownInteractionsProtocol::FlexibleTwoWayTableErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsProtocol::FlexibleTwoWayTableErr\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::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable);
}

}  // namespace
void UnknownInteractionsProtocol_Proxy::FlexibleTwoWayTableErr(FlexibleTwoWayTableErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayTableErr(&_encoder), UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResponseHandler(std::move(callback)));
}

UnknownInteractionsProtocol_Stub::UnknownInteractionsProtocol_Stub(::test::unknowninteractions::UnknownInteractionsProtocol_Stub::UnknownInteractionsProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

UnknownInteractionsProtocol_Stub::~UnknownInteractionsProtocol_Stub() = default;

namespace {

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

  void operator()() {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_DynamicFlags);
    const fidl_type_t* resp_type =nullptr;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWay(&_encoder));
  }

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

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

  void operator()(int32_t some_field) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayFields(&_encoder, &some_field));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse UnknownInteractionsProtocolStrictTwoWayUnionResponse) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayUnion(&_encoder, &UnknownInteractionsProtocolStrictTwoWayUnionResponse));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayTableResponse UnknownInteractionsProtocolStrictTwoWayTableResponse) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayTable(&_encoder, &UnknownInteractionsProtocolStrictTwoWayTableResponse));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result UnknownInteractionsProtocol_StrictTwoWayErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayErr(&_encoder, &UnknownInteractionsProtocol_StrictTwoWayErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayFieldsErr(&_encoder, &UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayUnionErr(&_encoder, &UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result UnknownInteractionsProtocol_StrictTwoWayTableErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictTwoWayTableErr(&_encoder, &UnknownInteractionsProtocol_StrictTwoWayTableErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result UnknownInteractionsProtocol_FlexibleTwoWay_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWay_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWay(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWay_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result UnknownInteractionsProtocol_FlexibleTwoWayFields_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayFields_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayFields(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayFields_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayUnion(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result UnknownInteractionsProtocol_FlexibleTwoWayTable_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayTable_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayTable(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayTable_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result UnknownInteractionsProtocol_FlexibleTwoWayErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayErr_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayErr(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayFieldsErr(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayUnionErr(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable;
    ZX_ASSERT_MSG(!UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleTwoWayTableErr(&_encoder, &UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result));
  }

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

}  // namespace

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

  if (!is_known) {
    auto is_flexible = message.is_flexible();
    auto ordinal = message.ordinal();
    // To satisfy RFC-0138, move the message so it is destructed before sending
    // a reply or calling the unknown method handler.
    { auto message_ = std::move(message); }
    if (is_flexible) {
      if (response.needs_response()) {
        ::fidl::MessageEncoder encoder(ordinal, ::fidl::MessageDynamicFlags::kFlexibleMethod);
        const fidl_type_t* resp_type = &kFidlInternalUnknownMethodResponseTable;
        response.Send(resp_type, ::fidl::internal::EncodeUnknownMethodResponse(&encoder));
        impl_->handle_unknown_method(ordinal, true);
      } else {
        impl_->handle_unknown_method(ordinal, false);
      }
      return ZX_OK;
    }
    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::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictOneWay_Ordinal:
    {
      impl_->StrictOneWay();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleOneWay_Ordinal:
    {
      impl_->FlexibleOneWay();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_Ordinal:
    {
      impl_->StrictTwoWay(UnknownInteractionsProtocol_StrictTwoWay_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_Ordinal:
    {
      impl_->StrictTwoWayFields(UnknownInteractionsProtocol_StrictTwoWayFields_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_Ordinal:
    {
      impl_->StrictTwoWayUnion(UnknownInteractionsProtocol_StrictTwoWayUnion_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_Ordinal:
    {
      impl_->StrictTwoWayTable(UnknownInteractionsProtocol_StrictTwoWayTable_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_Ordinal:
    {
      impl_->StrictTwoWayErr(UnknownInteractionsProtocol_StrictTwoWayErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_Ordinal:
    {
      impl_->StrictTwoWayFieldsErr(UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_Ordinal:
    {
      impl_->StrictTwoWayUnionErr(UnknownInteractionsProtocol_StrictTwoWayUnionErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_Ordinal:
    {
      impl_->StrictTwoWayTableErr(UnknownInteractionsProtocol_StrictTwoWayTableErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_Ordinal:
    {
      impl_->FlexibleTwoWay(UnknownInteractionsProtocol_FlexibleTwoWay_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_Ordinal:
    {
      impl_->FlexibleTwoWayFields(UnknownInteractionsProtocol_FlexibleTwoWayFields_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_Ordinal:
    {
      impl_->FlexibleTwoWayUnion(UnknownInteractionsProtocol_FlexibleTwoWayUnion_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_Ordinal:
    {
      impl_->FlexibleTwoWayTable(UnknownInteractionsProtocol_FlexibleTwoWayTable_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_Ordinal:
    {
      impl_->FlexibleTwoWayErr(UnknownInteractionsProtocol_FlexibleTwoWayErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Ordinal:
    {
      impl_->FlexibleTwoWayFieldsErr(UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Ordinal:
    {
      impl_->FlexibleTwoWayUnionErr(UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_Ordinal:
    {
      impl_->FlexibleTwoWayTableErr(UnknownInteractionsProtocol_FlexibleTwoWayTableErr_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;
}
void UnknownInteractionsProtocol_Stub::StrictEvent() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEvent_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEvent_DynamicFlags);
  const fidl_type_t* resp_type =nullptr;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictEvent(&_encoder));
}
void UnknownInteractionsProtocol_Stub::StrictEventFields(int32_t some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventFields_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventFieldsRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictEventFields(&_encoder, &some_field));
}
void UnknownInteractionsProtocol_Stub::StrictEventUnion(::test::unknowninteractions::UnknownInteractionsProtocolStrictEventUnionRequest UnknownInteractionsProtocolStrictEventUnionRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventUnion_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventUnionRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictEventUnion(&_encoder, &UnknownInteractionsProtocolStrictEventUnionRequest));
}
void UnknownInteractionsProtocol_Stub::StrictEventTable(::test::unknowninteractions::UnknownInteractionsProtocolStrictEventTableRequest UnknownInteractionsProtocolStrictEventTableRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictEventTable_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictEventTableRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::StrictEventTable(&_encoder, &UnknownInteractionsProtocolStrictEventTableRequest));
}
void UnknownInteractionsProtocol_Stub::FlexibleEvent() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEvent_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEvent_DynamicFlags);
  const fidl_type_t* resp_type =nullptr;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleEvent(&_encoder));
}
void UnknownInteractionsProtocol_Stub::FlexibleEventFields(int32_t some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventFields_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventFieldsRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleEventFields(&_encoder, &some_field));
}
void UnknownInteractionsProtocol_Stub::FlexibleEventUnion(::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventUnionRequest UnknownInteractionsProtocolFlexibleEventUnionRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventUnion_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventUnionRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleEventUnion(&_encoder, &UnknownInteractionsProtocolFlexibleEventUnionRequest));
}
void UnknownInteractionsProtocol_Stub::FlexibleEventTable(::test::unknowninteractions::UnknownInteractionsProtocolFlexibleEventTableRequest UnknownInteractionsProtocolFlexibleEventTableRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleEventTable_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolFlexibleEventTableRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_ResponseEncoder::FlexibleEventTable(&_encoder, &UnknownInteractionsProtocolFlexibleEventTableRequest));
}

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

UnknownInteractionsProtocol_SyncProxy::~UnknownInteractionsProtocol_SyncProxy() = default;

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictOneWay_DynamicFlags);
    const fidl_type_t* req_type =nullptr;
  return proxy_.Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictOneWay(&_encoder));
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleOneWay_DynamicFlags);
    const fidl_type_t* req_type =nullptr;
  return proxy_.Send(req_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleOneWay(&_encoder));
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWay_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =nullptr;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWay(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayFields(int32_t* out_some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFields_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayFieldsResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayFields(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_some_field = ::fidl::DecodeAs<int32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayUnion(::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse* out_UnknownInteractionsProtocolStrictTwoWayUnionResponse) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnion_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayUnionResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayUnion(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocolStrictTwoWayUnionResponse = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayUnionResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayTable(::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayTableResponse* out_UnknownInteractionsProtocolStrictTwoWayTableResponse) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTable_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocolStrictTwoWayTableResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayTable(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocolStrictTwoWayTableResponse = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocolStrictTwoWayTableResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayErr(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result* out_UnknownInteractionsProtocol_StrictTwoWayErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_StrictTwoWayErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayFieldsErr(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result* out_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayFieldsErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayFieldsErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayFieldsErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayUnionErr(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result* out_UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayUnionErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayUnionErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayUnionErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayUnionErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::StrictTwoWayTableErr(::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result* out_UnknownInteractionsProtocol_StrictTwoWayTableErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_StrictTwoWayTableErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_StrictTwoWayTableErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::StrictTwoWayTableErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_StrictTwoWayTableErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_StrictTwoWayTableErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWay(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result* out_UnknownInteractionsProtocol_FlexibleTwoWay_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWay_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWay_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWay(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWay_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWay_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayFields(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayFields_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFields_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFields_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayFields(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayFields_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFields_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayUnion(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnion_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnion_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayUnion(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnion_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayTable(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayTable_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTable_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTable_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayTable(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayTable_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTable_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayErr(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayFieldsErr(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayFieldsErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayFieldsErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayUnionErr(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayUnionErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayUnionErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayUnionErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsProtocol_SyncProxy::FlexibleTwoWayTableErr(::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result* out_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsProtocol_FlexibleTwoWayTableErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsProtocol_RequestEncoder::FlexibleTwoWayTableErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsProtocol_FlexibleTwoWayTableErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__


#ifdef __Fuchsia__

  
  
  
  
  
  
  
  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable;
  
  
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable;
  
  
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable;

}  // namespace _internal

UnknownInteractionsAjarProtocol::~UnknownInteractionsAjarProtocol() = default;

const fidl_type_t* ::test::unknowninteractions::UnknownInteractionsAjarProtocol_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::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictOneWay_Ordinal:
      *out_is_known = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleOneWay_Ordinal:
      *out_is_known = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    default:
      return nullptr;
  }
}

const fidl_type_t* UnknownInteractionsAjarProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEvent_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEvent_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable;
        ;
    default:
      return nullptr;
  }
}

UnknownInteractionsAjarProtocol_EventSender::~UnknownInteractionsAjarProtocol_EventSender() = default;

UnknownInteractionsAjarProtocol_Sync::~UnknownInteractionsAjarProtocol_Sync() = default;

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

UnknownInteractionsAjarProtocol_Proxy::~UnknownInteractionsAjarProtocol_Proxy() = default;

zx_status_t UnknownInteractionsAjarProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEvent_Ordinal: {
      if (!StrictEvent) {
        status = ZX_OK;
        break;
      }
      StrictEvent();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventFields_Ordinal: {
      if (!StrictEventFields) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventFields(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventUnion_Ordinal: {
      if (!StrictEventUnion) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventUnion(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventTable_Ordinal: {
      if (!StrictEventTable) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventTable(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventTableRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEvent_Ordinal: {
      if (!FlexibleEvent) {
        status = ZX_OK;
        break;
      }
      FlexibleEvent();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventFields_Ordinal: {
      if (!FlexibleEventFields) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      FlexibleEventFields(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventUnion_Ordinal: {
      if (!FlexibleEventUnion) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      FlexibleEventUnion(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventTable_Ordinal: {
      if (!FlexibleEventTable) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      FlexibleEventTable(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventTableRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      auto txid = message.txid();
      auto is_flexible = message.is_flexible();
      auto ordinal = message.ordinal();
      // To satisfy RFC-0138, move the message so it is destructed before
      // calling the unknown event handler.
      { auto message_ = std::move(message); }
      if (txid == 0 && is_flexible) {
        handle_unknown_event(ordinal);
        break;
      }
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}


void UnknownInteractionsAjarProtocol_Proxy::StrictOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictOneWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictOneWay(&_encoder), nullptr);
}
void UnknownInteractionsAjarProtocol_Proxy::FlexibleOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleOneWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::FlexibleOneWay(&_encoder), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWay_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWay\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        callback_();
        return ZX_OK;
      }, nullptr);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWay(StrictTwoWayCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWay(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWay_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayFields_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayFieldsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayFields\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayFields(StrictTwoWayFieldsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayFields(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayFields_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayUnion_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayUnionCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayUnion\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::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayUnion(StrictTwoWayUnionCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayUnion(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayUnion_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayTable_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayTableCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayTable\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::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayTableResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayTable(StrictTwoWayTableCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayTable(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayTable_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayErr\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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayErr(StrictTwoWayErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayErr(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayFieldsErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayFieldsErr\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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayFieldsErr(StrictTwoWayFieldsErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayFieldsErr(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayUnionErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayUnionErr\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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayUnionErr(StrictTwoWayUnionErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayUnionErr(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResponseHandler(UnknownInteractionsAjarProtocol::StrictTwoWayTableErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsAjarProtocol::StrictTwoWayTableErr\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::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable);
}

}  // namespace
void UnknownInteractionsAjarProtocol_Proxy::StrictTwoWayTableErr(StrictTwoWayTableErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayTableErr(&_encoder), UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResponseHandler(std::move(callback)));
}

UnknownInteractionsAjarProtocol_Stub::UnknownInteractionsAjarProtocol_Stub(::test::unknowninteractions::UnknownInteractionsAjarProtocol_Stub::UnknownInteractionsAjarProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

UnknownInteractionsAjarProtocol_Stub::~UnknownInteractionsAjarProtocol_Stub() = default;

namespace {

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

  void operator()() {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_DynamicFlags);
    const fidl_type_t* resp_type =nullptr;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWay(&_encoder));
  }

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

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

  void operator()(int32_t some_field) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayFields(&_encoder, &some_field));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayUnion(&_encoder, &UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayTableResponse UnknownInteractionsAjarProtocolStrictTwoWayTableResponse) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayTable(&_encoder, &UnknownInteractionsAjarProtocolStrictTwoWayTableResponse));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayErr(&_encoder, &UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayFieldsErr(&_encoder, &UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayUnionErr(&_encoder, &UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictTwoWayTableErr(&_encoder, &UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result));
  }

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

}  // namespace

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

  if (!is_known) {
    auto is_flexible = message.is_flexible();
    auto ordinal = message.ordinal();
    // To satisfy RFC-0138, move the message so it is destructed before sending
    // a reply or calling the unknown method handler.
    { auto message_ = std::move(message); }
    if (is_flexible) {
      if (!response.needs_response()) {
        impl_->handle_unknown_method(ordinal);
        return ZX_OK;
      }
    }
    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::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictOneWay_Ordinal:
    {
      impl_->StrictOneWay();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleOneWay_Ordinal:
    {
      impl_->FlexibleOneWay();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_Ordinal:
    {
      impl_->StrictTwoWay(UnknownInteractionsAjarProtocol_StrictTwoWay_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_Ordinal:
    {
      impl_->StrictTwoWayFields(UnknownInteractionsAjarProtocol_StrictTwoWayFields_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_Ordinal:
    {
      impl_->StrictTwoWayUnion(UnknownInteractionsAjarProtocol_StrictTwoWayUnion_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_Ordinal:
    {
      impl_->StrictTwoWayTable(UnknownInteractionsAjarProtocol_StrictTwoWayTable_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_Ordinal:
    {
      impl_->StrictTwoWayErr(UnknownInteractionsAjarProtocol_StrictTwoWayErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Ordinal:
    {
      impl_->StrictTwoWayFieldsErr(UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Ordinal:
    {
      impl_->StrictTwoWayUnionErr(UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Ordinal:
    {
      impl_->StrictTwoWayTableErr(UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_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;
}
void UnknownInteractionsAjarProtocol_Stub::StrictEvent() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEvent_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEvent_DynamicFlags);
  const fidl_type_t* resp_type =nullptr;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictEvent(&_encoder));
}
void UnknownInteractionsAjarProtocol_Stub::StrictEventFields(int32_t some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventFields_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventFieldsRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictEventFields(&_encoder, &some_field));
}
void UnknownInteractionsAjarProtocol_Stub::StrictEventUnion(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventUnionRequest UnknownInteractionsAjarProtocolStrictEventUnionRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventUnion_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventUnionRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictEventUnion(&_encoder, &UnknownInteractionsAjarProtocolStrictEventUnionRequest));
}
void UnknownInteractionsAjarProtocol_Stub::StrictEventTable(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictEventTableRequest UnknownInteractionsAjarProtocolStrictEventTableRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictEventTable_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictEventTableRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::StrictEventTable(&_encoder, &UnknownInteractionsAjarProtocolStrictEventTableRequest));
}
void UnknownInteractionsAjarProtocol_Stub::FlexibleEvent() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEvent_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEvent_DynamicFlags);
  const fidl_type_t* resp_type =nullptr;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::FlexibleEvent(&_encoder));
}
void UnknownInteractionsAjarProtocol_Stub::FlexibleEventFields(int32_t some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventFields_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventFieldsRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::FlexibleEventFields(&_encoder, &some_field));
}
void UnknownInteractionsAjarProtocol_Stub::FlexibleEventUnion(::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventUnionRequest UnknownInteractionsAjarProtocolFlexibleEventUnionRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventUnion_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventUnionRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::FlexibleEventUnion(&_encoder, &UnknownInteractionsAjarProtocolFlexibleEventUnionRequest));
}
void UnknownInteractionsAjarProtocol_Stub::FlexibleEventTable(::test::unknowninteractions::UnknownInteractionsAjarProtocolFlexibleEventTableRequest UnknownInteractionsAjarProtocolFlexibleEventTableRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleEventTable_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolFlexibleEventTableRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_ResponseEncoder::FlexibleEventTable(&_encoder, &UnknownInteractionsAjarProtocolFlexibleEventTableRequest));
}

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

UnknownInteractionsAjarProtocol_SyncProxy::~UnknownInteractionsAjarProtocol_SyncProxy() = default;

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictOneWay_DynamicFlags);
    const fidl_type_t* req_type =nullptr;
  return proxy_.Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictOneWay(&_encoder));
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::FlexibleOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_FlexibleOneWay_DynamicFlags);
    const fidl_type_t* req_type =nullptr;
  return proxy_.Send(req_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::FlexibleOneWay(&_encoder));
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWay_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =nullptr;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWay(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayFields(int32_t* out_some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFields_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayFieldsResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayFields(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_some_field = ::fidl::DecodeAs<int32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayUnion(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse* out_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnion_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayUnion(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayUnionResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayTable(::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayTableResponse* out_UnknownInteractionsAjarProtocolStrictTwoWayTableResponse) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTable_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocolStrictTwoWayTableResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayTable(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsAjarProtocolStrictTwoWayTableResponse = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocolStrictTwoWayTableResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayErr(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result* out_UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayFieldsErr(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result* out_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayFieldsErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayFieldsErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayUnionErr(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result* out_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayUnionErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayUnionErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsAjarProtocol_SyncProxy::StrictTwoWayTableErr(::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result* out_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsAjarProtocol_StrictTwoWayTableErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsAjarProtocol_RequestEncoder::StrictTwoWayTableErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsAjarProtocol_StrictTwoWayTableErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__


#ifdef __Fuchsia__

  
  
  
  
  
  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable;
  
  
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable;

}  // namespace _internal

UnknownInteractionsClosedProtocol::~UnknownInteractionsClosedProtocol() = default;

const fidl_type_t* ::test::unknowninteractions::UnknownInteractionsClosedProtocol_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::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictOneWay_Ordinal:
      *out_is_known = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    default:
      return nullptr;
  }
}

const fidl_type_t* UnknownInteractionsClosedProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEvent_Ordinal:
      return nullptr;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventFields_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventUnion_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable;
        ;
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventTable_Ordinal:
      return &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable;
        ;
    default:
      return nullptr;
  }
}

UnknownInteractionsClosedProtocol_EventSender::~UnknownInteractionsClosedProtocol_EventSender() = default;

UnknownInteractionsClosedProtocol_Sync::~UnknownInteractionsClosedProtocol_Sync() = default;

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

UnknownInteractionsClosedProtocol_Proxy::~UnknownInteractionsClosedProtocol_Proxy() = default;

zx_status_t UnknownInteractionsClosedProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEvent_Ordinal: {
      if (!StrictEvent) {
        status = ZX_OK;
        break;
      }
      StrictEvent();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventFields_Ordinal: {
      if (!StrictEventFields) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventFields(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventUnion_Ordinal: {
      if (!StrictEventUnion) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventUnion(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventTable_Ordinal: {
      if (!StrictEventTable) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      StrictEventTable(::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventTableRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}


void UnknownInteractionsClosedProtocol_Proxy::StrictOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictOneWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictOneWay(&_encoder), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWay_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWay\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        callback_();
        return ZX_OK;
      }, nullptr);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWay(StrictTwoWayCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWay(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWay_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayFields_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayFieldsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayFields\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayFields(StrictTwoWayFieldsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayFields(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayFields_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayUnion_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayUnionCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayUnion\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::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayUnion(StrictTwoWayUnionCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayUnion(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayUnion_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayTable_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayTableCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayTable\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::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayTableResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayTable(StrictTwoWayTableCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayTable(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayTable_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayErr\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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayErr(StrictTwoWayErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayErr(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayFieldsErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayFieldsErr\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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayFieldsErr(StrictTwoWayFieldsErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayFieldsErr(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayUnionErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayUnionErr\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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayUnionErr(StrictTwoWayUnionErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayUnionErr(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResponseHandler(UnknownInteractionsClosedProtocol::StrictTwoWayTableErrCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for UnknownInteractionsClosedProtocol::StrictTwoWayTableErr\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::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable);
}

}  // namespace
void UnknownInteractionsClosedProtocol_Proxy::StrictTwoWayTableErr(StrictTwoWayTableErrCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_DynamicFlags);
  const fidl_type_t* req_type =nullptr;
  controller_->Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayTableErr(&_encoder), UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResponseHandler(std::move(callback)));
}

UnknownInteractionsClosedProtocol_Stub::UnknownInteractionsClosedProtocol_Stub(::test::unknowninteractions::UnknownInteractionsClosedProtocol_Stub::UnknownInteractionsClosedProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

UnknownInteractionsClosedProtocol_Stub::~UnknownInteractionsClosedProtocol_Stub() = default;

namespace {

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

  void operator()() {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_DynamicFlags);
    const fidl_type_t* resp_type =nullptr;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWay(&_encoder));
  }

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

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

  void operator()(int32_t some_field) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayFields(&_encoder, &some_field));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayUnion(&_encoder, &UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayTableResponse UnknownInteractionsClosedProtocolStrictTwoWayTableResponse) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayTable(&_encoder, &UnknownInteractionsClosedProtocolStrictTwoWayTableResponse));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayErr(&_encoder, &UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayFieldsErr(&_encoder, &UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayUnionErr(&_encoder, &UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result));
  }

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

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

  void operator()(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result) {
    ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_DynamicFlags);
    const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable;
    response_.Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictTwoWayTableErr(&_encoder, &UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result));
  }

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

}  // namespace

zx_status_t UnknownInteractionsClosedProtocol_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::unknowninteractions::UnknownInteractionsClosedProtocol_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::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictOneWay_Ordinal:
    {
      impl_->StrictOneWay();
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_Ordinal:
    {
      impl_->StrictTwoWay(UnknownInteractionsClosedProtocol_StrictTwoWay_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_Ordinal:
    {
      impl_->StrictTwoWayFields(UnknownInteractionsClosedProtocol_StrictTwoWayFields_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_Ordinal:
    {
      impl_->StrictTwoWayUnion(UnknownInteractionsClosedProtocol_StrictTwoWayUnion_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_Ordinal:
    {
      impl_->StrictTwoWayTable(UnknownInteractionsClosedProtocol_StrictTwoWayTable_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_Ordinal:
    {
      impl_->StrictTwoWayErr(UnknownInteractionsClosedProtocol_StrictTwoWayErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Ordinal:
    {
      impl_->StrictTwoWayFieldsErr(UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Ordinal:
    {
      impl_->StrictTwoWayUnionErr(UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Responder(std::move(response)));
      break;
    }
    case ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Ordinal:
    {
      impl_->StrictTwoWayTableErr(UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_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;
}
void UnknownInteractionsClosedProtocol_Stub::StrictEvent() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEvent_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEvent_DynamicFlags);
  const fidl_type_t* resp_type =nullptr;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictEvent(&_encoder));
}
void UnknownInteractionsClosedProtocol_Stub::StrictEventFields(int32_t some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventFields_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventFieldsRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictEventFields(&_encoder, &some_field));
}
void UnknownInteractionsClosedProtocol_Stub::StrictEventUnion(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventUnionRequest UnknownInteractionsClosedProtocolStrictEventUnionRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventUnion_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventUnionRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictEventUnion(&_encoder, &UnknownInteractionsClosedProtocolStrictEventUnionRequest));
}
void UnknownInteractionsClosedProtocol_Stub::StrictEventTable(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictEventTableRequest UnknownInteractionsClosedProtocolStrictEventTableRequest) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictEventTable_DynamicFlags);
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictEventTableRequestTable;sender_()->Send(resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_ResponseEncoder::StrictEventTable(&_encoder, &UnknownInteractionsClosedProtocolStrictEventTableRequest));
}

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

UnknownInteractionsClosedProtocol_SyncProxy::~UnknownInteractionsClosedProtocol_SyncProxy() = default;

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictOneWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictOneWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictOneWay_DynamicFlags);
    const fidl_type_t* req_type =nullptr;
  return proxy_.Send(req_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictOneWay(&_encoder));
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWay() {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWay_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =nullptr;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWay(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayFields(int32_t* out_some_field) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFields_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayFieldsResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayFields(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_some_field = ::fidl::DecodeAs<int32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayUnion(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse* out_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnion_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayUnion(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayUnionResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayTable(::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayTableResponse* out_UnknownInteractionsClosedProtocolStrictTwoWayTableResponse) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTable_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocolStrictTwoWayTableResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayTable(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsClosedProtocolStrictTwoWayTableResponse = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocolStrictTwoWayTableResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayErr(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result* out_UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayFieldsErr(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result* out_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayFieldsErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayFieldsErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayUnionErr(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result* out_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayUnionErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayUnionErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t UnknownInteractionsClosedProtocol_SyncProxy::StrictTwoWayTableErr(::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result* out_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result) {
  ::fidl::MessageEncoder _encoder(::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Ordinal, ::test::unknowninteractions::internal::kUnknownInteractionsClosedProtocol_StrictTwoWayTableErr_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =nullptr;
  const fidl_type_t* resp_type =&::test::unknowninteractions::_internal::test_unknowninteractions_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::unknowninteractions::UnknownInteractionsClosedProtocol_RequestEncoder::StrictTwoWayTableErr(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result = ::fidl::DecodeAs<::test::unknowninteractions::UnknownInteractionsClosedProtocol_StrictTwoWayTableErr_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__

}  // namespace unknowninteractions
}  // namespace test

