1 // 2 // 3 // Copyright 2024 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_IMPL_GENERIC_STUB_INTERNAL_H 20 #define GRPCPP_IMPL_GENERIC_STUB_INTERNAL_H 21 22 #include <grpcpp/client_context.h> 23 #include <grpcpp/impl/rpc_method.h> 24 #include <grpcpp/support/byte_buffer.h> 25 #include <grpcpp/support/client_callback.h> 26 #include <grpcpp/support/status.h> 27 #include <grpcpp/support/stub_options.h> 28 29 #include <functional> 30 31 namespace grpc { 32 33 template <class RequestType, class ResponseType> 34 class TemplatedGenericStub; 35 template <class RequestType, class ResponseType> 36 class TemplatedGenericStubCallback; 37 38 namespace internal { 39 40 /// Generic stubs provide a type-unaware interface to call gRPC methods 41 /// by name. In practice, the Request and Response types should be basic 42 /// types like grpc::ByteBuffer or proto::MessageLite (the base protobuf). 43 template <class RequestType, class ResponseType> 44 class TemplatedGenericStubCallbackInternal { 45 public: TemplatedGenericStubCallbackInternal(std::shared_ptr<grpc::ChannelInterface> channel)46 explicit TemplatedGenericStubCallbackInternal( 47 std::shared_ptr<grpc::ChannelInterface> channel) 48 : channel_(channel) {} 49 50 /// Setup and start a unary call to a named method \a method using 51 /// \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)52 void UnaryCall(ClientContext* context, const std::string& method, 53 StubOptions options, const RequestType* request, 54 ResponseType* response, 55 std::function<void(grpc::Status)> on_completion) { 56 UnaryCallInternal(context, method, options, request, response, 57 std::move(on_completion)); 58 } 59 60 /// Setup a unary call to a named method \a method using 61 /// \a context and specifying the \a request and \a response buffers. 62 /// Like any other reactor-based RPC, it will not be activated until 63 /// StartCall is invoked on its reactor. PrepareUnaryCall(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,ClientUnaryReactor * reactor)64 void PrepareUnaryCall(ClientContext* context, const std::string& method, 65 StubOptions options, const RequestType* request, 66 ResponseType* response, ClientUnaryReactor* reactor) { 67 PrepareUnaryCallInternal(context, method, options, request, response, 68 reactor); 69 } 70 71 /// Setup a call to a named method \a method using \a context and tied to 72 /// \a reactor . Like any other bidi streaming RPC, it will not be activated 73 /// until StartCall is invoked on its reactor. PrepareBidiStreamingCall(ClientContext * context,const std::string & method,StubOptions options,ClientBidiReactor<RequestType,ResponseType> * reactor)74 void PrepareBidiStreamingCall( 75 ClientContext* context, const std::string& method, StubOptions options, 76 ClientBidiReactor<RequestType, ResponseType>* reactor) { 77 PrepareBidiStreamingCallInternal(context, method, options, reactor); 78 } 79 80 private: 81 template <class Req, class Resp> 82 friend class grpc::TemplatedGenericStub; 83 template <class Req, class Resp> 84 friend class grpc::TemplatedGenericStubCallback; 85 std::shared_ptr<grpc::ChannelInterface> channel_; 86 UnaryCallInternal(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,std::function<void (grpc::Status)> on_completion)87 void UnaryCallInternal(ClientContext* context, const std::string& method, 88 StubOptions options, const RequestType* request, 89 ResponseType* response, 90 std::function<void(grpc::Status)> on_completion) { 91 internal::CallbackUnaryCall( 92 channel_.get(), 93 grpc::internal::RpcMethod(method.c_str(), options.suffix_for_stats(), 94 grpc::internal::RpcMethod::NORMAL_RPC), 95 context, request, response, std::move(on_completion)); 96 } 97 PrepareUnaryCallInternal(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,ClientUnaryReactor * reactor)98 void PrepareUnaryCallInternal(ClientContext* context, 99 const std::string& method, StubOptions options, 100 const RequestType* request, 101 ResponseType* response, 102 ClientUnaryReactor* reactor) { 103 internal::ClientCallbackUnaryFactory::Create<RequestType, ResponseType>( 104 channel_.get(), 105 grpc::internal::RpcMethod(method.c_str(), options.suffix_for_stats(), 106 grpc::internal::RpcMethod::NORMAL_RPC), 107 context, request, response, reactor); 108 } 109 PrepareBidiStreamingCallInternal(ClientContext * context,const std::string & method,StubOptions options,ClientBidiReactor<RequestType,ResponseType> * reactor)110 void PrepareBidiStreamingCallInternal( 111 ClientContext* context, const std::string& method, StubOptions options, 112 ClientBidiReactor<RequestType, ResponseType>* reactor) { 113 internal::ClientCallbackReaderWriterFactory<RequestType, ResponseType>:: 114 Create(channel_.get(), 115 grpc::internal::RpcMethod( 116 method.c_str(), options.suffix_for_stats(), 117 grpc::internal::RpcMethod::BIDI_STREAMING), 118 context, reactor); 119 } 120 }; 121 122 } // namespace internal 123 } // namespace grpc 124 125 #endif // GRPCPP_IMPL_GENERIC_STUB_INTERNAL_H 126