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