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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace protocolrequest {

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocolrequest_ParentGetChildResponseTable;
const fidl_type_t* ParentGetChildResponse::FidlType = &test_protocolrequest_ParentGetChildResponseTable;

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

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

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocolrequest_ParentGetChildRequestResponseTable;
const fidl_type_t* ParentGetChildRequestResponse::FidlType = &test_protocolrequest_ParentGetChildRequestResponseTable;

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

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

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocolrequest_ParentTakeChildRequestTable;
const fidl_type_t* ParentTakeChildRequest::FidlType = &test_protocolrequest_ParentTakeChildRequestTable;

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

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

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_protocolrequest_ParentTakeChildRequestRequestTable;
const fidl_type_t* ParentTakeChildRequestRequest::FidlType = &test_protocolrequest_ParentTakeChildRequestRequestTable;

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

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

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

#endif  // __Fuchsia__

//
// Proxies and stubs definitions
//

#ifdef __Fuchsia__

Child::~Child() = default;

const fidl_type_t* ::test::protocolrequest::Child_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* Child_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    default:
      return nullptr;
  }
}

Child_EventSender::~Child_EventSender() = default;

Child_Sync::~Child_Sync() = default;

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

Child_Proxy::~Child_Proxy() = default;

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

Child_Stub::Child_Stub(::test::protocolrequest::Child_Stub::Child_clazz* impl) : impl_(impl) {
  (void)impl_;
}

Child_Stub::~Child_Stub() = default;

namespace {

}  // namespace

zx_status_t Child_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocolrequest::Child_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;
}

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

Child_SyncProxy::~Child_SyncProxy() = default;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

__LOCAL extern "C" const fidl_type_t test_protocolrequest_ParentGetChildRequestResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocolrequest_ParentTakeChildRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocolrequest_ParentTakeChildRequestRequestTable;

}  // namespace _internal

Parent::~Parent() = default;

const fidl_type_t* ::test::protocolrequest::Parent_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::protocolrequest::internal::kParent_GetChild_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocolrequest::internal::kParent_GetChildRequest_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return nullptr;
      ;
    case ::test::protocolrequest::internal::kParent_TakeChild_Ordinal:
      *out_is_known = true;
      return &::test::protocolrequest::_internal::test_protocolrequest_ParentTakeChildRequestTable;
      ;
    case ::test::protocolrequest::internal::kParent_TakeChildRequest_Ordinal:
      *out_is_known = true;
      return &::test::protocolrequest::_internal::test_protocolrequest_ParentTakeChildRequestRequestTable;
      ;
    default:
      return nullptr;
  }
}

const fidl_type_t* Parent_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocolrequest::internal::kParent_GetChild_Ordinal:
      return &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildResponseTable;
      ;
    case ::test::protocolrequest::internal::kParent_GetChildRequest_Ordinal:
      return &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildRequestResponseTable;
      ;
    default:
      return nullptr;
  }
}

Parent_EventSender::~Parent_EventSender() = default;

Parent_Sync::~Parent_Sync() = default;

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

Parent_Proxy::~Parent_Proxy() = default;

zx_status_t Parent_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>
Parent_GetChild_ResponseHandler(Parent::GetChildCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for Parent::GetChild\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::protocolrequest::Child>>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildResponseTable);
}

}  // namespace
void Parent_Proxy::GetChild(GetChildCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_GetChild_Ordinal, ::test::protocolrequest::internal::kParent_GetChild_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocolrequest::Parent_RequestEncoder::GetChild(&_encoder), Parent_GetChild_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
Parent_GetChildRequest_ResponseHandler(Parent::GetChildRequestCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for Parent::GetChildRequest\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::protocolrequest::Child>>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      },
      &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildRequestResponseTable);
}

}  // namespace
void Parent_Proxy::GetChildRequest(GetChildRequestCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_GetChildRequest_Ordinal, ::test::protocolrequest::internal::kParent_GetChildRequest_DynamicFlags);
  const fidl_type_t* req_type = nullptr;
  controller_->Send(req_type, ::test::protocolrequest::Parent_RequestEncoder::GetChildRequest(&_encoder), Parent_GetChildRequest_ResponseHandler(std::move(callback)));
}
void Parent_Proxy::TakeChild(::fidl::InterfaceHandle<::test::protocolrequest::Child> c) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_TakeChild_Ordinal, ::test::protocolrequest::internal::kParent_TakeChild_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentTakeChildRequestTable;
  controller_->Send(req_type, ::test::protocolrequest::Parent_RequestEncoder::TakeChild(&_encoder, &c), nullptr);
}
void Parent_Proxy::TakeChildRequest(::fidl::InterfaceRequest<::test::protocolrequest::Child> r) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_TakeChildRequest_Ordinal, ::test::protocolrequest::internal::kParent_TakeChildRequest_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentTakeChildRequestRequestTable;
  controller_->Send(req_type, ::test::protocolrequest::Parent_RequestEncoder::TakeChildRequest(&_encoder, &r), nullptr);
}

Parent_Stub::Parent_Stub(::test::protocolrequest::Parent_Stub::Parent_clazz* impl) : impl_(impl) {
  (void)impl_;
}

Parent_Stub::~Parent_Stub() = default;

namespace {

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

  void operator()(::fidl::InterfaceHandle<::test::protocolrequest::Child> c) {
    ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_GetChild_Ordinal, ::test::protocolrequest::internal::kParent_GetChild_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildResponseTable;
    response_.Send(resp_type, ::test::protocolrequest::Parent_ResponseEncoder::GetChild(&_encoder, &c));
  }

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

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

  void operator()(::fidl::InterfaceRequest<::test::protocolrequest::Child> r) {
    ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_GetChildRequest_Ordinal, ::test::protocolrequest::internal::kParent_GetChildRequest_DynamicFlags);
    const fidl_type_t* resp_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildRequestResponseTable;
    response_.Send(resp_type, ::test::protocolrequest::Parent_ResponseEncoder::GetChildRequest(&_encoder, &r));
  }

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

}  // namespace

zx_status_t Parent_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocolrequest::Parent_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::protocolrequest::internal::kParent_GetChild_Ordinal: {
      impl_->GetChild(Parent_GetChild_Responder(std::move(response)));
      break;
    }
    case ::test::protocolrequest::internal::kParent_GetChildRequest_Ordinal: {
      impl_->GetChildRequest(Parent_GetChildRequest_Responder(std::move(response)));
      break;
    }
    case ::test::protocolrequest::internal::kParent_TakeChild_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TakeChild(::fidl::DecodeAs<::fidl::InterfaceHandle<::test::protocolrequest::Child>>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocolrequest::internal::kParent_TakeChildRequest_Ordinal: {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TakeChildRequest(::fidl::DecodeAs<::fidl::InterfaceRequest<::test::protocolrequest::Child>>(&decoder, 0 + 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;
}

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

Parent_SyncProxy::~Parent_SyncProxy() = default;

zx_status_t Parent_SyncProxy::GetChild(::fidl::InterfaceHandle<::test::protocolrequest::Child>* out_c) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_GetChild_Ordinal, ::test::protocolrequest::internal::kParent_GetChild_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolrequest::Parent_RequestEncoder::GetChild(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_c = ::fidl::DecodeAs<::fidl::InterfaceHandle<::test::protocolrequest::Child>>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t Parent_SyncProxy::GetChildRequest(::fidl::InterfaceRequest<::test::protocolrequest::Child>* out_r) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_GetChildRequest_Ordinal, ::test::protocolrequest::internal::kParent_GetChildRequest_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type = nullptr;
  const fidl_type_t* resp_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentGetChildRequestResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocolrequest::Parent_RequestEncoder::GetChildRequest(&_encoder), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_r = ::fidl::DecodeAs<::fidl::InterfaceRequest<::test::protocolrequest::Child>>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t Parent_SyncProxy::TakeChild(::fidl::InterfaceHandle<::test::protocolrequest::Child> c) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_TakeChild_Ordinal, ::test::protocolrequest::internal::kParent_TakeChild_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentTakeChildRequestTable;
  return proxy_.Send(req_type, ::test::protocolrequest::Parent_RequestEncoder::TakeChild(&_encoder, &c));
}

zx_status_t Parent_SyncProxy::TakeChildRequest(::fidl::InterfaceRequest<::test::protocolrequest::Child> r) {
  ::fidl::MessageEncoder _encoder(::test::protocolrequest::internal::kParent_TakeChildRequest_Ordinal, ::test::protocolrequest::internal::kParent_TakeChildRequest_DynamicFlags);
  const fidl_type_t* req_type = &::test::protocolrequest::_internal::test_protocolrequest_ParentTakeChildRequestRequestTable;
  return proxy_.Send(req_type, ::test::protocolrequest::Parent_RequestEncoder::TakeChildRequest(&_encoder, &r));
}

#endif  // __Fuchsia__

}  // namespace protocolrequest
}  // namespace test
