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

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

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

//
// Domain objects definitions
//
namespace test {
namespace protocols {
#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsTopResponseTable;
const fidl_type_t* WithProtocolEndsServerEndsTopResponse::FidlType = &test_protocols_WithProtocolEndsServerEndsTopResponseTable;

void WithProtocolEndsServerEndsTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<WithProtocolEndsServerEndsTopResponse>::value) {
    memcpy(_encoder->template GetPtr<WithProtocolEndsServerEndsTopResponse>(_offset), this, sizeof(WithProtocolEndsServerEndsTopResponse));
  } else {
    ::fidl::Encode(_encoder, &out, _offset + 0, ::fidl::HandleInformation{
                                                    .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                    .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                });
  }
}

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

zx_status_t WithProtocolEndsServerEndsTopResponse::Clone(WithProtocolEndsServerEndsTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(out, &_result->out);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsRequestTable;
const fidl_type_t* WithProtocolEndsServerEndsRequest::FidlType = &test_protocols_WithProtocolEndsServerEndsRequestTable;

void WithProtocolEndsServerEndsRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                               cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<WithProtocolEndsServerEndsRequest>::value) {
    memcpy(_encoder->template GetPtr<WithProtocolEndsServerEndsRequest>(_offset), this, sizeof(WithProtocolEndsServerEndsRequest));
  } else {
    ::fidl::Encode(_encoder, &in, _offset + 0, ::fidl::HandleInformation{
                                                   .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                   .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                               });
  }
}

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

zx_status_t WithProtocolEndsServerEndsRequest::Clone(WithProtocolEndsServerEndsRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(in, &_result->in);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsTopResponseTable;
const fidl_type_t* WithProtocolEndsClientEndsTopResponse::FidlType = &test_protocols_WithProtocolEndsClientEndsTopResponseTable;

void WithProtocolEndsClientEndsTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<WithProtocolEndsClientEndsTopResponse>::value) {
    memcpy(_encoder->template GetPtr<WithProtocolEndsClientEndsTopResponse>(_offset), this, sizeof(WithProtocolEndsClientEndsTopResponse));
  } else {
    ::fidl::Encode(_encoder, &out, _offset + 0, ::fidl::HandleInformation{
                                                    .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                    .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                });
  }
}

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

zx_status_t WithProtocolEndsClientEndsTopResponse::Clone(WithProtocolEndsClientEndsTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(out, &_result->out);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsRequestTable;
const fidl_type_t* WithProtocolEndsClientEndsRequest::FidlType = &test_protocols_WithProtocolEndsClientEndsRequestTable;

void WithProtocolEndsClientEndsRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                               cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<WithProtocolEndsClientEndsRequest>::value) {
    memcpy(_encoder->template GetPtr<WithProtocolEndsClientEndsRequest>(_offset), this, sizeof(WithProtocolEndsClientEndsRequest));
  } else {
    ::fidl::Encode(_encoder, &in, _offset + 0, ::fidl::HandleInformation{
                                                   .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                   .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                               });
  }
}

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

zx_status_t WithProtocolEndsClientEndsRequest::Clone(WithProtocolEndsClientEndsRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(in, &_result->in);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ResponseAsStruct_ResponseTable;
const fidl_type_t* WithErrorSyntax_ResponseAsStruct_Response::FidlType = &test_protocols_WithErrorSyntax_ResponseAsStruct_ResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ResponseAsStruct_ResultTable;
const fidl_type_t* WithErrorSyntax_ResponseAsStruct_Result::FidlType = &test_protocols_WithErrorSyntax_ResponseAsStruct_ResultTable;

WithErrorSyntax_ResponseAsStruct_Result::WithErrorSyntax_ResponseAsStruct_Result() {}

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

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

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

WithErrorSyntax_ResponseAsStruct_Result WithErrorSyntax_ResponseAsStruct_Result::WithResponse(::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&& val) {
  WithErrorSyntax_ResponseAsStruct_Result result;
  result.set_response(std::move(val));
  return result;
}
WithErrorSyntax_ResponseAsStruct_Result WithErrorSyntax_ResponseAsStruct_Result::WithErr(uint32_t&& val) {
  WithErrorSyntax_ResponseAsStruct_Result result;
  result.set_err(std::move(val));
  return result;
}

void WithErrorSyntax_ResponseAsStruct_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::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_ResponseAsStruct_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_xunion_v2_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &response_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_ResponseAsStruct_Response, ::fidl::Encoder>(encoder)));

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

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

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

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kResponse: {
      new (&value->response_)::test::protocols::WithErrorSyntax_ResponseAsStruct_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

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

WithErrorSyntax_ResponseAsStruct_Result& WithErrorSyntax_ResponseAsStruct_Result::set_response(::test::protocols::WithErrorSyntax_ResponseAsStruct_Response value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

WithErrorSyntax_ResponseAsStruct_Result& WithErrorSyntax_ResponseAsStruct_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void WithErrorSyntax_ResponseAsStruct_Result::Destroy() {
  switch (tag_) {
    case ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kErr:
      break;

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

void WithErrorSyntax_ResponseAsStruct_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::Invalid):
        break;
      case ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kResponse:
        new (&response_)::test::protocols::WithErrorSyntax_ResponseAsStruct_Response();
        break;
      case ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable;
const fidl_type_t* WithErrorSyntaxResponseAsStructTopResponse::FidlType = &test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable;

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

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

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

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_HandleInResult_ResponseTable;
const fidl_type_t* WithErrorSyntax_HandleInResult_Response::FidlType = &test_protocols_WithErrorSyntax_HandleInResult_ResponseTable;

void WithErrorSyntax_HandleInResult_Response::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<WithErrorSyntax_HandleInResult_Response>::value) {
    memcpy(_encoder->template GetPtr<WithErrorSyntax_HandleInResult_Response>(_offset), this, sizeof(WithErrorSyntax_HandleInResult_Response));
  } else {
    ::fidl::Encode(_encoder, &h, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_NONE,
                                                  .rights = 0x80000000,
                                              });
  }
}

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

zx_status_t WithErrorSyntax_HandleInResult_Response::Clone(WithErrorSyntax_HandleInResult_Response* _result) const {
  zx_status_t _status = ::fidl::Clone(h, &_result->h);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_HandleInResult_ResultTable;
const fidl_type_t* WithErrorSyntax_HandleInResult_Result::FidlType = &test_protocols_WithErrorSyntax_HandleInResult_ResultTable;

WithErrorSyntax_HandleInResult_Result::WithErrorSyntax_HandleInResult_Result() {}

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

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

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

WithErrorSyntax_HandleInResult_Result WithErrorSyntax_HandleInResult_Result::WithResponse(::test::protocols::WithErrorSyntax_HandleInResult_Response&& val) {
  WithErrorSyntax_HandleInResult_Result result;
  result.set_response(std::move(val));
  return result;
}
WithErrorSyntax_HandleInResult_Result WithErrorSyntax_HandleInResult_Result::WithErr(uint32_t&& val) {
  WithErrorSyntax_HandleInResult_Result result;
  result.set_err(std::move(val));
  return result;
}

void WithErrorSyntax_HandleInResult_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::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_HandleInResult_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_xunion_v2_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &response_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_HandleInResult_Response, ::fidl::Encoder>(encoder)));

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

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

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

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kResponse: {
      new (&value->response_)::test::protocols::WithErrorSyntax_HandleInResult_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

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

WithErrorSyntax_HandleInResult_Result& WithErrorSyntax_HandleInResult_Result::set_response(::test::protocols::WithErrorSyntax_HandleInResult_Response value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

WithErrorSyntax_HandleInResult_Result& WithErrorSyntax_HandleInResult_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void WithErrorSyntax_HandleInResult_Result::Destroy() {
  switch (tag_) {
    case ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kErr:
      break;

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

void WithErrorSyntax_HandleInResult_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::Invalid):
        break;
      case ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kResponse:
        new (&response_)::test::protocols::WithErrorSyntax_HandleInResult_Response();
        break;
      case ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;
const fidl_type_t* WithErrorSyntaxHandleInResultTopResponse::FidlType = &test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;

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

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

zx_status_t WithErrorSyntaxHandleInResultTopResponse::Clone(WithErrorSyntaxHandleInResultTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(result, &_result->result);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResponseTable;
const fidl_type_t* WithErrorSyntax_ErrorAsPrimitive_Response::FidlType = &test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResponseTable;

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

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

zx_status_t WithErrorSyntax_ErrorAsPrimitive_Response::Clone(WithErrorSyntax_ErrorAsPrimitive_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_protocols_WithErrorSyntax_ErrorAsPrimitive_ResultTable;
const fidl_type_t* WithErrorSyntax_ErrorAsPrimitive_Result::FidlType = &test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResultTable;

WithErrorSyntax_ErrorAsPrimitive_Result::WithErrorSyntax_ErrorAsPrimitive_Result() {}

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

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

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

WithErrorSyntax_ErrorAsPrimitive_Result WithErrorSyntax_ErrorAsPrimitive_Result::WithResponse(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&& val) {
  WithErrorSyntax_ErrorAsPrimitive_Result result;
  result.set_response(std::move(val));
  return result;
}
WithErrorSyntax_ErrorAsPrimitive_Result WithErrorSyntax_ErrorAsPrimitive_Result::WithErr(uint32_t&& val) {
  WithErrorSyntax_ErrorAsPrimitive_Result result;
  result.set_err(std::move(val));
  return result;
}

void WithErrorSyntax_ErrorAsPrimitive_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::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_xunion_v2_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &response_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response, ::fidl::Encoder>(encoder)));

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

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

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

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kResponse: {
      new (&value->response_)::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

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

WithErrorSyntax_ErrorAsPrimitive_Result& WithErrorSyntax_ErrorAsPrimitive_Result::set_response(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

WithErrorSyntax_ErrorAsPrimitive_Result& WithErrorSyntax_ErrorAsPrimitive_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void WithErrorSyntax_ErrorAsPrimitive_Result::Destroy() {
  switch (tag_) {
    case ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kErr:
      break;

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

void WithErrorSyntax_ErrorAsPrimitive_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::Invalid):
        break;
      case ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kResponse:
        new (&response_)::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response();
        break;
      case ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;
const fidl_type_t* WithErrorSyntaxErrorAsPrimitiveTopResponse::FidlType = &test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ErrorAsEnum_ResponseTable;
const fidl_type_t* WithErrorSyntax_ErrorAsEnum_Response::FidlType = &test_protocols_WithErrorSyntax_ErrorAsEnum_ResponseTable;

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

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

zx_status_t WithErrorSyntax_ErrorAsEnum_Response::Clone(WithErrorSyntax_ErrorAsEnum_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_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;
const fidl_type_t* WithAndWithoutRequestResponseWithRequestWithResponseTopResponse::FidlType = &test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
const fidl_type_t* WithAndWithoutRequestResponseWithRequestWithResponseRequest::FidlType = &test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
const fidl_type_t* WithAndWithoutRequestResponseWithRequestNoResponseRequest::FidlType = &test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
const fidl_type_t* WithAndWithoutRequestResponseWithRequestEmptyResponseRequest::FidlType = &test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;
const fidl_type_t* WithAndWithoutRequestResponseOnWithResponseRequest::FidlType = &test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;
const fidl_type_t* WithAndWithoutRequestResponseNoRequestWithResponseTopResponse::FidlType = &test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_TransitionalRequestTopResponseTable;
const fidl_type_t* TransitionalRequestTopResponse::FidlType = &test_protocols_TransitionalRequestTopResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_TransitionalRequestRequestTable;
const fidl_type_t* TransitionalRequestRequest::FidlType = &test_protocols_TransitionalRequestRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_TransitionalOneWayRequestTable;
const fidl_type_t* TransitionalOneWayRequest::FidlType = &test_protocols_TransitionalOneWayRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_TransitionalEventRequestTable;
const fidl_type_t* TransitionalEventRequest::FidlType = &test_protocols_TransitionalEventRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_TheUnionTable;
const fidl_type_t* TheUnion::FidlType = &test_protocols_TheUnionTable;

TheUnion::TheUnion() {}

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

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

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

TheUnion TheUnion::WithV(uint32_t&& val) {
  TheUnion result;
  result.set_v(std::move(val));
  return result;
}

void TheUnion::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::protocols::TheUnion::Tag::kV: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &v_, offset + offsetof(fidl_xunion_v2_t, envelope));

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

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

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

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

zx_status_t TheUnion::Clone(TheUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocols::TheUnion::Tag::Invalid:
      return ZX_OK;
    case ::test::protocols::TheUnion::Tag::kV:
      return ::fidl::Clone(v_, &result->v_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

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

void TheUnion::Destroy() {
  switch (tag_) {
    case ::test::protocols::TheUnion::Tag::kV:
      break;

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

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

extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodRequestTable;
const fidl_type_t* MethodWithUnionUnionMethodRequest::FidlType = &test_protocols_MethodWithUnionUnionMethodRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_SyscallProtocolMethodCRequestTable;
const fidl_type_t* SyscallProtocolMethodCRequest::FidlType = &test_protocols_SyscallProtocolMethodCRequestTable;

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

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

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

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_ProtocolEndsTable;
const fidl_type_t* ProtocolEnds::FidlType = &test_protocols_ProtocolEndsTable;

void ProtocolEnds::Encode(::fidl::Encoder* _encoder, size_t _offset,
                          cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ProtocolEnds>::value) {
    memcpy(_encoder->template GetPtr<ProtocolEnds>(_offset), this, sizeof(ProtocolEnds));
  } else {
    ::fidl::Encode(_encoder, &client, _offset + 0, ::fidl::HandleInformation{
                                                       .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                       .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                   });

    ::fidl::Encode(_encoder, &server, _offset + 4, ::fidl::HandleInformation{
                                                       .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                       .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                   });

    ::fidl::Encode(_encoder, &client_opt, _offset + 8, ::fidl::HandleInformation{
                                                           .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                           .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                       });

    ::fidl::Encode(_encoder, &server_opt, _offset + 12, ::fidl::HandleInformation{
                                                            .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                            .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                        });
  }
}

void ProtocolEnds::Decode(::fidl::Decoder* _decoder, ProtocolEnds* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<ProtocolEnds>::value) {
    memcpy(_value, _decoder->template GetPtr<ProtocolEnds>(_offset), sizeof(ProtocolEnds));
  } else {
    ::fidl::Decode(_decoder, &_value->client, _offset + 0);
    ::fidl::Decode(_decoder, &_value->server, _offset + 4);
    ::fidl::Decode(_decoder, &_value->client_opt, _offset + 8);
    ::fidl::Decode(_decoder, &_value->server_opt, _offset + 12);
  }
}

zx_status_t ProtocolEnds::Clone(ProtocolEnds* _result) const {
  zx_status_t _status = ::fidl::Clone(client, &_result->client);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(server, &_result->server);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(client_opt, &_result->client_opt);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(server_opt, &_result->server_opt);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;
const fidl_type_t* WithProtocolEndsStructContainingEndsTopResponse::FidlType = &test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;

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

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

zx_status_t WithProtocolEndsStructContainingEndsTopResponse::Clone(WithProtocolEndsStructContainingEndsTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(out, &_result->out);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsRequestTable;
const fidl_type_t* WithProtocolEndsStructContainingEndsRequest::FidlType = &test_protocols_WithProtocolEndsStructContainingEndsRequestTable;

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

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

zx_status_t WithProtocolEndsStructContainingEndsRequest::Clone(WithProtocolEndsStructContainingEndsRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(in, &_result->in);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodTopResponseTable;
const fidl_type_t* MethodWithUnionUnionMethodTopResponse::FidlType = &test_protocols_MethodWithUnionUnionMethodTopResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_ManyParametersFifteenRequestTable;
const fidl_type_t* ManyParametersFifteenRequest::FidlType = &test_protocols_ManyParametersFifteenRequestTable;

void ManyParametersFifteenRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                          cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ManyParametersFifteenRequest>::value) {
    memcpy(_encoder->template GetPtr<ManyParametersFifteenRequest>(_offset), this, sizeof(ManyParametersFifteenRequest));
  } else {
    ::fidl::Encode(_encoder, &p1, _offset + 0);
    ::fidl::Encode(_encoder, &p2, _offset + 1);
    ::fidl::Encode(_encoder, &p3, _offset + 2);
    ::fidl::Encode(_encoder, &p4, _offset + 3);
    ::fidl::Encode(_encoder, &p5, _offset + 4);
    ::fidl::Encode(_encoder, &p6, _offset + 5);
    ::fidl::Encode(_encoder, &p7, _offset + 6);
    ::fidl::Encode(_encoder, &p8, _offset + 7);
    ::fidl::Encode(_encoder, &p9, _offset + 8);
    ::fidl::Encode(_encoder, &p10, _offset + 9);
    ::fidl::Encode(_encoder, &p11, _offset + 10);
    ::fidl::Encode(_encoder, &p12, _offset + 11);
    ::fidl::Encode(_encoder, &p13, _offset + 12);
    ::fidl::Encode(_encoder, &p14, _offset + 13);
    ::fidl::Encode(_encoder, &p15, _offset + 14);
  }
}

void ManyParametersFifteenRequest::Decode(::fidl::Decoder* _decoder, ManyParametersFifteenRequest* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<ManyParametersFifteenRequest>::value) {
    memcpy(_value, _decoder->template GetPtr<ManyParametersFifteenRequest>(_offset), sizeof(ManyParametersFifteenRequest));
  } else {
    ::fidl::Decode(_decoder, &_value->p1, _offset + 0);
    ::fidl::Decode(_decoder, &_value->p2, _offset + 1);
    ::fidl::Decode(_decoder, &_value->p3, _offset + 2);
    ::fidl::Decode(_decoder, &_value->p4, _offset + 3);
    ::fidl::Decode(_decoder, &_value->p5, _offset + 4);
    ::fidl::Decode(_decoder, &_value->p6, _offset + 5);
    ::fidl::Decode(_decoder, &_value->p7, _offset + 6);
    ::fidl::Decode(_decoder, &_value->p8, _offset + 7);
    ::fidl::Decode(_decoder, &_value->p9, _offset + 8);
    ::fidl::Decode(_decoder, &_value->p10, _offset + 9);
    ::fidl::Decode(_decoder, &_value->p11, _offset + 10);
    ::fidl::Decode(_decoder, &_value->p12, _offset + 11);
    ::fidl::Decode(_decoder, &_value->p13, _offset + 12);
    ::fidl::Decode(_decoder, &_value->p14, _offset + 13);
    ::fidl::Decode(_decoder, &_value->p15, _offset + 14);
  }
}

zx_status_t ManyParametersFifteenRequest::Clone(ManyParametersFifteenRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(p1, &_result->p1);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p2, &_result->p2);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p3, &_result->p3);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p4, &_result->p4);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p5, &_result->p5);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p6, &_result->p6);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p7, &_result->p7);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p8, &_result->p8);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p9, &_result->p9);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p10, &_result->p10);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p11, &_result->p11);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p12, &_result->p12);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p13, &_result->p13);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p14, &_result->p14);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(p15, &_result->p15);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;
const fidl_type_t* HandleRightsProtocolResponseMethodTopResponse::FidlType = &test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;

void HandleRightsProtocolResponseMethodTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                           cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<HandleRightsProtocolResponseMethodTopResponse>::value) {
    memcpy(_encoder->template GetPtr<HandleRightsProtocolResponseMethodTopResponse>(_offset), this, sizeof(HandleRightsProtocolResponseMethodTopResponse));
  } else {
    ::fidl::Encode(_encoder, &h, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_SOCKET,
                                                  .rights = 0x2,
                                              });
  }
}

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

zx_status_t HandleRightsProtocolResponseMethodTopResponse::Clone(HandleRightsProtocolResponseMethodTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(h, &_result->h);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_HandleRightsProtocolResponseMethodRequestTable;
const fidl_type_t* HandleRightsProtocolResponseMethodRequest::FidlType = &test_protocols_HandleRightsProtocolResponseMethodRequestTable;

void HandleRightsProtocolResponseMethodRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                       cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<HandleRightsProtocolResponseMethodRequest>::value) {
    memcpy(_encoder->template GetPtr<HandleRightsProtocolResponseMethodRequest>(_offset), this, sizeof(HandleRightsProtocolResponseMethodRequest));
  } else {
    ::fidl::Encode(_encoder, &h, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_SOCKET,
                                                  .rights = 0x3,
                                              });
  }
}

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

zx_status_t HandleRightsProtocolResponseMethodRequest::Clone(HandleRightsProtocolResponseMethodRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(h, &_result->h);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;
const fidl_type_t* HandleRightsProtocolNoResponseMethodRequest::FidlType = &test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;

void HandleRightsProtocolNoResponseMethodRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<HandleRightsProtocolNoResponseMethodRequest>::value) {
    memcpy(_encoder->template GetPtr<HandleRightsProtocolNoResponseMethodRequest>(_offset), this, sizeof(HandleRightsProtocolNoResponseMethodRequest));
  } else {
    ::fidl::Encode(_encoder, &h, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_SOCKET,
                                                  .rights = 0x3,
                                              });
  }
}

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

zx_status_t HandleRightsProtocolNoResponseMethodRequest::Clone(HandleRightsProtocolNoResponseMethodRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(h, &_result->h);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_HandleRightsProtocolAnEventRequestTable;
const fidl_type_t* HandleRightsProtocolAnEventRequest::FidlType = &test_protocols_HandleRightsProtocolAnEventRequestTable;

void HandleRightsProtocolAnEventRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<HandleRightsProtocolAnEventRequest>::value) {
    memcpy(_encoder->template GetPtr<HandleRightsProtocolAnEventRequest>(_offset), this, sizeof(HandleRightsProtocolAnEventRequest));
  } else {
    ::fidl::Encode(_encoder, &h, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_SOCKET,
                                                  .rights = 0x3,
                                              });
  }
}

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

zx_status_t HandleRightsProtocolAnEventRequest::Clone(HandleRightsProtocolAnEventRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(h, &_result->h);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ErrorAsEnum_ResultTable;
const fidl_type_t* WithErrorSyntax_ErrorAsEnum_Result::FidlType = &test_protocols_WithErrorSyntax_ErrorAsEnum_ResultTable;

WithErrorSyntax_ErrorAsEnum_Result::WithErrorSyntax_ErrorAsEnum_Result() {}

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

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

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

WithErrorSyntax_ErrorAsEnum_Result WithErrorSyntax_ErrorAsEnum_Result::WithResponse(::test::protocols::WithErrorSyntax_ErrorAsEnum_Response&& val) {
  WithErrorSyntax_ErrorAsEnum_Result result;
  result.set_response(std::move(val));
  return result;
}
WithErrorSyntax_ErrorAsEnum_Result WithErrorSyntax_ErrorAsEnum_Result::WithErr(::test::protocols::ErrorEnum&& val) {
  WithErrorSyntax_ErrorAsEnum_Result result;
  result.set_err(std::move(val));
  return result;
}

void WithErrorSyntax_ErrorAsEnum_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::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_ErrorAsEnum_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_xunion_v2_t, envelope));

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

      ::fidl::Encode(
          encoder,
          &response_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::protocols::WithErrorSyntax_ErrorAsEnum_Response, ::fidl::Encoder>(encoder)));

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

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

      ::fidl::Encode(
          encoder,
          &err_,
          encoder->Alloc(::fidl::EncodingInlineSize<::test::protocols::ErrorEnum, ::fidl::Encoder>(encoder)));

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

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

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

  value->EnsureStorageInitialized(xunion->tag);

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

  switch (value->tag_) {
    case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kResponse: {
      new (&value->response_)::test::protocols::WithErrorSyntax_ErrorAsEnum_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kErr: {
      new (&value->err_)::test::protocols::ErrorEnum();
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
      break;
    }
  }
}

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

WithErrorSyntax_ErrorAsEnum_Result& WithErrorSyntax_ErrorAsEnum_Result::set_response(::test::protocols::WithErrorSyntax_ErrorAsEnum_Response value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

WithErrorSyntax_ErrorAsEnum_Result& WithErrorSyntax_ErrorAsEnum_Result::set_err(::test::protocols::ErrorEnum value) {
  EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void WithErrorSyntax_ErrorAsEnum_Result::Destroy() {
  switch (tag_) {
    case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kErr:
      err_.~decltype(err_)();
      break;

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

void WithErrorSyntax_ErrorAsEnum_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::Invalid):
        break;
      case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kResponse:
        new (&response_)::test::protocols::WithErrorSyntax_ErrorAsEnum_Response();
        break;
      case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kErr:
        new (&err_)::test::protocols::ErrorEnum();
        break;
      default:
        break;
    }
  }
}

extern "C" const fidl_type_t test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;
const fidl_type_t* WithErrorSyntaxErrorAsEnumTopResponse::FidlType = &test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;

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

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

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

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_ChannelProtocolTakeHandleRequestTable;
const fidl_type_t* ChannelProtocolTakeHandleRequest::FidlType = &test_protocols_ChannelProtocolTakeHandleRequestTable;

void ChannelProtocolTakeHandleRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                              cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ChannelProtocolTakeHandleRequest>::value) {
    memcpy(_encoder->template GetPtr<ChannelProtocolTakeHandleRequest>(_offset), this, sizeof(ChannelProtocolTakeHandleRequest));
  } else {
    ::fidl::Encode(_encoder, &h, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_NONE,
                                                  .rights = 0x80000000,
                                              });
  }
}

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

zx_status_t ChannelProtocolTakeHandleRequest::Clone(ChannelProtocolTakeHandleRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(h, &_result->h);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketTopResponseTable;
const fidl_type_t* ChannelProtocolMutateSocketTopResponse::FidlType = &test_protocols_ChannelProtocolMutateSocketTopResponseTable;

void ChannelProtocolMutateSocketTopResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                    cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ChannelProtocolMutateSocketTopResponse>::value) {
    memcpy(_encoder->template GetPtr<ChannelProtocolMutateSocketTopResponse>(_offset), this, sizeof(ChannelProtocolMutateSocketTopResponse));
  } else {
    ::fidl::Encode(_encoder, &b, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_SOCKET,
                                                  .rights = 0x80000000,
                                              });
  }
}

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

zx_status_t ChannelProtocolMutateSocketTopResponse::Clone(ChannelProtocolMutateSocketTopResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(b, &_result->b);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketRequestTable;
const fidl_type_t* ChannelProtocolMutateSocketRequest::FidlType = &test_protocols_ChannelProtocolMutateSocketRequestTable;

void ChannelProtocolMutateSocketRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ChannelProtocolMutateSocketRequest>::value) {
    memcpy(_encoder->template GetPtr<ChannelProtocolMutateSocketRequest>(_offset), this, sizeof(ChannelProtocolMutateSocketRequest));
  } else {
    ::fidl::Encode(_encoder, &a, _offset + 0, ::fidl::HandleInformation{
                                                  .object_type = ZX_OBJ_TYPE_SOCKET,
                                                  .rights = 0x80000000,
                                              });
  }
}

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

zx_status_t ChannelProtocolMutateSocketRequest::Clone(ChannelProtocolMutateSocketRequest* _result) const {
  zx_status_t _status = ::fidl::Clone(a, &_result->a);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}
#endif  // __Fuchsia__

extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodBTopResponseTable;
const fidl_type_t* ChannelProtocolMethodBTopResponse::FidlType = &test_protocols_ChannelProtocolMethodBTopResponseTable;

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

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

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

extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodBRequestTable;
const fidl_type_t* ChannelProtocolMethodBRequest::FidlType = &test_protocols_ChannelProtocolMethodBRequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodARequestTable;
const fidl_type_t* ChannelProtocolMethodARequest::FidlType = &test_protocols_ChannelProtocolMethodARequestTable;

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

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

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

extern "C" const fidl_type_t test_protocols_ChannelProtocolEventARequestTable;
const fidl_type_t* ChannelProtocolEventARequest::FidlType = &test_protocols_ChannelProtocolEventARequestTable;

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

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

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

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

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;

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

const fidl_type_t* ::test::protocols::WithAndWithoutRequestResponse_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal:
      return nullptr;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* WithAndWithoutRequestResponse_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
      return nullptr;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
      return nullptr;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal:
      return nullptr;
      ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_OnWithResponse_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;
      ;
    default:
      return nullptr;
  }
}

WithAndWithoutRequestResponse_EventSender::~WithAndWithoutRequestResponse_EventSender() = default;

WithAndWithoutRequestResponse_Sync::~WithAndWithoutRequestResponse_Sync() = default;

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

WithAndWithoutRequestResponse_Proxy::~WithAndWithoutRequestResponse_Proxy() = default;

zx_status_t WithAndWithoutRequestResponse_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal: {
      if (!OnEmptyResponse) {
        status = ZX_OK;
        break;
      }
      OnEmptyResponse();
      break;
    }
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_OnWithResponse_Ordinal: {
      if (!OnWithResponse) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnWithResponse(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

void WithAndWithoutRequestResponse_Proxy::NoRequestNoResponse() {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::NoRequestNoResponse(&_encoder), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithAndWithoutRequestResponse_NoRequestEmptyResponse_ResponseHandler(WithAndWithoutRequestResponse::NoRequestEmptyResponseCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithAndWithoutRequestResponse::NoRequestEmptyResponse\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        callback_();
        return ZX_OK;
      },
      nullptr);
}

}  // namespace
void WithAndWithoutRequestResponse_Proxy::NoRequestEmptyResponse(NoRequestEmptyResponseCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::NoRequestEmptyResponse(&_encoder), WithAndWithoutRequestResponse_NoRequestEmptyResponse_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithAndWithoutRequestResponse_NoRequestWithResponse_ResponseHandler(WithAndWithoutRequestResponse::NoRequestWithResponseCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithAndWithoutRequestResponse::NoRequestWithResponse\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable);
}

}  // namespace
void WithAndWithoutRequestResponse_Proxy::NoRequestWithResponse(NoRequestWithResponseCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::NoRequestWithResponse(&_encoder), WithAndWithoutRequestResponse_NoRequestWithResponse_ResponseHandler(std::move(callback)));
}
void WithAndWithoutRequestResponse_Proxy::WithRequestNoResponse(::std::string arg) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
  controller_->Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::WithRequestNoResponse(&_encoder, &arg), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithAndWithoutRequestResponse_WithRequestEmptyResponse_ResponseHandler(WithAndWithoutRequestResponse::WithRequestEmptyResponseCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithAndWithoutRequestResponse::WithRequestEmptyResponse\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        callback_();
        return ZX_OK;
      },
      nullptr);
}

}  // namespace
void WithAndWithoutRequestResponse_Proxy::WithRequestEmptyResponse(::std::string arg, WithRequestEmptyResponseCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
  controller_->Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::WithRequestEmptyResponse(&_encoder, &arg), WithAndWithoutRequestResponse_WithRequestEmptyResponse_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithAndWithoutRequestResponse_WithRequestWithResponse_ResponseHandler(WithAndWithoutRequestResponse::WithRequestWithResponseCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithAndWithoutRequestResponse::WithRequestWithResponse\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable);
}

}  // namespace
void WithAndWithoutRequestResponse_Proxy::WithRequestWithResponse(::std::string arg, WithRequestWithResponseCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
  controller_->Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::WithRequestWithResponse(&_encoder, &arg), WithAndWithoutRequestResponse_WithRequestWithResponse_ResponseHandler(std::move(callback)));
}

WithAndWithoutRequestResponse_Stub::WithAndWithoutRequestResponse_Stub(::test::protocols::WithAndWithoutRequestResponse_Stub::WithAndWithoutRequestResponse_clazz* impl) : impl_(impl) {
  (void)impl_;
}

WithAndWithoutRequestResponse_Stub::~WithAndWithoutRequestResponse_Stub() = default;

namespace {

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

  void operator()() {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_DynamicFlags);
    const fidl_type_t* resp_type = nullptr;
    response_.Send(resp_type, ::test::protocols::WithAndWithoutRequestResponse_ResponseEncoder::NoRequestEmptyResponse(&_encoder));
  }

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

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

  void operator()(::std::string ret) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithAndWithoutRequestResponse_ResponseEncoder::NoRequestWithResponse(&_encoder, &ret));
  }

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

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

  void operator()() {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_DynamicFlags);
    const fidl_type_t* resp_type = nullptr;
    response_.Send(resp_type, ::test::protocols::WithAndWithoutRequestResponse_ResponseEncoder::WithRequestEmptyResponse(&_encoder));
  }

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

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

  void operator()(::std::string ret) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithAndWithoutRequestResponse_ResponseEncoder::WithRequestWithResponse(&_encoder, &ret));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal: {
      impl_->NoRequestNoResponse();
      break;
    }
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal: {
      impl_->NoRequestEmptyResponse(WithAndWithoutRequestResponse_NoRequestEmptyResponse_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal: {
      impl_->NoRequestWithResponse(WithAndWithoutRequestResponse_NoRequestWithResponse_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->WithRequestNoResponse(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->WithRequestEmptyResponse(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)), WithAndWithoutRequestResponse_WithRequestEmptyResponse_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->WithRequestWithResponse(::fidl::DecodeAs<::std::string>(&decoder, 0 + sizeof(fidl_message_header_t)), WithAndWithoutRequestResponse_WithRequestWithResponse_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}
void WithAndWithoutRequestResponse_Stub::OnEmptyResponse() {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_OnEmptyResponse_DynamicFlags);
  const fidl_type_t* resp_type = nullptr;
  sender_()->Send(resp_type, ::test::protocols::WithAndWithoutRequestResponse_ResponseEncoder::OnEmptyResponse(&_encoder));
}
void WithAndWithoutRequestResponse_Stub::OnWithResponse(::std::string ret) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_OnWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_OnWithResponse_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;
  sender_()->Send(resp_type, ::test::protocols::WithAndWithoutRequestResponse_ResponseEncoder::OnWithResponse(&_encoder, &ret));
}

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

WithAndWithoutRequestResponse_SyncProxy::~WithAndWithoutRequestResponse_SyncProxy() = default;

zx_status_t WithAndWithoutRequestResponse_SyncProxy::NoRequestNoResponse() {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  return proxy_.Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::NoRequestNoResponse(&_encoder));
}

zx_status_t WithAndWithoutRequestResponse_SyncProxy::NoRequestEmptyResponse() {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_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::protocols::WithAndWithoutRequestResponse_RequestEncoder::NoRequestEmptyResponse(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  return ZX_OK;
}

zx_status_t WithAndWithoutRequestResponse_SyncProxy::NoRequestWithResponse(::std::string* out_ret) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::NoRequestWithResponse(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ret = ::fidl::DecodeAs<::std::string>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t WithAndWithoutRequestResponse_SyncProxy::WithRequestNoResponse(::std::string arg) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
  return proxy_.Send(req_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::WithRequestNoResponse(&_encoder, &arg));
}

zx_status_t WithAndWithoutRequestResponse_SyncProxy::WithRequestEmptyResponse(::std::string arg) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
  const fidl_type_t* resp_type = nullptr;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::WithRequestEmptyResponse(&_encoder, &arg), &response_);
  if (status_ != ZX_OK)
    return status_;
  return ZX_OK;
}

zx_status_t WithAndWithoutRequestResponse_SyncProxy::WithRequestWithResponse(::std::string arg, ::std::string* out_ret) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal, ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithAndWithoutRequestResponse_RequestEncoder::WithRequestWithResponse(&_encoder, &arg), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ret = ::fidl::DecodeAs<::std::string>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalRequestRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalRequestTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalOneWayRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalEventRequestTable;

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

const fidl_type_t* ::test::protocols::Transitional_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kTransitional_Request_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_TransitionalRequestRequestTable;
      ;
    case ::test::protocols::internal::kTransitional_OneWay_Ordinal:
      return &::test::protocols::_internal::test_protocols_TransitionalOneWayRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* Transitional_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kTransitional_Request_Ordinal:
      return &::test::protocols::_internal::test_protocols_TransitionalRequestTopResponseTable;
      ;
    case ::test::protocols::internal::kTransitional_Event_Ordinal:
      return &::test::protocols::_internal::test_protocols_TransitionalEventRequestTable;
      ;
    default:
      return nullptr;
  }
}

Transitional_EventSender::~Transitional_EventSender() = default;

Transitional_Sync::~Transitional_Sync() = default;

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

Transitional_Proxy::~Transitional_Proxy() = default;

zx_status_t Transitional_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocols::internal::kTransitional_Event_Ordinal: {
      if (!Event) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocols::_internal::test_protocols_TransitionalEventRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocols::_internal::test_protocols_TransitionalEventRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      Event(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
Transitional_Request_ResponseHandler(Transitional::RequestCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for Transitional::Request\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_TransitionalRequestTopResponseTable);
}

}  // namespace
void Transitional_Proxy::Request(int64_t x, RequestCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kTransitional_Request_Ordinal, ::test::protocols::internal::kTransitional_Request_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_TransitionalRequestRequestTable;
  controller_->Send(req_type, ::test::protocols::Transitional_RequestEncoder::Request(&_encoder, &x), Transitional_Request_ResponseHandler(std::move(callback)));
}
void Transitional_Proxy::OneWay(int64_t x) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kTransitional_OneWay_Ordinal, ::test::protocols::internal::kTransitional_OneWay_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_TransitionalOneWayRequestTable;
  controller_->Send(req_type, ::test::protocols::Transitional_RequestEncoder::OneWay(&_encoder, &x), nullptr);
}

Transitional_Stub::Transitional_Stub(::test::protocols::Transitional_Stub::Transitional_clazz* impl) : impl_(impl) {
  (void)impl_;
}

Transitional_Stub::~Transitional_Stub() = default;

namespace {

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

  void operator()(int64_t y) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kTransitional_Request_Ordinal, ::test::protocols::internal::kTransitional_Request_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_TransitionalRequestTopResponseTable;
    response_.Send(resp_type, ::test::protocols::Transitional_ResponseEncoder::Request(&_encoder, &y));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kTransitional_Request_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->Request(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)), Transitional_Request_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kTransitional_OneWay_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWay(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}
void Transitional_Stub::Event(int64_t x) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kTransitional_Event_Ordinal, ::test::protocols::internal::kTransitional_Event_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_TransitionalEventRequestTable;
  sender_()->Send(resp_type, ::test::protocols::Transitional_ResponseEncoder::Event(&_encoder, &x));
}

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

Transitional_SyncProxy::~Transitional_SyncProxy() = default;

zx_status_t Transitional_SyncProxy::Request(int64_t x, int64_t* out_y) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kTransitional_Request_Ordinal, ::test::protocols::internal::kTransitional_Request_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_TransitionalRequestRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_TransitionalRequestTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::Transitional_RequestEncoder::Request(&_encoder, &x), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_y = ::fidl::DecodeAs<int64_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t Transitional_SyncProxy::OneWay(int64_t x) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kTransitional_OneWay_Ordinal, ::test::protocols::internal::kTransitional_OneWay_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_TransitionalOneWayRequestTable;
  return proxy_.Send(req_type, ::test::protocols::Transitional_RequestEncoder::OneWay(&_encoder, &x));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;

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

const fidl_type_t* ::test::protocols::WithProtocolEnds_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsRequestTable;
      ;
    case ::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsRequestTable;
      ;
    case ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* WithProtocolEnds_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsTopResponseTable;
      ;
    case ::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsTopResponseTable;
      ;
    case ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

WithProtocolEnds_EventSender::~WithProtocolEnds_EventSender() = default;

WithProtocolEnds_Sync::~WithProtocolEnds_Sync() = default;

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

WithProtocolEnds_Proxy::~WithProtocolEnds_Proxy() = default;

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

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithProtocolEnds_ClientEnds_ResponseHandler(WithProtocolEnds::ClientEndsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithProtocolEnds::ClientEnds\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsTopResponseTable);
}

}  // namespace
void WithProtocolEnds_Proxy::ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in, ClientEndsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_ClientEnds_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsRequestTable;
  controller_->Send(req_type, ::test::protocols::WithProtocolEnds_RequestEncoder::ClientEnds(&_encoder, &in), WithProtocolEnds_ClientEnds_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithProtocolEnds_ServerEnds_ResponseHandler(WithProtocolEnds::ServerEndsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithProtocolEnds::ServerEnds\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsTopResponseTable);
}

}  // namespace
void WithProtocolEnds_Proxy::ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in, ServerEndsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_ServerEnds_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsRequestTable;
  controller_->Send(req_type, ::test::protocols::WithProtocolEnds_RequestEncoder::ServerEnds(&_encoder, &in), WithProtocolEnds_ServerEnds_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithProtocolEnds_StructContainingEnds_ResponseHandler(WithProtocolEnds::StructContainingEndsCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithProtocolEnds::StructContainingEnds\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::protocols::ProtocolEnds>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable);
}

}  // namespace
void WithProtocolEnds_Proxy::StructContainingEnds(::test::protocols::ProtocolEnds in, StructContainingEndsCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsRequestTable;
  controller_->Send(req_type, ::test::protocols::WithProtocolEnds_RequestEncoder::StructContainingEnds(&_encoder, &in), WithProtocolEnds_StructContainingEnds_ResponseHandler(std::move(callback)));
}

WithProtocolEnds_Stub::WithProtocolEnds_Stub(::test::protocols::WithProtocolEnds_Stub::WithProtocolEnds_clazz* impl) : impl_(impl) {
  (void)impl_;
}

WithProtocolEnds_Stub::~WithProtocolEnds_Stub() = default;

namespace {

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

  void operator()(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> out) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_ClientEnds_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithProtocolEnds_ResponseEncoder::ClientEnds(&_encoder, &out));
  }

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

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

  void operator()(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> out) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_ServerEnds_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithProtocolEnds_ResponseEncoder::ServerEnds(&_encoder, &out));
  }

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

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

  void operator()(::test::protocols::ProtocolEnds out) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithProtocolEnds_ResponseEncoder::StructContainingEnds(&_encoder, &out));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->ClientEnds(::fidl::DecodeAs<::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>>(&decoder, 0 + sizeof(fidl_message_header_t)), WithProtocolEnds_ClientEnds_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->ServerEnds(::fidl::DecodeAs<::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>>(&decoder, 0 + sizeof(fidl_message_header_t)), WithProtocolEnds_ServerEnds_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->StructContainingEnds(::fidl::DecodeAs<::test::protocols::ProtocolEnds>(&decoder, 0 + sizeof(fidl_message_header_t)), WithProtocolEnds_StructContainingEnds_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

WithProtocolEnds_SyncProxy::~WithProtocolEnds_SyncProxy() = default;

zx_status_t WithProtocolEnds_SyncProxy::ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in, ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>* out_out) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_ClientEnds_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithProtocolEnds_RequestEncoder::ClientEnds(&_encoder, &in), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_out = ::fidl::DecodeAs<::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t WithProtocolEnds_SyncProxy::ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in, ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>* out_out) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_ServerEnds_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithProtocolEnds_RequestEncoder::ServerEnds(&_encoder, &in), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_out = ::fidl::DecodeAs<::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t WithProtocolEnds_SyncProxy::StructContainingEnds(::test::protocols::ProtocolEnds in, ::test::protocols::ProtocolEnds* out_out) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal, ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithProtocolEnds_RequestEncoder::StructContainingEnds(&_encoder, &in), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_out = ::fidl::DecodeAs<::test::protocols::ProtocolEnds>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodTopResponseTable;

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

const fidl_type_t* ::test::protocols::MethodWithUnion_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* MethodWithUnion_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal:
      return &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

MethodWithUnion_EventSender::~MethodWithUnion_EventSender() = default;

MethodWithUnion_Sync::~MethodWithUnion_Sync() = default;

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

MethodWithUnion_Proxy::~MethodWithUnion_Proxy() = default;

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

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MethodWithUnion_UnionMethod_ResponseHandler(MethodWithUnion::UnionMethodCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MethodWithUnion::UnionMethod\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::std::unique_ptr<::test::protocols::TheUnion>>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodTopResponseTable);
}

}  // namespace
void MethodWithUnion_Proxy::UnionMethod(::test::protocols::TheUnion u, UnionMethodCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal, ::test::protocols::internal::kMethodWithUnion_UnionMethod_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodRequestTable;
  controller_->Send(req_type, ::test::protocols::MethodWithUnion_RequestEncoder::UnionMethod(&_encoder, &u), MethodWithUnion_UnionMethod_ResponseHandler(std::move(callback)));
}

MethodWithUnion_Stub::MethodWithUnion_Stub(::test::protocols::MethodWithUnion_Stub::MethodWithUnion_clazz* impl) : impl_(impl) {
  (void)impl_;
}

MethodWithUnion_Stub::~MethodWithUnion_Stub() = default;

namespace {

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

  void operator()(::std::unique_ptr<::test::protocols::TheUnion> u) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal, ::test::protocols::internal::kMethodWithUnion_UnionMethod_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodTopResponseTable;
    response_.Send(resp_type, ::test::protocols::MethodWithUnion_ResponseEncoder::UnionMethod(&_encoder, &u));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->UnionMethod(::fidl::DecodeAs<::test::protocols::TheUnion>(&decoder, 0 + sizeof(fidl_message_header_t)), MethodWithUnion_UnionMethod_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

MethodWithUnion_SyncProxy::~MethodWithUnion_SyncProxy() = default;

zx_status_t MethodWithUnion_SyncProxy::UnionMethod(::test::protocols::TheUnion u, ::std::unique_ptr<::test::protocols::TheUnion>* out_u) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal, ::test::protocols::internal::kMethodWithUnion_UnionMethod_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_MethodWithUnionUnionMethodTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::MethodWithUnion_RequestEncoder::UnionMethod(&_encoder, &u), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_u = ::fidl::DecodeAs<::std::unique_ptr<::test::protocols::TheUnion>>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

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

const fidl_type_t* ::test::protocols::ManyParameters_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kManyParameters_Fifteen_Ordinal:
      return &::test::protocols::_internal::test_protocols_ManyParametersFifteenRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* ManyParameters_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    default:
      return nullptr;
  }
}

ManyParameters_EventSender::~ManyParameters_EventSender() = default;

ManyParameters_Sync::~ManyParameters_Sync() = default;

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

ManyParameters_Proxy::~ManyParameters_Proxy() = default;

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

void ManyParameters_Proxy::Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kManyParameters_Fifteen_Ordinal, ::test::protocols::internal::kManyParameters_Fifteen_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ManyParametersFifteenRequestTable;
  controller_->Send(req_type, ::test::protocols::ManyParameters_RequestEncoder::Fifteen(&_encoder, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10, &p11, &p12, &p13, &p14, &p15), nullptr);
}

ManyParameters_Stub::ManyParameters_Stub(::test::protocols::ManyParameters_Stub::ManyParameters_clazz* impl) : impl_(impl) {
  (void)impl_;
}

ManyParameters_Stub::~ManyParameters_Stub() = default;

namespace {

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kManyParameters_Fifteen_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->Fifteen(::fidl::DecodeAs<bool>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 1 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 2 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 3 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 4 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 5 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 6 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 7 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 8 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 9 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 10 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 11 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 12 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 13 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<bool>(&decoder, 14 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

ManyParameters_SyncProxy::~ManyParameters_SyncProxy() = default;

zx_status_t ManyParameters_SyncProxy::Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kManyParameters_Fifteen_Ordinal, ::test::protocols::internal::kManyParameters_Fifteen_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ManyParametersFifteenRequestTable;
  return proxy_.Send(req_type, ::test::protocols::ManyParameters_RequestEncoder::Fifteen(&_encoder, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10, &p11, &p12, &p13, &p14, &p15));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolResponseMethodRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolAnEventRequestTable;

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

const fidl_type_t* ::test::protocols::HandleRightsProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_Ordinal:
      return &::test::protocols::_internal::test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;
      ;
    case ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* HandleRightsProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal:
      return &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;
      ;
    case ::test::protocols::internal::kHandleRightsProtocol_AnEvent_Ordinal:
      return &::test::protocols::_internal::test_protocols_HandleRightsProtocolAnEventRequestTable;
      ;
    default:
      return nullptr;
  }
}

HandleRightsProtocol_EventSender::~HandleRightsProtocol_EventSender() = default;

HandleRightsProtocol_Sync::~HandleRightsProtocol_Sync() = default;

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

HandleRightsProtocol_Proxy::~HandleRightsProtocol_Proxy() = default;

zx_status_t HandleRightsProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocols::internal::kHandleRightsProtocol_AnEvent_Ordinal: {
      if (!AnEvent) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocols::_internal::test_protocols_HandleRightsProtocolAnEventRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocols::_internal::test_protocols_HandleRightsProtocolAnEventRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      AnEvent(::fidl::DecodeAs<::zx::socket>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

void HandleRightsProtocol_Proxy::NoResponseMethod(::zx::socket h) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_Ordinal, ::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;
  controller_->Send(req_type, ::test::protocols::HandleRightsProtocol_RequestEncoder::NoResponseMethod(&_encoder, &h), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
HandleRightsProtocol_ResponseMethod_ResponseHandler(HandleRightsProtocol::ResponseMethodCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for HandleRightsProtocol::ResponseMethod\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::zx::socket>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodTopResponseTable);
}

}  // namespace
void HandleRightsProtocol_Proxy::ResponseMethod(::zx::socket h, ResponseMethodCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal, ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodRequestTable;
  controller_->Send(req_type, ::test::protocols::HandleRightsProtocol_RequestEncoder::ResponseMethod(&_encoder, &h), HandleRightsProtocol_ResponseMethod_ResponseHandler(std::move(callback)));
}

HandleRightsProtocol_Stub::HandleRightsProtocol_Stub(::test::protocols::HandleRightsProtocol_Stub::HandleRightsProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

HandleRightsProtocol_Stub::~HandleRightsProtocol_Stub() = default;

namespace {

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

  void operator()(::zx::socket h) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal, ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;
    response_.Send(resp_type, ::test::protocols::HandleRightsProtocol_ResponseEncoder::ResponseMethod(&_encoder, &h));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->NoResponseMethod(::fidl::DecodeAs<::zx::socket>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->ResponseMethod(::fidl::DecodeAs<::zx::socket>(&decoder, 0 + sizeof(fidl_message_header_t)), HandleRightsProtocol_ResponseMethod_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}
void HandleRightsProtocol_Stub::AnEvent(::zx::socket h) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kHandleRightsProtocol_AnEvent_Ordinal, ::test::protocols::internal::kHandleRightsProtocol_AnEvent_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolAnEventRequestTable;
  sender_()->Send(resp_type, ::test::protocols::HandleRightsProtocol_ResponseEncoder::AnEvent(&_encoder, &h));
}

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

HandleRightsProtocol_SyncProxy::~HandleRightsProtocol_SyncProxy() = default;

zx_status_t HandleRightsProtocol_SyncProxy::NoResponseMethod(::zx::socket h) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_Ordinal, ::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;
  return proxy_.Send(req_type, ::test::protocols::HandleRightsProtocol_RequestEncoder::NoResponseMethod(&_encoder, &h));
}

zx_status_t HandleRightsProtocol_SyncProxy::ResponseMethod(::zx::socket h, ::zx::socket* out_h) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal, ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::HandleRightsProtocol_RequestEncoder::ResponseMethod(&_encoder, &h), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_h = ::fidl::DecodeAs<::zx::socket>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;

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

const fidl_type_t* ::test::protocols::WithErrorSyntax_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal:
      *out_needs_response = true;
      return nullptr;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* WithErrorSyntax_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable;
      ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;
      ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;
      ;
    case ::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

WithErrorSyntax_EventSender::~WithErrorSyntax_EventSender() = default;

WithErrorSyntax_Sync::~WithErrorSyntax_Sync() = default;

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

WithErrorSyntax_Proxy::~WithErrorSyntax_Proxy() = default;

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

namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithErrorSyntax_ResponseAsStruct_ResponseHandler(WithErrorSyntax::ResponseAsStructCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithErrorSyntax::ResponseAsStruct\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::protocols::WithErrorSyntax_ResponseAsStruct_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable);
}

}  // namespace
void WithErrorSyntax_Proxy::ResponseAsStruct(ResponseAsStructCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithErrorSyntax_RequestEncoder::ResponseAsStruct(&_encoder), WithErrorSyntax_ResponseAsStruct_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithErrorSyntax_ErrorAsPrimitive_ResponseHandler(WithErrorSyntax::ErrorAsPrimitiveCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithErrorSyntax::ErrorAsPrimitive\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::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable);
}

}  // namespace
void WithErrorSyntax_Proxy::ErrorAsPrimitive(ErrorAsPrimitiveCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithErrorSyntax_RequestEncoder::ErrorAsPrimitive(&_encoder), WithErrorSyntax_ErrorAsPrimitive_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithErrorSyntax_ErrorAsEnum_ResponseHandler(WithErrorSyntax::ErrorAsEnumCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithErrorSyntax::ErrorAsEnum\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::protocols::WithErrorSyntax_ErrorAsEnum_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable);
}

}  // namespace
void WithErrorSyntax_Proxy::ErrorAsEnum(ErrorAsEnumCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithErrorSyntax_RequestEncoder::ErrorAsEnum(&_encoder), WithErrorSyntax_ErrorAsEnum_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
WithErrorSyntax_HandleInResult_ResponseHandler(WithErrorSyntax::HandleInResultCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for WithErrorSyntax::HandleInResult\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::protocols::WithErrorSyntax_HandleInResult_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_WithErrorSyntaxHandleInResultTopResponseTable);
}

}  // namespace
void WithErrorSyntax_Proxy::HandleInResult(HandleInResultCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal, ::test::protocols::internal::kWithErrorSyntax_HandleInResult_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::WithErrorSyntax_RequestEncoder::HandleInResult(&_encoder), WithErrorSyntax_HandleInResult_ResponseHandler(std::move(callback)));
}

WithErrorSyntax_Stub::WithErrorSyntax_Stub(::test::protocols::WithErrorSyntax_Stub::WithErrorSyntax_clazz* impl) : impl_(impl) {
  (void)impl_;
}

WithErrorSyntax_Stub::~WithErrorSyntax_Stub() = default;

namespace {

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

  void operator()(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result result) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::ResponseAsStruct(&_encoder, &result));
  }

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

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

  void operator()(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result result) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::ErrorAsPrimitive(&_encoder, &result));
  }

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

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

  void operator()(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result result) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::ErrorAsEnum(&_encoder, &result));
  }

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

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

  void operator()(::test::protocols::WithErrorSyntax_HandleInResult_Result result) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal, ::test::protocols::internal::kWithErrorSyntax_HandleInResult_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::HandleInResult(&_encoder, &result));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal: {
      impl_->ResponseAsStruct(WithErrorSyntax_ResponseAsStruct_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal: {
      impl_->ErrorAsPrimitive(WithErrorSyntax_ErrorAsPrimitive_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal: {
      impl_->ErrorAsEnum(WithErrorSyntax_ErrorAsEnum_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal: {
      impl_->HandleInResult(WithErrorSyntax_HandleInResult_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

WithErrorSyntax_SyncProxy::~WithErrorSyntax_SyncProxy() = default;

zx_status_t WithErrorSyntax_SyncProxy::ResponseAsStruct(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result* out_result) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithErrorSyntax_RequestEncoder::ResponseAsStruct(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_result = ::fidl::DecodeAs<::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t WithErrorSyntax_SyncProxy::ErrorAsPrimitive(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result* out_result) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithErrorSyntax_RequestEncoder::ErrorAsPrimitive(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_result = ::fidl::DecodeAs<::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t WithErrorSyntax_SyncProxy::ErrorAsEnum(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* out_result) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal, ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithErrorSyntax_RequestEncoder::ErrorAsEnum(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_result = ::fidl::DecodeAs<::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t WithErrorSyntax_SyncProxy::HandleInResult(::test::protocols::WithErrorSyntax_HandleInResult_Result* out_result) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal, ::test::protocols::internal::kWithErrorSyntax_HandleInResult_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::WithErrorSyntax_RequestEncoder::HandleInResult(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_result = ::fidl::DecodeAs<::test::protocols::WithErrorSyntax_HandleInResult_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

DiscoverableProtocol::~DiscoverableProtocol() = default;
const char DiscoverableProtocol::Name_[] = "test.protocols.DiscoverableProtocol";

const fidl_type_t* ::test::protocols::DiscoverableProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kDiscoverableProtocol_Method_Ordinal:
      return nullptr;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* DiscoverableProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    default:
      return nullptr;
  }
}

DiscoverableProtocol_EventSender::~DiscoverableProtocol_EventSender() = default;

DiscoverableProtocol_Sync::~DiscoverableProtocol_Sync() = default;

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

DiscoverableProtocol_Proxy::~DiscoverableProtocol_Proxy() = default;

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

void DiscoverableProtocol_Proxy::Method() {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kDiscoverableProtocol_Method_Ordinal, ::test::protocols::internal::kDiscoverableProtocol_Method_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocols::DiscoverableProtocol_RequestEncoder::Method(&_encoder), nullptr);
}

DiscoverableProtocol_Stub::DiscoverableProtocol_Stub(::test::protocols::DiscoverableProtocol_Stub::DiscoverableProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

DiscoverableProtocol_Stub::~DiscoverableProtocol_Stub() = default;

namespace {

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kDiscoverableProtocol_Method_Ordinal: {
      impl_->Method();
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

DiscoverableProtocol_SyncProxy::~DiscoverableProtocol_SyncProxy() = default;

zx_status_t DiscoverableProtocol_SyncProxy::Method() {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kDiscoverableProtocol_Method_Ordinal, ::test::protocols::internal::kDiscoverableProtocol_Method_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  return proxy_.Send(req_type, ::test::protocols::DiscoverableProtocol_RequestEncoder::Method(&_encoder));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolEventARequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodBRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodBTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolTakeHandleRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketTopResponseTable;

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

const fidl_type_t* ::test::protocols::ChannelProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    case ::test::protocols::internal::kChannelProtocol_MethodA_Ordinal:
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMethodARequestTable;
      ;
    case ::test::protocols::internal::kChannelProtocol_MethodB_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBRequestTable;
      ;
    case ::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_ChannelProtocolTakeHandleRequestTable;
      ;
    case ::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal:
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* ChannelProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocols::internal::kChannelProtocol_EventA_Ordinal:
      return &::test::protocols::_internal::test_protocols_ChannelProtocolEventARequestTable;
      ;
    case ::test::protocols::internal::kChannelProtocol_MethodB_Ordinal:
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBTopResponseTable;
      ;
    case ::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal:
      return nullptr;
      ;
    case ::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal:
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketTopResponseTable;
      ;
    default:
      return nullptr;
  }
}

ChannelProtocol_EventSender::~ChannelProtocol_EventSender() = default;

ChannelProtocol_Sync::~ChannelProtocol_Sync() = default;

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

ChannelProtocol_Proxy::~ChannelProtocol_Proxy() = default;

zx_status_t ChannelProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocols::internal::kChannelProtocol_EventA_Ordinal: {
      if (!EventA) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocols::_internal::test_protocols_ChannelProtocolEventARequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocols::_internal::test_protocols_ChannelProtocolEventARequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      EventA(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<int64_t>(&decoder, 8 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

void ChannelProtocol_Proxy::MethodA(int64_t a, int64_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MethodA_Ordinal, ::test::protocols::internal::kChannelProtocol_MethodA_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMethodARequestTable;
  controller_->Send(req_type, ::test::protocols::ChannelProtocol_RequestEncoder::MethodA(&_encoder, &a, &b), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ChannelProtocol_MethodB_ResponseHandler(ChannelProtocol::MethodBCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ChannelProtocol::MethodB\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBTopResponseTable);
}

}  // namespace
void ChannelProtocol_Proxy::MethodB(int64_t a, int64_t b, MethodBCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MethodB_Ordinal, ::test::protocols::internal::kChannelProtocol_MethodB_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBRequestTable;
  controller_->Send(req_type, ::test::protocols::ChannelProtocol_RequestEncoder::MethodB(&_encoder, &a, &b), ChannelProtocol_MethodB_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ChannelProtocol_TakeHandle_ResponseHandler(ChannelProtocol::TakeHandleCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ChannelProtocol::TakeHandle\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        callback_();
        return ZX_OK;
      },
      nullptr);
}

}  // namespace
void ChannelProtocol_Proxy::TakeHandle(::zx::handle h, TakeHandleCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal, ::test::protocols::internal::kChannelProtocol_TakeHandle_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolTakeHandleRequestTable;
  controller_->Send(req_type, ::test::protocols::ChannelProtocol_RequestEncoder::TakeHandle(&_encoder, &h), ChannelProtocol_TakeHandle_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ChannelProtocol_MutateSocket_ResponseHandler(ChannelProtocol::MutateSocketCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ChannelProtocol::MutateSocket\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::zx::socket>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketTopResponseTable);
}

}  // namespace
void ChannelProtocol_Proxy::MutateSocket(::zx::socket a, MutateSocketCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal, ::test::protocols::internal::kChannelProtocol_MutateSocket_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketRequestTable;
  controller_->Send(req_type, ::test::protocols::ChannelProtocol_RequestEncoder::MutateSocket(&_encoder, &a), ChannelProtocol_MutateSocket_ResponseHandler(std::move(callback)));
}

ChannelProtocol_Stub::ChannelProtocol_Stub(::test::protocols::ChannelProtocol_Stub::ChannelProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

ChannelProtocol_Stub::~ChannelProtocol_Stub() = default;

namespace {

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

  void operator()(int64_t result) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MethodB_Ordinal, ::test::protocols::internal::kChannelProtocol_MethodB_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBTopResponseTable;
    response_.Send(resp_type, ::test::protocols::ChannelProtocol_ResponseEncoder::MethodB(&_encoder, &result));
  }

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

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

  void operator()() {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal, ::test::protocols::internal::kChannelProtocol_TakeHandle_DynamicFlags);
    const fidl_type_t* resp_type = nullptr;
    response_.Send(resp_type, ::test::protocols::ChannelProtocol_ResponseEncoder::TakeHandle(&_encoder));
  }

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

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

  void operator()(::zx::socket b) {
    ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal, ::test::protocols::internal::kChannelProtocol_MutateSocket_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketTopResponseTable;
    response_.Send(resp_type, ::test::protocols::ChannelProtocol_ResponseEncoder::MutateSocket(&_encoder, &b));
  }

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

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kChannelProtocol_MethodA_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->MethodA(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<int64_t>(&decoder, 8 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocols::internal::kChannelProtocol_MethodB_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->MethodB(::fidl::DecodeAs<int64_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<int64_t>(&decoder, 8 + sizeof(fidl_message_header_t)), ChannelProtocol_MethodB_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TakeHandle(::fidl::DecodeAs<::zx::handle>(&decoder, 0 + sizeof(fidl_message_header_t)), ChannelProtocol_TakeHandle_Responder(std::move(response)));
      break;
    }
    case ::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->MutateSocket(::fidl::DecodeAs<::zx::socket>(&decoder, 0 + sizeof(fidl_message_header_t)), ChannelProtocol_MutateSocket_Responder(std::move(response)));
      break;
    }
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}
void ChannelProtocol_Stub::EventA(int64_t a, int64_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_EventA_Ordinal, ::test::protocols::internal::kChannelProtocol_EventA_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_ChannelProtocolEventARequestTable;
  sender_()->Send(resp_type, ::test::protocols::ChannelProtocol_ResponseEncoder::EventA(&_encoder, &a, &b));
}

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

ChannelProtocol_SyncProxy::~ChannelProtocol_SyncProxy() = default;

zx_status_t ChannelProtocol_SyncProxy::MethodA(int64_t a, int64_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MethodA_Ordinal, ::test::protocols::internal::kChannelProtocol_MethodA_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMethodARequestTable;
  return proxy_.Send(req_type, ::test::protocols::ChannelProtocol_RequestEncoder::MethodA(&_encoder, &a, &b));
}

zx_status_t ChannelProtocol_SyncProxy::MethodB(int64_t a, int64_t b, int64_t* out_result) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MethodB_Ordinal, ::test::protocols::internal::kChannelProtocol_MethodB_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::ChannelProtocol_RequestEncoder::MethodB(&_encoder, &a, &b), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_result = ::fidl::DecodeAs<int64_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t ChannelProtocol_SyncProxy::TakeHandle(::zx::handle h) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal, ::test::protocols::internal::kChannelProtocol_TakeHandle_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolTakeHandleRequestTable;
  const fidl_type_t* resp_type = nullptr;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::ChannelProtocol_RequestEncoder::TakeHandle(&_encoder, &h), &response_);
  if (status_ != ZX_OK)
    return status_;
  return ZX_OK;
}

zx_status_t ChannelProtocol_SyncProxy::MutateSocket(::zx::socket a, ::zx::socket* out_b) {
  ::fidl::MessageEncoder _encoder(::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal, ::test::protocols::internal::kChannelProtocol_MutateSocket_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketRequestTable;
  const fidl_type_t* resp_type = &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketTopResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocols::ChannelProtocol_RequestEncoder::MutateSocket(&_encoder, &a), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_b = ::fidl::DecodeAs<::zx::socket>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

AnotherDiscoverableProtocol::~AnotherDiscoverableProtocol() = default;
const char AnotherDiscoverableProtocol::Name_[] = "fake.library.FakeProtocol";

const fidl_type_t* ::test::protocols::AnotherDiscoverableProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response) {
  *out_needs_response = false;
  switch (ordinal) {
    default:
      return nullptr;
  }
}

const fidl_type_t* AnotherDiscoverableProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    default:
      return nullptr;
  }
}

AnotherDiscoverableProtocol_EventSender::~AnotherDiscoverableProtocol_EventSender() = default;

AnotherDiscoverableProtocol_Sync::~AnotherDiscoverableProtocol_Sync() = default;

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

AnotherDiscoverableProtocol_Proxy::~AnotherDiscoverableProtocol_Proxy() = default;

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

AnotherDiscoverableProtocol_Stub::AnotherDiscoverableProtocol_Stub(::test::protocols::AnotherDiscoverableProtocol_Stub::AnotherDiscoverableProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

AnotherDiscoverableProtocol_Stub::~AnotherDiscoverableProtocol_Stub() = default;

namespace {

}  // namespace

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    default: {
      return ZX_ERR_NOT_SUPPORTED;
    }
  }
  return ZX_OK;
}

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

AnotherDiscoverableProtocol_SyncProxy::~AnotherDiscoverableProtocol_SyncProxy() = default;
#endif  // __Fuchsia__

}  // namespace protocols
}  // namespace test
