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