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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace protocols {

extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
const fidl_type_t* WithAndWithoutRequestResponseNoRequestWithResponseResponse::FidlType = &test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;

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

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

zx_status_t WithAndWithoutRequestResponseNoRequestWithResponseResponse::Clone(WithAndWithoutRequestResponseNoRequestWithResponseResponse* _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_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_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_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
const fidl_type_t* WithAndWithoutRequestResponseWithRequestWithResponseResponse::FidlType = &test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;

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

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

zx_status_t WithAndWithoutRequestResponseWithRequestWithResponseResponse::Clone(WithAndWithoutRequestResponseWithRequestWithResponseResponse* _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_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_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_union_t, envelope));

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

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

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

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

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

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

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

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::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: {
      value->response_.~decltype(value->response_)();
      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_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_union_t, envelope));

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

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

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

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

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

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

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

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::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: {
      value->response_.~decltype(value->response_)();
      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_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_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_union_t, envelope));

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

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

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::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_union_t, envelope));

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

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

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

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

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::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: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::protocols::WithErrorSyntax_ErrorAsEnum_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kErr: {
      value->err_.~decltype(value->err_)();
      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;
    }
  }
}


#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_union_t, envelope));

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

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

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

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

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

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

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

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::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: {
      value->response_.~decltype(value->response_)();
      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__



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;
}


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_ChannelProtocolMethodBResponseTable;
const fidl_type_t* ChannelProtocolMethodBResponse::FidlType = &test_protocols_ChannelProtocolMethodBResponseTable;

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

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

zx_status_t ChannelProtocolMethodBResponse::Clone(ChannelProtocolMethodBResponse* _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_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__



#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketResponseTable;
const fidl_type_t* ChannelProtocolMutateSocketResponse::FidlType = &test_protocols_ChannelProtocolMutateSocketResponseTable;

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

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

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

#endif  // __Fuchsia__



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_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_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_HandleRightsProtocolResponseMethodResponseTable;
const fidl_type_t* HandleRightsProtocolResponseMethodResponse::FidlType = &test_protocols_HandleRightsProtocolResponseMethodResponseTable;

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

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

zx_status_t HandleRightsProtocolResponseMethodResponse::Clone(HandleRightsProtocolResponseMethodResponse* _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__



#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_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__



#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsResponseTable;
const fidl_type_t* WithProtocolEndsClientEndsResponse::FidlType = &test_protocols_WithProtocolEndsClientEndsResponseTable;

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

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

zx_status_t WithProtocolEndsClientEndsResponse::Clone(WithProtocolEndsClientEndsResponse* _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_WithProtocolEndsServerEndsResponseTable;
const fidl_type_t* WithProtocolEndsServerEndsResponse::FidlType = &test_protocols_WithProtocolEndsServerEndsResponseTable;

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

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

zx_status_t WithProtocolEndsServerEndsResponse::Clone(WithProtocolEndsServerEndsResponse* _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__



#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsResponseTable;
const fidl_type_t* WithProtocolEndsStructContainingEndsResponse::FidlType = &test_protocols_WithProtocolEndsStructContainingEndsResponseTable;

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

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

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

#endif  // __Fuchsia__



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;
}


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_union_t, envelope));

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

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

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

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

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::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_MethodWithUnionUnionMethodResponseTable;
const fidl_type_t* MethodWithUnionUnionMethodResponse::FidlType = &test_protocols_MethodWithUnionUnionMethodResponseTable;

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

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

zx_status_t MethodWithUnionUnionMethodResponse::Clone(MethodWithUnionUnionMethodResponse* _result) const {
  zx_status_t _status = ::fidl::Clone(u, &_result->u);
  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_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
  
__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_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
  
  
  
  
__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, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal:
      *out_is_known = true;
      return nullptr;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal:
      *out_is_known = true;
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
      *out_is_known = true;
      *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_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
      return nullptr;
        ;
    case ::test::protocols::internal::kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
        ;
    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_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable);
}

}  // 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_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable);
}

}  // 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_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
    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_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::WithAndWithoutRequestResponse_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}
void 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_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
  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_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
  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_WithErrorSyntax_ResponseAsStruct_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntax_ErrorAsEnum_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntax_HandleInResult_ResultTable;

}  // namespace _internal

WithErrorSyntax::~WithErrorSyntax() = default;

const fidl_type_t* ::test::protocols::WithErrorSyntax_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kWithErrorSyntax_ResponseAsStruct_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
        ;
    case ::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal:
      *out_is_known = true;
      *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_WithErrorSyntax_ResponseAsStruct_ResultTable;
        ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResultTable;
        ;
    case ::test::protocols::internal::kWithErrorSyntax_ErrorAsEnum_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntax_ErrorAsEnum_ResultTable;
        ;
    case ::test::protocols::internal::kWithErrorSyntax_HandleInResult_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithErrorSyntax_HandleInResult_ResultTable;
        ;
    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_WithErrorSyntax_ResponseAsStruct_ResultTable);
}

}  // 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_WithErrorSyntax_ErrorAsPrimitive_ResultTable);
}

}  // 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_WithErrorSyntax_ErrorAsEnum_ResultTable);
}

}  // 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_WithErrorSyntax_HandleInResult_ResultTable);
}

}  // 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 WithErrorSyntax_ResponseAsStruct_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_WithErrorSyntax_ResponseAsStruct_ResultTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::ResponseAsStruct(&_encoder, &WithErrorSyntax_ResponseAsStruct_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 WithErrorSyntax_ErrorAsPrimitive_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_WithErrorSyntax_ErrorAsPrimitive_ResultTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::ErrorAsPrimitive(&_encoder, &WithErrorSyntax_ErrorAsPrimitive_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 WithErrorSyntax_ErrorAsEnum_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_WithErrorSyntax_ErrorAsEnum_ResultTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::ErrorAsEnum(&_encoder, &WithErrorSyntax_ErrorAsEnum_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 WithErrorSyntax_HandleInResult_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_WithErrorSyntax_HandleInResult_ResultTable;
    response_.Send(resp_type, ::test::protocols::WithErrorSyntax_ResponseEncoder::HandleInResult(&_encoder, &WithErrorSyntax_HandleInResult_Result));
  }

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

}  // namespace

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

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  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_WithErrorSyntax_ResponseAsStruct_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_WithErrorSyntax_ResponseAsStruct_ResultTable;
  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_WithErrorSyntax_ResponseAsStruct_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_WithErrorSyntax_ErrorAsPrimitive_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_WithErrorSyntax_ErrorAsPrimitive_ResultTable;
  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_WithErrorSyntax_ErrorAsPrimitive_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_WithErrorSyntax_ErrorAsEnum_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_WithErrorSyntax_ErrorAsEnum_ResultTable;
  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_WithErrorSyntax_ErrorAsEnum_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_WithErrorSyntax_HandleInResult_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_WithErrorSyntax_HandleInResult_ResultTable;
  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_WithErrorSyntax_HandleInResult_Result = ::fidl::DecodeAs<::test::protocols::WithErrorSyntax_HandleInResult_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__


#ifdef __Fuchsia__

  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_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_ChannelProtocolMethodBResponseTable;
  
__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_ChannelProtocolMutateSocketResponseTable;

}  // namespace _internal

ChannelProtocol::~ChannelProtocol() = default;

const fidl_type_t* ::test::protocols::ChannelProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kChannelProtocol_MethodA_Ordinal:
      *out_is_known = true;
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMethodARequestTable;
        ;
    case ::test::protocols::internal::kChannelProtocol_MethodB_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMethodBRequestTable;
        ;
    case ::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_ChannelProtocolTakeHandleRequestTable;
        ;
    case ::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal:
      *out_is_known = true;
      *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_ChannelProtocolMethodBResponseTable;
        ;
    case ::test::protocols::internal::kChannelProtocol_TakeHandle_Ordinal:
      return nullptr;
        ;
    case ::test::protocols::internal::kChannelProtocol_MutateSocket_Ordinal:
      return &::test::protocols::_internal::test_protocols_ChannelProtocolMutateSocketResponseTable;
        ;
    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_ChannelProtocolMethodBResponseTable);
}

}  // 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_ChannelProtocolMutateSocketResponseTable);
}

}  // 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_ChannelProtocolMethodBResponseTable;
    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_ChannelProtocolMutateSocketResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::ChannelProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}
void 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_ChannelProtocolMethodBResponseTable;
  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_ChannelProtocolMutateSocketResponseTable;
  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__

  
  



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, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kDiscoverableProtocol_Method_Ordinal:
      *out_is_known = true;
      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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::DiscoverableProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocols::internal::kDiscoverableProtocol_Method_Ordinal:
    {
      impl_->Method();
      break;
    }
    default: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}

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__




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, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = 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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::AnotherDiscoverableProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    default: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}

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

AnotherDiscoverableProtocol_SyncProxy::~AnotherDiscoverableProtocol_SyncProxy() = default;

#endif  // __Fuchsia__


#ifdef __Fuchsia__




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

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

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

PlatformServer_EventSender::~PlatformServer_EventSender() = default;

PlatformServer_Sync::~PlatformServer_Sync() = default;

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

PlatformServer_Proxy::~PlatformServer_Proxy() = default;

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



PlatformServer_Stub::PlatformServer_Stub(::test::protocols::PlatformServer_Stub::PlatformServer_clazz* impl) : impl_(impl) {
  (void)impl_;
}

PlatformServer_Stub::~PlatformServer_Stub() = default;

namespace {

}  // namespace

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

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    default: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}

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

PlatformServer_SyncProxy::~PlatformServer_SyncProxy() = default;

#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_HandleRightsProtocolResponseMethodResponseTable;
  
  
__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, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kHandleRightsProtocol_NoResponseMethod_Ordinal:
      *out_is_known = true;
      return &::test::protocols::_internal::test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;
        ;
    case ::test::protocols::internal::kHandleRightsProtocol_ResponseMethod_Ordinal:
      *out_is_known = true;
      *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_HandleRightsProtocolResponseMethodResponseTable;
        ;
    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_HandleRightsProtocolResponseMethodResponseTable);
}

}  // 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_HandleRightsProtocolResponseMethodResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::HandleRightsProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}
void 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_HandleRightsProtocolResponseMethodResponseTable;
  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_WithProtocolEndsClientEndsRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsResponseTable;
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsResponseTable;
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsResponseTable;

}  // namespace _internal

WithProtocolEnds::~WithProtocolEnds() = default;

const fidl_type_t* ::test::protocols::WithProtocolEnds_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kWithProtocolEnds_ClientEnds_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsClientEndsRequestTable;
        ;
    case ::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsRequestTable;
        ;
    case ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal:
      *out_is_known = true;
      *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_WithProtocolEndsClientEndsResponseTable;
        ;
    case ::test::protocols::internal::kWithProtocolEnds_ServerEnds_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsServerEndsResponseTable;
        ;
    case ::test::protocols::internal::kWithProtocolEnds_StructContainingEnds_Ordinal:
      return &::test::protocols::_internal::test_protocols_WithProtocolEndsStructContainingEndsResponseTable;
        ;
    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_WithProtocolEndsClientEndsResponseTable);
}

}  // 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_WithProtocolEndsServerEndsResponseTable);
}

}  // 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_WithProtocolEndsStructContainingEndsResponseTable);
}

}  // 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_WithProtocolEndsClientEndsResponseTable;
    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_WithProtocolEndsServerEndsResponseTable;
    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_WithProtocolEndsStructContainingEndsResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::WithProtocolEnds_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  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_WithProtocolEndsClientEndsResponseTable;
  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_WithProtocolEndsServerEndsResponseTable;
  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_WithProtocolEndsStructContainingEndsResponseTable;
  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_ManyParametersFifteenRequestTable;
  

}  // namespace _internal

ManyParameters::~ManyParameters() = default;

const fidl_type_t* ::test::protocols::ManyParameters_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kManyParameters_Fifteen_Ordinal:
      *out_is_known = true;
      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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::ManyParameters_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  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_MethodWithUnionUnionMethodRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodResponseTable;

}  // namespace _internal

MethodWithUnion::~MethodWithUnion() = default;

const fidl_type_t* ::test::protocols::MethodWithUnion_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocols::internal::kMethodWithUnion_UnionMethod_Ordinal:
      *out_is_known = true;
      *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_MethodWithUnionUnionMethodResponseTable;
        ;
    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_MethodWithUnionUnionMethodResponseTable);
}

}  // 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_MethodWithUnionUnionMethodResponseTable;
    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;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocols::MethodWithUnion_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

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

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

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::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: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  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_MethodWithUnionUnionMethodResponseTable;
  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__

}  // namespace protocols
}  // namespace test

