xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/generic/generic_stub.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPCPP_GENERIC_GENERIC_STUB_H
20 #define GRPCPP_GENERIC_GENERIC_STUB_H
21 
22 #include <functional>
23 
24 #include <grpcpp/client_context.h>
25 #include <grpcpp/impl/rpc_method.h>
26 #include <grpcpp/support/async_stream.h>
27 #include <grpcpp/support/async_unary_call.h>
28 #include <grpcpp/support/byte_buffer.h>
29 #include <grpcpp/support/client_callback.h>
30 #include <grpcpp/support/status.h>
31 #include <grpcpp/support/stub_options.h>
32 
33 namespace grpc {
34 
35 class CompletionQueue;
36 
37 typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
38     GenericClientAsyncReaderWriter;
39 typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
40 
41 /// Generic stubs provide a type-unaware interface to call gRPC methods
42 /// by name. In practice, the Request and Response types should be basic
43 /// types like grpc::ByteBuffer or proto::MessageLite (the base protobuf).
44 template <class RequestType, class ResponseType>
45 class TemplatedGenericStub final {
46  public:
TemplatedGenericStub(std::shared_ptr<grpc::ChannelInterface> channel)47   explicit TemplatedGenericStub(std::shared_ptr<grpc::ChannelInterface> channel)
48       : channel_(channel) {}
49 
50   /// Setup a call to a named method \a method using \a context, but don't
51   /// start it. Let it be started explicitly with StartCall and a tag.
52   /// The return value only indicates whether or not registration of the call
53   /// succeeded (i.e. the call won't proceed if the return value is nullptr).
54   std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>
PrepareCall(ClientContext * context,const std::string & method,grpc::CompletionQueue * cq)55   PrepareCall(ClientContext* context, const std::string& method,
56               grpc::CompletionQueue* cq) {
57     return CallInternal(channel_.get(), context, method, /*options=*/{}, cq,
58                         false, nullptr);
59   }
60 
61   /// Setup a unary call to a named method \a method using \a context, and don't
62   /// start it. Let it be started explicitly with StartCall.
63   /// The return value only indicates whether or not registration of the call
64   /// succeeded (i.e. the call won't proceed if the return value is nullptr).
PrepareUnaryCall(ClientContext * context,const std::string & method,const RequestType & request,grpc::CompletionQueue * cq)65   std::unique_ptr<ClientAsyncResponseReader<ResponseType>> PrepareUnaryCall(
66       ClientContext* context, const std::string& method,
67       const RequestType& request, grpc::CompletionQueue* cq) {
68     return std::unique_ptr<ClientAsyncResponseReader<ResponseType>>(
69         internal::ClientAsyncResponseReaderHelper::Create<ResponseType>(
70             channel_.get(), cq,
71             grpc::internal::RpcMethod(method.c_str(),
72                                       /*suffix_for_stats=*/nullptr,
73                                       grpc::internal::RpcMethod::NORMAL_RPC),
74             context, request));
75   }
76 
77   /// DEPRECATED for multi-threaded use
78   /// Begin a call to a named method \a method using \a context.
79   /// A tag \a tag will be delivered to \a cq when the call has been started
80   /// (i.e, initial metadata has been sent).
81   /// The return value only indicates whether or not registration of the call
82   /// succeeded (i.e. the call won't proceed if the return value is nullptr).
Call(ClientContext * context,const std::string & method,grpc::CompletionQueue * cq,void * tag)83   std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>> Call(
84       ClientContext* context, const std::string& method,
85       grpc::CompletionQueue* cq, void* tag) {
86     return CallInternal(channel_.get(), context, method, /*options=*/{}, cq,
87                         true, tag);
88   }
89 
90   /// Setup and start a unary call to a named method \a method using
91   /// \a context and specifying the \a request and \a response buffers.
UnaryCall(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,std::function<void (grpc::Status)> on_completion)92   void UnaryCall(ClientContext* context, const std::string& method,
93                  StubOptions options, const RequestType* request,
94                  ResponseType* response,
95                  std::function<void(grpc::Status)> on_completion) {
96     UnaryCallInternal(context, method, options, request, response,
97                       std::move(on_completion));
98   }
99 
100   /// Setup a unary call to a named method \a method using
101   /// \a context and specifying the \a request and \a response buffers.
102   /// Like any other reactor-based RPC, it will not be activated until
103   /// StartCall is invoked on its reactor.
PrepareUnaryCall(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,ClientUnaryReactor * reactor)104   void PrepareUnaryCall(ClientContext* context, const std::string& method,
105                         StubOptions options, const RequestType* request,
106                         ResponseType* response, ClientUnaryReactor* reactor) {
107     PrepareUnaryCallInternal(context, method, options, request, response,
108                              reactor);
109   }
110 
111   /// Setup a call to a named method \a method using \a context and tied to
112   /// \a reactor . Like any other bidi streaming RPC, it will not be activated
113   /// until StartCall is invoked on its reactor.
PrepareBidiStreamingCall(ClientContext * context,const std::string & method,StubOptions options,ClientBidiReactor<RequestType,ResponseType> * reactor)114   void PrepareBidiStreamingCall(
115       ClientContext* context, const std::string& method, StubOptions options,
116       ClientBidiReactor<RequestType, ResponseType>* reactor) {
117     PrepareBidiStreamingCallInternal(context, method, options, reactor);
118   }
119 
120  private:
121   std::shared_ptr<grpc::ChannelInterface> channel_;
122 
UnaryCallInternal(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,std::function<void (grpc::Status)> on_completion)123   void UnaryCallInternal(ClientContext* context, const std::string& method,
124                          StubOptions options, const RequestType* request,
125                          ResponseType* response,
126                          std::function<void(grpc::Status)> on_completion) {
127     internal::CallbackUnaryCall(
128         channel_.get(),
129         grpc::internal::RpcMethod(method.c_str(), options.suffix_for_stats(),
130                                   grpc::internal::RpcMethod::NORMAL_RPC),
131         context, request, response, std::move(on_completion));
132   }
133 
PrepareUnaryCallInternal(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,ClientUnaryReactor * reactor)134   void PrepareUnaryCallInternal(ClientContext* context,
135                                 const std::string& method, StubOptions options,
136                                 const RequestType* request,
137                                 ResponseType* response,
138                                 ClientUnaryReactor* reactor) {
139     internal::ClientCallbackUnaryFactory::Create<RequestType, ResponseType>(
140         channel_.get(),
141         grpc::internal::RpcMethod(method.c_str(), options.suffix_for_stats(),
142                                   grpc::internal::RpcMethod::NORMAL_RPC),
143         context, request, response, reactor);
144   }
145 
PrepareBidiStreamingCallInternal(ClientContext * context,const std::string & method,StubOptions options,ClientBidiReactor<RequestType,ResponseType> * reactor)146   void PrepareBidiStreamingCallInternal(
147       ClientContext* context, const std::string& method, StubOptions options,
148       ClientBidiReactor<RequestType, ResponseType>* reactor) {
149     internal::ClientCallbackReaderWriterFactory<RequestType, ResponseType>::
150         Create(channel_.get(),
151                grpc::internal::RpcMethod(
152                    method.c_str(), options.suffix_for_stats(),
153                    grpc::internal::RpcMethod::BIDI_STREAMING),
154                context, reactor);
155   }
156 
157   std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>
CallInternal(grpc::ChannelInterface * channel,ClientContext * context,const std::string & method,StubOptions options,grpc::CompletionQueue * cq,bool start,void * tag)158   CallInternal(grpc::ChannelInterface* channel, ClientContext* context,
159                const std::string& method, StubOptions options,
160                grpc::CompletionQueue* cq, bool start, void* tag) {
161     return std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>(
162         internal::ClientAsyncReaderWriterFactory<RequestType, ResponseType>::
163             Create(channel, cq,
164                    grpc::internal::RpcMethod(
165                        method.c_str(), options.suffix_for_stats(),
166                        grpc::internal::RpcMethod::BIDI_STREAMING),
167                    context, start, tag));
168   }
169 };
170 
171 typedef TemplatedGenericStub<grpc::ByteBuffer, grpc::ByteBuffer> GenericStub;
172 
173 }  // namespace grpc
174 
175 #endif  // GRPCPP_GENERIC_GENERIC_STUB_H
176