1 /*
2  *
3  * Copyright 2019 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_CODEGEN_SERVER_CONTEXT_H
20 #define GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
21 
22 #include <atomic>
23 #include <cassert>
24 #include <map>
25 #include <memory>
26 #include <type_traits>
27 #include <vector>
28 
29 #include <grpc/impl/codegen/port_platform.h>
30 
31 #include <grpc/impl/codegen/compression_types.h>
32 #include <grpcpp/impl/codegen/call.h>
33 #include <grpcpp/impl/codegen/call_op_set.h>
34 #include <grpcpp/impl/codegen/callback_common.h>
35 #include <grpcpp/impl/codegen/completion_queue_tag.h>
36 #include <grpcpp/impl/codegen/config.h>
37 #include <grpcpp/impl/codegen/create_auth_context.h>
38 #include <grpcpp/impl/codegen/message_allocator.h>
39 #include <grpcpp/impl/codegen/metadata_map.h>
40 #include <grpcpp/impl/codegen/rpc_service_method.h>
41 #include <grpcpp/impl/codegen/security/auth_context.h>
42 #include <grpcpp/impl/codegen/server_callback.h>
43 #include <grpcpp/impl/codegen/server_interceptor.h>
44 #include <grpcpp/impl/codegen/status.h>
45 #include <grpcpp/impl/codegen/string_ref.h>
46 #include <grpcpp/impl/codegen/time.h>
47 
48 struct grpc_metadata;
49 struct grpc_call;
50 struct census_context;
51 
52 namespace grpc {
53 template <class W, class R>
54 class ServerAsyncReader;
55 template <class W>
56 class ServerAsyncWriter;
57 template <class W>
58 class ServerAsyncResponseWriter;
59 template <class W, class R>
60 class ServerAsyncReaderWriter;
61 template <class R>
62 class ServerReader;
63 template <class W>
64 class ServerWriter;
65 
66 namespace internal {
67 template <class ServiceType, class RequestType, class ResponseType>
68 class BidiStreamingHandler;
69 template <class RequestType, class ResponseType>
70 class CallbackUnaryHandler;
71 template <class RequestType, class ResponseType>
72 class CallbackClientStreamingHandler;
73 template <class RequestType, class ResponseType>
74 class CallbackServerStreamingHandler;
75 template <class RequestType, class ResponseType>
76 class CallbackBidiHandler;
77 template <class ServiceType, class RequestType, class ResponseType>
78 class ClientStreamingHandler;
79 template <class ResponseType>
80 void UnaryRunHandlerHelper(const MethodHandler::HandlerParameter&,
81                            ResponseType*, Status&);
82 template <class ServiceType, class RequestType, class ResponseType,
83           class BaseRequestType, class BaseResponseType>
84 class RpcMethodHandler;
85 template <class Base>
86 class FinishOnlyReactor;
87 template <class W, class R>
88 class ServerReaderWriterBody;
89 template <class ServiceType, class RequestType, class ResponseType>
90 class ServerStreamingHandler;
91 class ServerReactor;
92 template <class Streamer, bool WriteNeeded>
93 class TemplatedBidiStreamingHandler;
94 template <::grpc::StatusCode code>
95 class ErrorMethodHandler;
96 }  // namespace internal
97 
98 class ClientContext;
99 class CompletionQueue;
100 class GenericServerContext;
101 class Server;
102 class ServerInterface;
103 
104 // TODO(vjpai): Remove namespace experimental when de-experimentalized fully.
105 namespace experimental {
106 
107 typedef ::grpc::ServerContextBase ServerContextBase;
108 typedef ::grpc::CallbackServerContext CallbackServerContext;
109 
110 }  // namespace experimental
111 
112 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
113 namespace experimental {
114 #endif
115 class GenericCallbackServerContext;
116 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
117 }  // namespace experimental
118 #endif
119 namespace internal {
120 class Call;
121 }  // namespace internal
122 
123 namespace testing {
124 class InteropServerContextInspector;
125 class ServerContextTestSpouse;
126 class DefaultReactorTestPeer;
127 }  // namespace testing
128 
129 /// Base class of ServerContext. Experimental until callback API is final.
130 class ServerContextBase {
131  public:
132   virtual ~ServerContextBase();
133 
134   /// Return the deadline for the server call.
deadline()135   std::chrono::system_clock::time_point deadline() const {
136     return ::grpc::Timespec2Timepoint(deadline_);
137   }
138 
139   /// Return a \a gpr_timespec representation of the server call's deadline.
raw_deadline()140   gpr_timespec raw_deadline() const { return deadline_; }
141 
142   /// Add the (\a key, \a value) pair to the initial metadata
143   /// associated with a server call. These are made available at the client side
144   /// by the \a grpc::ClientContext::GetServerInitialMetadata() method.
145   ///
146   /// \warning This method should only be called before sending initial metadata
147   /// to the client (which can happen explicitly, or implicitly when sending a
148   /// a response message or status to the client).
149   ///
150   /// \param key The metadata key. If \a value is binary data, it must
151   /// end in "-bin".
152   /// \param value The metadata value. If its value is binary, the key name
153   /// must end in "-bin".
154   ///
155   /// Metadata must conform to the following format:
156   /// Custom-Metadata -> Binary-Header / ASCII-Header
157   /// Binary-Header -> {Header-Name "-bin" } {binary value}
158   /// ASCII-Header -> Header-Name ASCII-Value
159   /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - .
160   /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII
161   void AddInitialMetadata(const std::string& key, const std::string& value);
162 
163   /// Add the (\a key, \a value) pair to the initial metadata
164   /// associated with a server call. These are made available at the client
165   /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method.
166   ///
167   /// \warning This method should only be called before sending trailing
168   /// metadata to the client (which happens when the call is finished and a
169   /// status is sent to the client).
170   ///
171   /// \param key The metadata key. If \a value is binary data,
172   /// it must end in "-bin".
173   /// \param value The metadata value. If its value is binary, the key name
174   /// must end in "-bin".
175   ///
176   /// Metadata must conform to the following format:
177   /// Custom-Metadata -> Binary-Header / ASCII-Header
178   /// Binary-Header -> {Header-Name "-bin" } {binary value}
179   /// ASCII-Header -> Header-Name ASCII-Value
180   /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - .
181   /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII
182   void AddTrailingMetadata(const std::string& key, const std::string& value);
183 
184   /// Return whether this RPC failed before the server could provide its status
185   /// back to the client. This could be because of explicit API cancellation
186   /// from the client-side or server-side, because of deadline exceeded, network
187   /// connection reset, HTTP/2 parameter configuration (e.g., max message size,
188   /// max connection age), etc. It does NOT include failure due to a non-OK
189   /// status return from the server application's request handler, including
190   /// Status::CANCELLED.
191   ///
192   /// IsCancelled is always safe to call when using sync or callback API.
193   /// When using async API, it is only safe to call IsCancelled after
194   /// the AsyncNotifyWhenDone tag has been delivered. Thread-safe.
195   bool IsCancelled() const;
196 
197   /// Cancel the Call from the server. This is a best-effort API and
198   /// depending on when it is called, the RPC may still appear successful to
199   /// the client. For example, if TryCancel() is called on a separate thread, it
200   /// might race with the server handler which might return success to the
201   /// client before TryCancel() was even started by the thread.
202   ///
203   /// It is the caller's responsibility to prevent such races and ensure that if
204   /// TryCancel() is called, the serverhandler must return Status::CANCELLED.
205   /// The only exception is that if the serverhandler is already returning an
206   /// error status code, it is ok to not return Status::CANCELLED even if
207   /// TryCancel() was called.
208   ///
209   /// For reasons such as the above, it is generally preferred to explicitly
210   /// finish an RPC by returning Status::CANCELLED rather than using TryCancel.
211   ///
212   /// Note that TryCancel() does not change any of the tags that are pending
213   /// on the completion queue. All pending tags will still be delivered
214   /// (though their ok result may reflect the effect of cancellation).
215   void TryCancel() const;
216 
217   /// Return a collection of initial metadata key-value pairs sent from the
218   /// client. Note that keys may happen more than
219   /// once (ie, a \a std::multimap is returned).
220   ///
221   /// It is safe to use this method after initial metadata has been received,
222   /// Calls always begin with the client sending initial metadata, so this is
223   /// safe to access as soon as the call has begun on the server side.
224   ///
225   /// \return A multimap of initial metadata key-value pairs from the server.
client_metadata()226   const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata()
227       const {
228     return *client_metadata_.map();
229   }
230 
231   /// Return the compression algorithm to be used by the server call.
compression_level()232   grpc_compression_level compression_level() const {
233     return compression_level_;
234   }
235 
236   /// Set \a level to be the compression level used for the server call.
237   ///
238   /// \param level The compression level used for the server call.
set_compression_level(grpc_compression_level level)239   void set_compression_level(grpc_compression_level level) {
240     compression_level_set_ = true;
241     compression_level_ = level;
242   }
243 
244   /// Return a bool indicating whether the compression level for this call
245   /// has been set (either implicitly or through a previous call to
246   /// \a set_compression_level.
compression_level_set()247   bool compression_level_set() const { return compression_level_set_; }
248 
249   /// Return the compression algorithm the server call will request be used.
250   /// Note that the gRPC runtime may decide to ignore this request, for example,
251   /// due to resource constraints, or if the server is aware the client doesn't
252   /// support the requested algorithm.
compression_algorithm()253   grpc_compression_algorithm compression_algorithm() const {
254     return compression_algorithm_;
255   }
256   /// Set \a algorithm to be the compression algorithm used for the server call.
257   ///
258   /// \param algorithm The compression algorithm used for the server call.
259   void set_compression_algorithm(grpc_compression_algorithm algorithm);
260 
261   /// Set the serialized load reporting costs in \a cost_data for the call.
262   void SetLoadReportingCosts(const std::vector<std::string>& cost_data);
263 
264   /// Return the authentication context for this server call.
265   ///
266   /// \see grpc::AuthContext.
auth_context()267   std::shared_ptr<const ::grpc::AuthContext> auth_context() const {
268     if (auth_context_ == nullptr) {
269       auth_context_ = ::grpc::CreateAuthContext(call_.call);
270     }
271     return auth_context_;
272   }
273 
274   /// Return the peer uri in a string.
275   /// WARNING: this value is never authenticated or subject to any security
276   /// related code. It must not be used for any authentication related
277   /// functionality. Instead, use auth_context.
278   std::string peer() const;
279 
280   /// Get the census context associated with this server call.
281   const struct census_context* census_context() const;
282 
283   /// Should be used for framework-level extensions only.
284   /// Applications never need to call this method.
c_call()285   grpc_call* c_call() { return call_.call; }
286 
287  protected:
288   /// Async only. Has to be called before the rpc starts.
289   /// Returns the tag in completion queue when the rpc finishes.
290   /// IsCancelled() can then be called to check whether the rpc was cancelled.
291   /// TODO(vjpai): Fix this so that the tag is returned even if the call never
292   /// starts (https://github.com/grpc/grpc/issues/10136).
AsyncNotifyWhenDone(void * tag)293   void AsyncNotifyWhenDone(void* tag) {
294     has_notify_when_done_tag_ = true;
295     async_notify_when_done_tag_ = tag;
296   }
297 
298   /// NOTE: This is an API for advanced users who need custom allocators.
299   /// Get and maybe mutate the allocator state associated with the current RPC.
300   /// Currently only applicable for callback unary RPC methods.
301   /// WARNING: This is experimental API and could be changed or removed.
GetRpcAllocatorState()302   ::grpc::experimental::RpcAllocatorState* GetRpcAllocatorState() {
303     return message_allocator_state_;
304   }
305 
306   /// Get a library-owned default unary reactor for use in minimal reaction
307   /// cases. This supports typical unary RPC usage of providing a response and
308   /// status. It supports immediate Finish (finish from within the method
309   /// handler) or delayed Finish (finish called after the method handler
310   /// invocation). It does not support reacting to cancellation or completion,
311   /// or early sending of initial metadata. Since this is a library-owned
312   /// reactor, it should not be delete'd or freed in any way. This is more
313   /// efficient than creating a user-owned reactor both because of avoiding an
314   /// allocation and because its minimal reactions are optimized using a core
315   /// surface flag that allows their reactions to run inline without any
316   /// thread-hop.
317   ///
318   /// This method should not be called more than once or called after return
319   /// from the method handler.
320   ///
321   /// WARNING: This is experimental API and could be changed or removed.
DefaultReactor()322   ::grpc::ServerUnaryReactor* DefaultReactor() {
323     // Short-circuit the case where a default reactor was already set up by
324     // the TestPeer.
325     if (test_unary_ != nullptr) {
326       return reinterpret_cast<Reactor*>(&default_reactor_);
327     }
328     new (&default_reactor_) Reactor;
329 #ifndef NDEBUG
330     bool old = false;
331     assert(default_reactor_used_.compare_exchange_strong(
332         old, true, std::memory_order_relaxed));
333 #else
334     default_reactor_used_.store(true, std::memory_order_relaxed);
335 #endif
336     return reinterpret_cast<Reactor*>(&default_reactor_);
337   }
338 
339   /// Constructors for use by derived classes
340   ServerContextBase();
341   ServerContextBase(gpr_timespec deadline, grpc_metadata_array* arr);
342 
343  private:
344   friend class ::grpc::testing::InteropServerContextInspector;
345   friend class ::grpc::testing::ServerContextTestSpouse;
346   friend class ::grpc::testing::DefaultReactorTestPeer;
347   friend class ::grpc::ServerInterface;
348   friend class ::grpc::Server;
349   template <class W, class R>
350   friend class ::grpc::ServerAsyncReader;
351   template <class W>
352   friend class ::grpc::ServerAsyncWriter;
353   template <class W>
354   friend class ::grpc::ServerAsyncResponseWriter;
355   template <class W, class R>
356   friend class ::grpc::ServerAsyncReaderWriter;
357   template <class R>
358   friend class ::grpc::ServerReader;
359   template <class W>
360   friend class ::grpc::ServerWriter;
361   template <class W, class R>
362   friend class ::grpc::internal::ServerReaderWriterBody;
363   template <class ResponseType>
364   friend void ::grpc::internal::UnaryRunHandlerHelper(
365       const internal::MethodHandler::HandlerParameter& param, ResponseType* rsp,
366       Status& status);
367   template <class ServiceType, class RequestType, class ResponseType,
368             class BaseRequestType, class BaseResponseType>
369   friend class ::grpc::internal::RpcMethodHandler;
370   template <class ServiceType, class RequestType, class ResponseType>
371   friend class ::grpc::internal::ClientStreamingHandler;
372   template <class ServiceType, class RequestType, class ResponseType>
373   friend class ::grpc::internal::ServerStreamingHandler;
374   template <class Streamer, bool WriteNeeded>
375   friend class ::grpc::internal::TemplatedBidiStreamingHandler;
376   template <class RequestType, class ResponseType>
377   friend class ::grpc::internal::CallbackUnaryHandler;
378   template <class RequestType, class ResponseType>
379   friend class ::grpc::internal::CallbackClientStreamingHandler;
380   template <class RequestType, class ResponseType>
381   friend class ::grpc::internal::CallbackServerStreamingHandler;
382   template <class RequestType, class ResponseType>
383   friend class ::grpc::internal::CallbackBidiHandler;
384   template <::grpc::StatusCode code>
385   friend class ::grpc::internal::ErrorMethodHandler;
386   template <class Base>
387   friend class ::grpc::internal::FinishOnlyReactor;
388   friend class ::grpc::ClientContext;
389   friend class ::grpc::GenericServerContext;
390 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
391   friend class ::grpc::GenericCallbackServerContext;
392 #else
393   friend class ::grpc::experimental::GenericCallbackServerContext;
394 #endif
395 
396   /// Prevent copying.
397   ServerContextBase(const ServerContextBase&);
398   ServerContextBase& operator=(const ServerContextBase&);
399 
400   class CompletionOp;
401 
402   void BeginCompletionOp(
403       ::grpc::internal::Call* call, std::function<void(bool)> callback,
404       ::grpc::internal::ServerCallbackCall* callback_controller);
405   /// Return the tag queued by BeginCompletionOp()
406   ::grpc::internal::CompletionQueueTag* GetCompletionOpTag();
407 
set_call(grpc_call * call)408   void set_call(grpc_call* call) { call_.call = call; }
409 
410   void BindDeadlineAndMetadata(gpr_timespec deadline, grpc_metadata_array* arr);
411 
initial_metadata_flags()412   uint32_t initial_metadata_flags() const { return 0; }
413 
set_server_rpc_info(const char * method,::grpc::internal::RpcMethod::RpcType type,const std::vector<std::unique_ptr<::grpc::experimental::ServerInterceptorFactoryInterface>> & creators)414   ::grpc::experimental::ServerRpcInfo* set_server_rpc_info(
415       const char* method, ::grpc::internal::RpcMethod::RpcType type,
416       const std::vector<std::unique_ptr<
417           ::grpc::experimental::ServerInterceptorFactoryInterface>>& creators) {
418     if (!creators.empty()) {
419       rpc_info_ = new ::grpc::experimental::ServerRpcInfo(this, method, type);
420       rpc_info_->RegisterInterceptors(creators);
421     }
422     return rpc_info_;
423   }
424 
set_message_allocator_state(::grpc::experimental::RpcAllocatorState * allocator_state)425   void set_message_allocator_state(
426       ::grpc::experimental::RpcAllocatorState* allocator_state) {
427     message_allocator_state_ = allocator_state;
428   }
429 
430   struct CallWrapper {
431     ~CallWrapper();
432 
433     grpc_call* call = nullptr;
434   };
435 
436   // NOTE: call_ must be the first data member of this object so that its
437   //       destructor is the last to be called, since its destructor may unref
438   //       the underlying core call which holds the arena that may be used to
439   //       hold this object.
440   CallWrapper call_;
441 
442   CompletionOp* completion_op_ = nullptr;
443   bool has_notify_when_done_tag_ = false;
444   void* async_notify_when_done_tag_ = nullptr;
445   ::grpc::internal::CallbackWithSuccessTag completion_tag_;
446 
447   gpr_timespec deadline_;
448   ::grpc::CompletionQueue* cq_ = nullptr;
449   bool sent_initial_metadata_ = false;
450   mutable std::shared_ptr<const ::grpc::AuthContext> auth_context_;
451   mutable ::grpc::internal::MetadataMap client_metadata_;
452   std::multimap<std::string, std::string> initial_metadata_;
453   std::multimap<std::string, std::string> trailing_metadata_;
454 
455   bool compression_level_set_ = false;
456   grpc_compression_level compression_level_;
457   grpc_compression_algorithm compression_algorithm_;
458 
459   ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
460                               ::grpc::internal::CallOpSendMessage>
461       pending_ops_;
462   bool has_pending_ops_ = false;
463 
464   ::grpc::experimental::ServerRpcInfo* rpc_info_ = nullptr;
465   ::grpc::experimental::RpcAllocatorState* message_allocator_state_ = nullptr;
466 
467   class Reactor : public ::grpc::ServerUnaryReactor {
468    public:
OnCancel()469     void OnCancel() override {}
OnDone()470     void OnDone() override {}
471     // Override InternalInlineable for this class since its reactions are
472     // trivial and thus do not need to be run from the executor (triggering a
473     // thread hop). This should only be used by internal reactors (thus the
474     // name) and not by user application code.
InternalInlineable()475     bool InternalInlineable() override { return true; }
476   };
477 
SetupTestDefaultReactor(std::function<void (::grpc::Status)> func)478   void SetupTestDefaultReactor(std::function<void(::grpc::Status)> func) {
479     // NOLINTNEXTLINE(modernize-make-unique)
480     test_unary_.reset(new TestServerCallbackUnary(this, std::move(func)));
481   }
test_status_set()482   bool test_status_set() const {
483     return (test_unary_ != nullptr) && test_unary_->status_set();
484   }
test_status()485   ::grpc::Status test_status() const { return test_unary_->status(); }
486 
487   class TestServerCallbackUnary : public ::grpc::ServerCallbackUnary {
488    public:
TestServerCallbackUnary(ServerContextBase * ctx,std::function<void (::grpc::Status)> func)489     TestServerCallbackUnary(ServerContextBase* ctx,
490                             std::function<void(::grpc::Status)> func)
491         : reactor_(ctx->DefaultReactor()), func_(std::move(func)) {
492       this->BindReactor(reactor_);
493     }
Finish(::grpc::Status s)494     void Finish(::grpc::Status s) override {
495       status_ = s;
496       func_(std::move(s));
497       status_set_.store(true, std::memory_order_release);
498     }
SendInitialMetadata()499     void SendInitialMetadata() override {}
500 
status_set()501     bool status_set() const {
502       return status_set_.load(std::memory_order_acquire);
503     }
status()504     ::grpc::Status status() const { return status_; }
505 
506    private:
CallOnDone()507     void CallOnDone() override {}
reactor()508     ::grpc::internal::ServerReactor* reactor() override { return reactor_; }
509 
510     ::grpc::ServerUnaryReactor* const reactor_;
511     std::atomic_bool status_set_{false};
512     ::grpc::Status status_;
513     const std::function<void(::grpc::Status s)> func_;
514   };
515 
516   typename std::aligned_storage<sizeof(Reactor), alignof(Reactor)>::type
517       default_reactor_;
518   std::atomic_bool default_reactor_used_{false};
519   std::unique_ptr<TestServerCallbackUnary> test_unary_;
520 };
521 
522 /// A ServerContext or CallbackServerContext allows the code implementing a
523 /// service handler to:
524 ///
525 /// - Add custom initial and trailing metadata key-value pairs that will
526 ///   propagated to the client side.
527 /// - Control call settings such as compression and authentication.
528 /// - Access metadata coming from the client.
529 /// - Get performance metrics (ie, census).
530 ///
531 /// Context settings are only relevant to the call handler they are supplied to,
532 /// that is to say, they aren't sticky across multiple calls. Some of these
533 /// settings, such as the compression options, can be made persistent at server
534 /// construction time by specifying the appropriate \a ChannelArguments
535 /// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument.
536 ///
537 /// \warning ServerContext instances should \em not be reused across rpcs.
538 class ServerContext : public ServerContextBase {
539  public:
ServerContext()540   ServerContext() {}  // for async calls
541 
542   using ServerContextBase::AddInitialMetadata;
543   using ServerContextBase::AddTrailingMetadata;
544   using ServerContextBase::auth_context;
545   using ServerContextBase::c_call;
546   using ServerContextBase::census_context;
547   using ServerContextBase::client_metadata;
548   using ServerContextBase::compression_algorithm;
549   using ServerContextBase::compression_level;
550   using ServerContextBase::compression_level_set;
551   using ServerContextBase::deadline;
552   using ServerContextBase::IsCancelled;
553   using ServerContextBase::peer;
554   using ServerContextBase::raw_deadline;
555   using ServerContextBase::set_compression_algorithm;
556   using ServerContextBase::set_compression_level;
557   using ServerContextBase::SetLoadReportingCosts;
558   using ServerContextBase::TryCancel;
559 
560   // Sync/CQ-based Async ServerContext only
561   using ServerContextBase::AsyncNotifyWhenDone;
562 
563  private:
564   // Constructor for internal use by server only
565   friend class ::grpc::Server;
ServerContext(gpr_timespec deadline,grpc_metadata_array * arr)566   ServerContext(gpr_timespec deadline, grpc_metadata_array* arr)
567       : ServerContextBase(deadline, arr) {}
568 
569   // CallbackServerContext only
570   using ServerContextBase::DefaultReactor;
571   using ServerContextBase::GetRpcAllocatorState;
572 
573   /// Prevent copying.
574   ServerContext(const ServerContext&) = delete;
575   ServerContext& operator=(const ServerContext&) = delete;
576 };
577 
578 class CallbackServerContext : public ServerContextBase {
579  public:
580   /// Public constructors are for direct use only by mocking tests. In practice,
581   /// these objects will be owned by the library.
CallbackServerContext()582   CallbackServerContext() {}
583 
584   using ServerContextBase::AddInitialMetadata;
585   using ServerContextBase::AddTrailingMetadata;
586   using ServerContextBase::auth_context;
587   using ServerContextBase::c_call;
588   using ServerContextBase::census_context;
589   using ServerContextBase::client_metadata;
590   using ServerContextBase::compression_algorithm;
591   using ServerContextBase::compression_level;
592   using ServerContextBase::compression_level_set;
593   using ServerContextBase::deadline;
594   using ServerContextBase::IsCancelled;
595   using ServerContextBase::peer;
596   using ServerContextBase::raw_deadline;
597   using ServerContextBase::set_compression_algorithm;
598   using ServerContextBase::set_compression_level;
599   using ServerContextBase::SetLoadReportingCosts;
600   using ServerContextBase::TryCancel;
601 
602   // CallbackServerContext only
603   using ServerContextBase::DefaultReactor;
604   using ServerContextBase::GetRpcAllocatorState;
605 
606  private:
607   // Sync/CQ-based Async ServerContext only
608   using ServerContextBase::AsyncNotifyWhenDone;
609 
610   /// Prevent copying.
611   CallbackServerContext(const CallbackServerContext&) = delete;
612   CallbackServerContext& operator=(const CallbackServerContext&) = delete;
613 };
614 
615 }  // namespace grpc
616 
617 static_assert(
618     std::is_base_of<::grpc::ServerContextBase, ::grpc::ServerContext>::value,
619     "improper base class");
620 static_assert(std::is_base_of<::grpc::ServerContextBase,
621                               ::grpc::CallbackServerContext>::value,
622               "improper base class");
623 static_assert(sizeof(::grpc::ServerContextBase) ==
624                   sizeof(::grpc::ServerContext),
625               "wrong size");
626 static_assert(sizeof(::grpc::ServerContextBase) ==
627                   sizeof(::grpc::CallbackServerContext),
628               "wrong size");
629 
630 #endif  // GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
631