.. _module-pw_rpc_nanopb:

------
nanopb
------
``pw_rpc`` can generate services which encode/decode RPC requests and responses
as nanopb message structs.

Usage
=====
To enable nanopb code generation, the build argument
``dir_pw_third_party_nanopb`` must be set to point to a local nanopb
installation.

Define a ``pw_proto_library`` containing the .proto file defining your service
(and optionally other related protos), then depend on the ``nanopb_rpc``
version of that library in the code implementing the service.

.. code::

  # chat/BUILD.gn

  import("$dir_pw_build/target_types.gni")
  import("$dir_pw_protobuf_compiler/proto.gni")

  pw_proto_library("chat_protos") {
    sources = [ "chat_protos/chat_service.proto" ]
  }

  # Library that implements the ChatService.
  pw_source_set("chat_service") {
    sources = [
      "chat_service.cc",
      "chat_service.h",
    ]
    public_deps = [ ":chat_protos.nanopb_rpc" ]
  }

A C++ header file is generated for each input .proto file, with the ``.proto``
extension replaced by ``.rpc.pb.h``. For example, given the input file
``chat_protos/chat_service.proto``, the generated header file will be placed
at the include path ``"chat_protos/chat_service.rpc.pb.h"``.

Generated code API
==================
Take the following RPC service as an example.

.. code:: protobuf

  // chat/chat_protos/chat_service.proto

  syntax = "proto3";

  service ChatService {
    // Returns information about a chatroom.
    rpc GetRoomInformation(RoomInfoRequest) returns (RoomInfoResponse) {}

    // Lists all of the users in a chatroom. The response is streamed as there
    // may be a large amount of users.
    rpc ListUsersInRoom(ListUsersRequest) returns (stream ListUsersResponse) {}

    // Uploads a file, in chunks, to a chatroom.
    rpc UploadFile(stream UploadFileRequest) returns (UploadFileResponse) {}

    // Sends messages to a chatroom while receiving messages from other users.
    rpc Chat(stream ChatMessage) returns (stream ChatMessage) {}
  }

Server-side
-----------
A C++ class is generated for each service in the .proto file. The class is
located within a special ``generated`` sub-namespace of the file's package.

The generated class is a base class which must be derived to implement the
service's methods. The base class is templated on the derived class.

.. code:: c++

  #include "chat_protos/chat_service.rpc.pb.h"

  class ChatService final : public generated::ChatService<ChatService> {
   public:
    // Implementations of the service's RPC methods; see below.
  };

Unary RPC
^^^^^^^^^
A unary RPC is implemented as a function which takes in the RPC's request struct
and populates a response struct to send back, with a status indicating whether
the request succeeded.

.. code:: c++

  pw::Status GetRoomInformation(pw::rpc::ServerContext& ctx,
                                const RoomInfoRequest& request,
                                RoomInfoResponse& response);

Server streaming RPC
^^^^^^^^^^^^^^^^^^^^
A server streaming RPC receives the client's request message alongside a
``ServerWriter``, used to stream back responses.

.. code:: c++

  void ListUsersInRoom(pw::rpc::ServerContext& ctx,
                       const ListUsersRequest& request,
                       pw::rpc::ServerWriter<ListUsersResponse>& writer);

The ``ServerWriter`` object is movable, and remains active until it is manually
closed or goes out of scope. The writer has a simple API to return responses:

.. cpp:function:: Status ServerWriter::Write(const T& response)

  Writes a single response message to the stream. The returned status indicates
  whether the write was successful.

.. cpp:function:: void ServerWriter::Finish(Status status = OkStatus())

  Closes the stream and sends back the RPC's overall status to the client.

Once a ``ServerWriter`` has been closed, all future ``Write`` calls will fail.

.. attention::

  Make sure to use ``std::move`` when passing the ``ServerWriter`` around to
  avoid accidentally closing it and ending the RPC.

Client streaming RPC
^^^^^^^^^^^^^^^^^^^^
.. attention::

  ``pw_rpc`` does not yet support client streaming RPCs.

Bidirectional streaming RPC
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. attention::

  ``pw_rpc`` does not yet support bidirectional streaming RPCs.

Client-side
-----------
A corresponding client class is generated for every service defined in the proto
file. Like the service class, it is placed under the ``generated`` namespace.
The class is named after the service, with a ``Client`` suffix. For example, the
``ChatService`` would create a ``generated::ChatServiceClient``.

The client class contains static methods to call each of the service's methods.
It is not meant to be instantiated. The signatures for the methods all follow
the same format, taking a channel through which to communicate, the initial
request struct, and a response handler.

.. code-block:: c++

  static NanopbClientCall<UnaryResponseHandler<RoomInfoResponse>>
  GetRoomInformation(Channel& channel,
                     const RoomInfoRequest& request,
                     UnaryResponseHandler<RoomInfoResponse> handler);

The ``NanopbClientCall`` object returned by the RPC invocation stores the active
RPC's context. For more information on ``ClientCall`` objects, refer to the
:ref:`core RPC documentation <module-pw_rpc-making-calls>`.

Response handlers
^^^^^^^^^^^^^^^^^
RPC responses are sent back to the caller through a response handler object.
These are classes with virtual callback functions implemented by the RPC caller
to handle RPC events.

There are two types of response handlers: unary and server-streaming, which are
used depending whether the method's responses are a stream or not.

Unary / client streaming RPC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A ``UnaryResponseHandler`` is used by methods where the server returns a single
response. It contains a callback for the response, which is only called once.

.. code-block:: c++

  template <typename Response>
  class UnaryResponseHandler {
   public:
    virtual ~UnaryResponseHandler() = default;

    // Called when the response is received from the server with the method's
    // status and the deserialized response struct.
    virtual void ReceivedResponse(Status status, const Response& response) = 0;

    // Called when an error occurs internally in the RPC client or server.
    virtual void RpcError(Status) {}
  };

.. cpp:class:: template <typename Response> UnaryResponseHandler

  A handler for RPC methods which return a single response (i.e. unary and
  client streaming).

.. cpp:function:: virtual void UnaryResponseHandler::ReceivedResponse(Status status, const Response& response)

  Callback invoked when the response is recieved from the server. Guaranteed to
  only be called once.

.. cpp:function:: virtual void UnaryResponseHandler::RpcError(Status status)

  Callback invoked if an internal error occurs in the RPC system. Optional;
  defaults to a no-op.

**Example implementation**

.. code-block:: c++

  class RoomInfoHandler : public UnaryResponseHandler<RoomInfoResponse> {
   public:
    void ReceivedResponse(Status status,
                          const RoomInfoResponse& response) override {
      if (status.ok()) {
        response_ = response;
      }
    }

    constexpr RoomInfoResponse& response() { return response_; }

   private:
    RoomInfoResponse response_;
  };

Server streaming / bidirectional streaming RPC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For methods which return a response stream, a ``ServerStreamingResponseHandler``
is used.

.. code:: c++

  class ServerStreamingResponseHandler {
   public:
    virtual ~ServerStreamingResponseHandler() = default;

    // Called on every response received from the server with the deserialized
    // response struct.
    virtual void ReceivedResponse(const Response& response) = 0;

    // Called when the server ends the stream with the overall RPC status.
    virtual void Complete(Status status) = 0;

    // Called when an error occurs internally in the RPC client or server.
    virtual void RpcError(Status) {}
  };

.. cpp:class:: template <typename Response> ServerStreamingResponseHandler

  A handler for RPC methods which return zero or more responses (i.e. server
  and bidirectional streaming).

.. cpp:function:: virtual void ServerStreamingResponseHandler::ReceivedResponse(const Response& response)

  Callback invoked whenever a response is received from the server.

.. cpp:function:: virtual void ServerStreamingResponseHandler::Complete(Status status)

  Callback invoked when the server ends the stream, with the overall status for
  the RPC.

.. cpp:function:: virtual void ServerStreamingResponseHandler::RpcError(Status status)

  Callback invoked if an internal error occurs in the RPC system. Optional;
  defaults to a no-op.

**Example implementation**

.. code-block:: c++

  class ChatHandler : public UnaryResponseHandler<ChatMessage> {
   public:
    void ReceivedResponse(const ChatMessage& response) override {
      gui_.RenderChatMessage(response);
    }

    void Complete(Status status) override {
      client_.Exit(status);
    }

   private:
    ChatGui& gui_;
    ChatClient& client_;
  };

Example usage
~~~~~~~~~~~~~
The following example demonstrates how to call an RPC method using a nanopb
service client and receive the response.

.. code-block:: c++

  #include "chat_protos/chat_service.rpc.pb.h"

  namespace {
    MyChannelOutput output;
    pw::rpc::Channel channels[] = {pw::rpc::Channel::Create<0>(&output)};
    pw::rpc::Client client(channels);
  }

  void InvokeSomeRpcs() {
    RoomInfoHandler handler;

    // The RPC will remain active as long as `call` is alive.
    auto call = ChatServiceClient::GetRoomInformation(channels[0],
                                                      {.room = "pigweed"},
                                                      handler);

    // For simplicity, block here. An actual implementation would likely
    // std::move the call somewhere to keep it active while doing other work.
    while (call.active()) {
      Wait();
    }

    DoStuff(handler.response());
  }
