3 * Copyright 2015 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #ifndef GRPCPP_IMPL_CODEGEN_SERVICE_TYPE_H
20 #define GRPCPP_IMPL_CODEGEN_SERVICE_TYPE_H
22 // IWYU pragma: private, include <grpcpp/impl/service_type.h>
24 #include <grpcpp/impl/codegen/config.h>
25 #include <grpcpp/impl/codegen/core_codegen_interface.h>
26 #include <grpcpp/impl/codegen/rpc_service_method.h>
27 #include <grpcpp/impl/codegen/serialization_traits.h>
28 #include <grpcpp/impl/codegen/server_interface.h>
29 #include <grpcpp/impl/codegen/status.h>
33 class CompletionQueue;
35 class ServerInterface;
39 class ServerAsyncStreamingInterface {
41 virtual ~ServerAsyncStreamingInterface() {}
43 /// Request notification of the sending of initial metadata to the client.
44 /// Completion will be notified by \a tag on the associated completion
45 /// queue. This call is optional, but if it is used, it cannot be used
46 /// concurrently with or after the \a Finish method.
48 /// \param[in] tag Tag identifying this request.
49 virtual void SendInitialMetadata(void* tag) = 0;
52 friend class ::grpc::ServerInterface;
53 virtual void BindCall(Call* call) = 0;
55 } // namespace internal
57 /// Desriptor of an RPC service and its various RPC methods
60 Service() : server_(nullptr) {}
63 bool has_async_methods() const {
64 for (const auto& method : methods_) {
65 if (method && method->handler() == nullptr) {
72 bool has_synchronous_methods() const {
73 for (const auto& method : methods_) {
75 method->api_type() == internal::RpcServiceMethod::ApiType::SYNC) {
82 bool has_callback_methods() const {
83 for (const auto& method : methods_) {
84 if (method && (method->api_type() ==
85 internal::RpcServiceMethod::ApiType::CALL_BACK ||
87 internal::RpcServiceMethod::ApiType::RAW_CALL_BACK)) {
94 bool has_generic_methods() const {
95 for (const auto& method : methods_) {
96 if (method == nullptr) {
104 template <class Message>
105 void RequestAsyncUnary(int index, ::grpc::ServerContext* context,
107 internal::ServerAsyncStreamingInterface* stream,
108 ::grpc::CompletionQueue* call_cq,
109 ::grpc::ServerCompletionQueue* notification_cq,
111 // Typecast the index to size_t for indexing into a vector
112 // while preserving the API that existed before a compiler
113 // warning was first seen (grpc/grpc#11664)
114 size_t idx = static_cast<size_t>(index);
115 server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
116 notification_cq, tag, request);
118 void RequestAsyncClientStreaming(
119 int index, ::grpc::ServerContext* context,
120 internal::ServerAsyncStreamingInterface* stream,
121 ::grpc::CompletionQueue* call_cq,
122 ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
123 size_t idx = static_cast<size_t>(index);
124 server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
125 notification_cq, tag);
127 template <class Message>
128 void RequestAsyncServerStreaming(
129 int index, ::grpc::ServerContext* context, Message* request,
130 internal::ServerAsyncStreamingInterface* stream,
131 ::grpc::CompletionQueue* call_cq,
132 ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
133 size_t idx = static_cast<size_t>(index);
134 server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
135 notification_cq, tag, request);
137 void RequestAsyncBidiStreaming(
138 int index, ::grpc::ServerContext* context,
139 internal::ServerAsyncStreamingInterface* stream,
140 ::grpc::CompletionQueue* call_cq,
141 ::grpc::ServerCompletionQueue* notification_cq, void* tag) {
142 size_t idx = static_cast<size_t>(index);
143 server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
144 notification_cq, tag);
147 void AddMethod(internal::RpcServiceMethod* method) {
148 methods_.emplace_back(method);
151 void MarkMethodAsync(int index) {
152 // This does not have to be a hard error, however no one has approached us
153 // with a use case yet. Please file an issue if you believe you have one.
154 size_t idx = static_cast<size_t>(index);
156 methods_[idx].get() != nullptr &&
157 "Cannot mark the method as 'async' because it has already been "
158 "marked as 'generic'.");
159 methods_[idx]->SetServerApiType(internal::RpcServiceMethod::ApiType::ASYNC);
162 void MarkMethodRaw(int index) {
163 // This does not have to be a hard error, however no one has approached us
164 // with a use case yet. Please file an issue if you believe you have one.
165 size_t idx = static_cast<size_t>(index);
166 GPR_CODEGEN_ASSERT(methods_[idx].get() != nullptr &&
167 "Cannot mark the method as 'raw' because it has already "
168 "been marked as 'generic'.");
169 methods_[idx]->SetServerApiType(internal::RpcServiceMethod::ApiType::RAW);
172 void MarkMethodGeneric(int index) {
173 // This does not have to be a hard error, however no one has approached us
174 // with a use case yet. Please file an issue if you believe you have one.
175 size_t idx = static_cast<size_t>(index);
177 methods_[idx]->handler() != nullptr &&
178 "Cannot mark the method as 'generic' because it has already been "
179 "marked as 'async' or 'raw'.");
180 methods_[idx].reset();
183 void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
184 // This does not have to be a hard error, however no one has approached us
185 // with a use case yet. Please file an issue if you believe you have one.
186 size_t idx = static_cast<size_t>(index);
187 GPR_CODEGEN_ASSERT(methods_[idx] && methods_[idx]->handler() &&
188 "Cannot mark an async or generic method Streamed");
189 methods_[idx]->SetHandler(streamed_method);
191 // From the server's point of view, streamed unary is a special
192 // case of BIDI_STREAMING that has 1 read and 1 write, in that order,
193 // and split server-side streaming is BIDI_STREAMING with 1 read and
194 // any number of writes, in that order.
195 methods_[idx]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
198 void MarkMethodCallback(int index, internal::MethodHandler* handler) {
199 // This does not have to be a hard error, however no one has approached us
200 // with a use case yet. Please file an issue if you believe you have one.
201 size_t idx = static_cast<size_t>(index);
203 methods_[idx].get() != nullptr &&
204 "Cannot mark the method as 'callback' because it has already been "
205 "marked as 'generic'.");
206 methods_[idx]->SetHandler(handler);
207 methods_[idx]->SetServerApiType(
208 internal::RpcServiceMethod::ApiType::CALL_BACK);
211 void MarkMethodRawCallback(int index, internal::MethodHandler* handler) {
212 // This does not have to be a hard error, however no one has approached us
213 // with a use case yet. Please file an issue if you believe you have one.
214 size_t idx = static_cast<size_t>(index);
216 methods_[idx].get() != nullptr &&
217 "Cannot mark the method as 'raw callback' because it has already "
218 "been marked as 'generic'.");
219 methods_[idx]->SetHandler(handler);
220 methods_[idx]->SetServerApiType(
221 internal::RpcServiceMethod::ApiType::RAW_CALL_BACK);
224 internal::MethodHandler* GetHandler(int index) {
225 size_t idx = static_cast<size_t>(index);
226 return methods_[idx]->handler();
231 friend class ServerInterface;
232 ServerInterface* server_;
233 std::vector<std::unique_ptr<internal::RpcServiceMethod>> methods_;
238 #endif // GRPCPP_IMPL_CODEGEN_SERVICE_TYPE_H