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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace protocolpayloads {

extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;
const fidl_type_t* LocalStructPayload::FidlType = &test_protocolpayloads_LocalStructPayloadTable;

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

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

zx_status_t LocalStructPayload::Clone(LocalStructPayload* _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_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable;
const fidl_type_t* MainProtocol_TwoWayLocalWithError_Result::FidlType = &test_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable;

MainProtocol_TwoWayLocalWithError_Result::MainProtocol_TwoWayLocalWithError_Result() {}

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

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

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

MainProtocol_TwoWayLocalWithError_Result MainProtocol_TwoWayLocalWithError_Result::WithResponse(::test::protocolpayloads::LocalStructPayload&& val) {
  MainProtocol_TwoWayLocalWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
MainProtocol_TwoWayLocalWithError_Result MainProtocol_TwoWayLocalWithError_Result::WithErr(uint32_t&& val) {
  MainProtocol_TwoWayLocalWithError_Result result;
  result.set_err(std::move(val));
  return result;
}

void MainProtocol_TwoWayLocalWithError_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::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocolpayloads::LocalStructPayload>(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::protocolpayloads::LocalStructPayload, ::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::protocolpayloads::MainProtocol_TwoWayLocalWithError_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 MainProtocol_TwoWayLocalWithError_Result::Decode(::fidl::Decoder* _decoder, MainProtocol_TwoWayLocalWithError_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::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

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

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

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

MainProtocol_TwoWayLocalWithError_Result& MainProtocol_TwoWayLocalWithError_Result::set_response(::test::protocolpayloads::LocalStructPayload value) {
  EnsureStorageInitialized(::test::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

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

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

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

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

extern "C" const fidl_type_t test_protocolpayloads_MainProtocolOneWayAnonRequestTable;
const fidl_type_t* MainProtocolOneWayAnonRequest::FidlType = &test_protocolpayloads_MainProtocolOneWayAnonRequestTable;

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

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

zx_status_t MainProtocolOneWayAnonRequest::Clone(MainProtocolOneWayAnonRequest* _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_protocolpayloads_MainProtocolTwoWayAnonRequestTable;
const fidl_type_t* MainProtocolTwoWayAnonRequest::FidlType = &test_protocolpayloads_MainProtocolTwoWayAnonRequestTable;

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

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

zx_status_t MainProtocolTwoWayAnonRequest::Clone(MainProtocolTwoWayAnonRequest* _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_protocolpayloads_MainProtocolTwoWayAnonResponseTable;
const fidl_type_t* MainProtocolTwoWayAnonResponse::FidlType = &test_protocolpayloads_MainProtocolTwoWayAnonResponseTable;

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

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

zx_status_t MainProtocolTwoWayAnonResponse::Clone(MainProtocolTwoWayAnonResponse* _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_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;
const fidl_type_t* MainProtocolTwoWayAnonWithErrorRequest::FidlType = &test_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;

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

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

zx_status_t MainProtocolTwoWayAnonWithErrorRequest::Clone(MainProtocolTwoWayAnonWithErrorRequest* _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_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResponseTable;
const fidl_type_t* MainProtocol_TwoWayAnonWithError_Response::FidlType = &test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResponseTable;

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

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

zx_status_t MainProtocol_TwoWayAnonWithError_Response::Clone(MainProtocol_TwoWayAnonWithError_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;
  return ZX_OK;
}

extern "C" const fidl_type_t test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable;
const fidl_type_t* MainProtocol_TwoWayAnonWithError_Result::FidlType = &test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable;

MainProtocol_TwoWayAnonWithError_Result::MainProtocol_TwoWayAnonWithError_Result() {}

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

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

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

MainProtocol_TwoWayAnonWithError_Result MainProtocol_TwoWayAnonWithError_Result::WithResponse(::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_Response&& val) {
  MainProtocol_TwoWayAnonWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
MainProtocol_TwoWayAnonWithError_Result MainProtocol_TwoWayAnonWithError_Result::WithErr(uint32_t&& val) {
  MainProtocol_TwoWayAnonWithError_Result result;
  result.set_err(std::move(val));
  return result;
}

void MainProtocol_TwoWayAnonWithError_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::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_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::protocolpayloads::MainProtocol_TwoWayAnonWithError_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::protocolpayloads::MainProtocol_TwoWayAnonWithError_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 MainProtocol_TwoWayAnonWithError_Result::Decode(::fidl::Decoder* _decoder, MainProtocol_TwoWayAnonWithError_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::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

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

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

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

MainProtocol_TwoWayAnonWithError_Result& MainProtocol_TwoWayAnonWithError_Result::set_response(::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_Response value) {
  EnsureStorageInitialized(::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

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

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

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

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

extern "C" const fidl_type_t test_protocolpayloads_MainProtocolOnAnonRequestTable;
const fidl_type_t* MainProtocolOnAnonRequest::FidlType = &test_protocolpayloads_MainProtocolOnAnonRequestTable;

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

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

zx_status_t MainProtocolOnAnonRequest::Clone(MainProtocolOnAnonRequest* _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_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable;
const fidl_type_t* MainProtocol_TwoWayImportWithError_Result::FidlType = &test_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable;

MainProtocol_TwoWayImportWithError_Result::MainProtocol_TwoWayImportWithError_Result() {}

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

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

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

MainProtocol_TwoWayImportWithError_Result MainProtocol_TwoWayImportWithError_Result::WithResponse(::test::protocolpayloads::imported::ImportStructPayload&& val) {
  MainProtocol_TwoWayImportWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
MainProtocol_TwoWayImportWithError_Result MainProtocol_TwoWayImportWithError_Result::WithErr(uint32_t&& val) {
  MainProtocol_TwoWayImportWithError_Result result;
  result.set_err(std::move(val));
  return result;
}

void MainProtocol_TwoWayImportWithError_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::protocolpayloads::MainProtocol_TwoWayImportWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocolpayloads::imported::ImportStructPayload>(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::protocolpayloads::imported::ImportStructPayload, ::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::protocolpayloads::MainProtocol_TwoWayImportWithError_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 MainProtocol_TwoWayImportWithError_Result::Decode(::fidl::Decoder* _decoder, MainProtocol_TwoWayImportWithError_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::protocolpayloads::MainProtocol_TwoWayImportWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

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

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

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

MainProtocol_TwoWayImportWithError_Result& MainProtocol_TwoWayImportWithError_Result::set_response(::test::protocolpayloads::imported::ImportStructPayload value) {
  EnsureStorageInitialized(::test::protocolpayloads::MainProtocol_TwoWayImportWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

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

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

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

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

//
// Proxies and stubs definitions
//

#ifdef __Fuchsia__

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

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_imported_ComposedProtocol_TwoWayComposedWithError_ResultTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_LocalStructPayloadTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocolOneWayAnonRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocolTwoWayAnonRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocolTwoWayAnonResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable;

__LOCAL extern "C" const fidl_type_t test_protocolpayloads_MainProtocolOnAnonRequestTable;

}  // namespace _internal

MainProtocol::~MainProtocol() = default;

const fidl_type_t* ::test::protocolpayloads::MainProtocol_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::protocolpayloads::internal::kMainProtocol_OneWayComposed_Ordinal:
      *out_is_known = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OneWayLocal_Ordinal:
      *out_is_known = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OneWayImport_Ordinal:
      *out_is_known = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OneWayAnon_Ordinal:
      *out_is_known = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOneWayAnonRequestTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonRequestTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* MainProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ComposedProtocol_TwoWayComposedWithError_ResultTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OnComposed_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OnLocal_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OnImport_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonResponseTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable;
      ;
    case ::test::protocolpayloads::internal::kMainProtocol_OnAnon_Ordinal:
      return &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOnAnonRequestTable;
      ;
    default:
      return nullptr;
  }
}

MainProtocol_EventSender::~MainProtocol_EventSender() = default;

MainProtocol_Sync::~MainProtocol_Sync() = default;

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

MainProtocol_Proxy::~MainProtocol_Proxy() = default;

zx_status_t MainProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocolpayloads::internal::kMainProtocol_OnComposed_Ordinal: {
      if (!OnComposed) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnComposed(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_OnLocal_Ordinal: {
      if (!OnLocal) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnLocal(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_OnImport_Ordinal: {
      if (!OnImport) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnImport(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_OnAnon_Ordinal: {
      if (!OnAnon) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOnAnonRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOnAnonRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnAnon(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

void MainProtocol_Proxy::OneWayComposed(int32_t a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayComposed_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayComposed_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayComposed(&_encoder, &a), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayComposed_ResponseHandler(MainProtocol::TwoWayComposedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayComposed\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayComposed(int32_t a, TwoWayComposedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayComposed(&_encoder, &a), MainProtocol_TwoWayComposed_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayComposedWithError_ResponseHandler(MainProtocol::TwoWayComposedWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayComposedWithError\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::protocolpayloads::imported::ComposedProtocol_TwoWayComposedWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ComposedProtocol_TwoWayComposedWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayComposedWithError(int32_t a, TwoWayComposedWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayComposedWithError(&_encoder, &a), MainProtocol_TwoWayComposedWithError_ResponseHandler(std::move(callback)));
}
void MainProtocol_Proxy::OneWayLocal(uint32_t a, uint32_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayLocal_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayLocal_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayLocal(&_encoder, &a, &b), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayLocal_ResponseHandler(MainProtocol::TwoWayLocalCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayLocal\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayLocal(uint32_t a, uint32_t b, TwoWayLocalCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayLocal(&_encoder, &a, &b), MainProtocol_TwoWayLocal_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayLocalWithError_ResponseHandler(MainProtocol::TwoWayLocalWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayLocalWithError\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::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayLocalWithError(uint32_t a, uint32_t b, TwoWayLocalWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayLocalWithError(&_encoder, &a, &b), MainProtocol_TwoWayLocalWithError_ResponseHandler(std::move(callback)));
}
void MainProtocol_Proxy::OneWayImport(int32_t a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayImport_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayImport_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayImport(&_encoder, &a), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayImport_ResponseHandler(MainProtocol::TwoWayImportCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayImport\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayImport(int32_t a, TwoWayImportCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayImport(&_encoder, &a), MainProtocol_TwoWayImport_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayImportWithError_ResponseHandler(MainProtocol::TwoWayImportWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayImportWithError\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::protocolpayloads::MainProtocol_TwoWayImportWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayImportWithError(int32_t a, TwoWayImportWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayImportWithError(&_encoder, &a), MainProtocol_TwoWayImportWithError_ResponseHandler(std::move(callback)));
}
void MainProtocol_Proxy::OneWayAnon(uint32_t a, uint32_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayAnon_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayAnon_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOneWayAnonRequestTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayAnon(&_encoder, &a, &b), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayAnon_ResponseHandler(MainProtocol::TwoWayAnonCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayAnon\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonResponseTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayAnon(uint32_t a, uint32_t b, TwoWayAnonCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonRequestTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayAnon(&_encoder, &a, &b), MainProtocol_TwoWayAnon_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayAnonWithError_ResponseHandler(MainProtocol::TwoWayAnonWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayAnonWithError\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::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayAnonWithError(uint32_t a, uint32_t b, TwoWayAnonWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;
  controller_->Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayAnonWithError(&_encoder, &a, &b), MainProtocol_TwoWayAnonWithError_ResponseHandler(std::move(callback)));
}

MainProtocol_Stub::MainProtocol_Stub(::test::protocolpayloads::MainProtocol_Stub::MainProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

MainProtocol_Stub::~MainProtocol_Stub() = default;

namespace {

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

  void operator()(int32_t a) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayComposed(&_encoder, &a));
  }

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

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

  void operator()(::test::protocolpayloads::imported::ComposedProtocol_TwoWayComposedWithError_Result ComposedProtocol_TwoWayComposedWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ComposedProtocol_TwoWayComposedWithError_ResultTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayComposedWithError(&_encoder, &ComposedProtocol_TwoWayComposedWithError_Result));
  }

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

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

  void operator()(uint32_t a, uint32_t b) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayLocal(&_encoder, &a, &b));
  }

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

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

  void operator()(::test::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result MainProtocol_TwoWayLocalWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayLocalWithError(&_encoder, &MainProtocol_TwoWayLocalWithError_Result));
  }

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

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

  void operator()(int32_t a) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayImport(&_encoder, &a));
  }

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

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

  void operator()(::test::protocolpayloads::MainProtocol_TwoWayImportWithError_Result MainProtocol_TwoWayImportWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayImportWithError(&_encoder, &MainProtocol_TwoWayImportWithError_Result));
  }

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

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

  void operator()(uint32_t a, uint32_t b) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonResponseTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayAnon(&_encoder, &a, &b));
  }

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

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

  void operator()(::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result MainProtocol_TwoWayAnonWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable;
    response_.Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::TwoWayAnonWithError(&_encoder, &MainProtocol_TwoWayAnonWithError_Result));
  }

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

}  // namespace

zx_status_t MainProtocol_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocolpayloads::MainProtocol_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::protocolpayloads::internal::kMainProtocol_OneWayComposed_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayComposed(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayComposed(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayComposed_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayComposedWithError(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayComposedWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_OneWayLocal_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayLocal(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayLocal(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayLocal_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayLocalWithError(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayLocalWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_OneWayImport_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayImport(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayImport(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayImport_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayImportWithError(::fidl::DecodeAs<int32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayImportWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_OneWayAnon_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayAnon(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnon(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayAnon_Responder(std::move(response)));
      break;
    }
    case ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnonWithError(::fidl::DecodeAs<uint32_t>(&decoder, 0 + sizeof(fidl_message_header_t)), ::fidl::DecodeAs<uint32_t>(&decoder, 4 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayAnonWithError_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 MainProtocol_Stub::OnComposed(int32_t a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OnComposed_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OnComposed_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  sender_()->Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::OnComposed(&_encoder, &a));
}
void MainProtocol_Stub::OnLocal(uint32_t a, uint32_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OnLocal_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OnLocal_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  sender_()->Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::OnLocal(&_encoder, &a, &b));
}
void MainProtocol_Stub::OnImport(int32_t a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OnImport_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OnImport_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  sender_()->Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::OnImport(&_encoder, &a));
}
void MainProtocol_Stub::OnAnon(uint32_t a, uint32_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OnAnon_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OnAnon_DynamicFlags);
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOnAnonRequestTable;
  sender_()->Send(resp_type, ::test::protocolpayloads::MainProtocol_ResponseEncoder::OnAnon(&_encoder, &a, &b));
}

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

MainProtocol_SyncProxy::~MainProtocol_SyncProxy() = default;

zx_status_t MainProtocol_SyncProxy::OneWayComposed(int32_t a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayComposed_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayComposed_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  return proxy_.Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayComposed(&_encoder, &a));
}

zx_status_t MainProtocol_SyncProxy::TwoWayComposed(int32_t a, int32_t* out_a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposed_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayComposed(&_encoder, &a), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_a = ::fidl::DecodeAs<int32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayComposedWithError(int32_t a, ::test::protocolpayloads::imported::ComposedProtocol_TwoWayComposedWithError_Result* out_ComposedProtocol_TwoWayComposedWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayComposedWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ComposedProtocol_TwoWayComposedWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayComposedWithError(&_encoder, &a), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocol_TwoWayComposedWithError_Result = ::fidl::DecodeAs<::test::protocolpayloads::imported::ComposedProtocol_TwoWayComposedWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::OneWayLocal(uint32_t a, uint32_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayLocal_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayLocal_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  return proxy_.Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayLocal(&_encoder, &a, &b));
}

zx_status_t MainProtocol_SyncProxy::TwoWayLocal(uint32_t a, uint32_t b, uint32_t* out_a, uint32_t* out_b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocal_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayLocal(&_encoder, &a, &b), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_a = ::fidl::DecodeAs<uint32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  *out_b = ::fidl::DecodeAs<uint32_t>(&decoder_, 4 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayLocalWithError(uint32_t a, uint32_t b, ::test::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result* out_MainProtocol_TwoWayLocalWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_LocalStructPayloadTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayLocalWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayLocalWithError(&_encoder, &a, &b), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_MainProtocol_TwoWayLocalWithError_Result = ::fidl::DecodeAs<::test::protocolpayloads::MainProtocol_TwoWayLocalWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::OneWayImport(int32_t a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayImport_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayImport_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  return proxy_.Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayImport(&_encoder, &a));
}

zx_status_t MainProtocol_SyncProxy::TwoWayImport(int32_t a, int32_t* out_a) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayImport_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayImport(&_encoder, &a), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_a = ::fidl::DecodeAs<int32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayImportWithError(int32_t a, ::test::protocolpayloads::MainProtocol_TwoWayImportWithError_Result* out_MainProtocol_TwoWayImportWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayImportWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_imported_ImportStructPayloadTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayImportWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayImportWithError(&_encoder, &a), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_MainProtocol_TwoWayImportWithError_Result = ::fidl::DecodeAs<::test::protocolpayloads::MainProtocol_TwoWayImportWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::OneWayAnon(uint32_t a, uint32_t b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_OneWayAnon_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_OneWayAnon_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolOneWayAnonRequestTable;
  return proxy_.Send(req_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::OneWayAnon(&_encoder, &a, &b));
}

zx_status_t MainProtocol_SyncProxy::TwoWayAnon(uint32_t a, uint32_t b, uint32_t* out_a, uint32_t* out_b) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnon_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonRequestTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayAnon(&_encoder, &a, &b), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_a = ::fidl::DecodeAs<uint32_t>(&decoder_, 0 + sizeof(fidl_message_header_t));
  *out_b = ::fidl::DecodeAs<uint32_t>(&decoder_, 4 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayAnonWithError(uint32_t a, uint32_t b, ::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result* out_MainProtocol_TwoWayAnonWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_Ordinal, ::test::protocolpayloads::internal::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocolTwoWayAnonWithErrorRequestTable;
  const fidl_type_t* resp_type = &::test::protocolpayloads::_internal::test_protocolpayloads_MainProtocol_TwoWayAnonWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolpayloads::MainProtocol_RequestEncoder::TwoWayAnonWithError(&_encoder, &a, &b), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_MainProtocol_TwoWayAnonWithError_Result = ::fidl::DecodeAs<::test::protocolpayloads::MainProtocol_TwoWayAnonWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__

}  // namespace protocolpayloads
}  // namespace test
