1 // Copyright 2023 gRPC Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_QUERY_EXTENSIONS_H 15 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_QUERY_EXTENSIONS_H 16 17 #include <grpc/support/port_platform.h> 18 19 #include "absl/strings/string_view.h" 20 21 #include <grpc/event_engine/event_engine.h> 22 23 namespace grpc_event_engine { 24 namespace experimental { 25 26 namespace endpoint_detail { 27 28 template <typename Querying, typename... Es> 29 struct QueryExtensionRecursion; 30 31 template <typename Querying, typename E, typename... Es> 32 struct QueryExtensionRecursion<Querying, E, Es...> { 33 static void* Query(absl::string_view id, Querying* p) { 34 if (id == E::EndpointExtensionName()) return static_cast<E*>(p); 35 return QueryExtensionRecursion<Querying, Es...>::Query(id, p); 36 } 37 }; 38 39 template <typename Querying> 40 struct QueryExtensionRecursion<Querying> { 41 static void* Query(absl::string_view, Querying*) { return nullptr; } 42 }; 43 44 } // namespace endpoint_detail 45 46 // A helper class to derive from some set of base classes and export 47 // QueryExtension for them all. 48 // EventEngine Extensible object implementations which need to support different 49 // extensions just need to derive from this class. 50 template <typename EEClass, typename... Exports> 51 class ExtendedType : public EEClass, public Exports... { 52 public: 53 void* QueryExtension(absl::string_view id) override { 54 return endpoint_detail::QueryExtensionRecursion<ExtendedType, 55 Exports...>::Query(id, 56 this); 57 } 58 }; 59 60 /// A helper method which returns a valid pointer if the extension is 61 /// supported by the endpoint. 62 template <typename T> 63 T* QueryExtension(EventEngine::Endpoint* endpoint) { 64 if (endpoint == nullptr) return nullptr; 65 return static_cast<T*>(endpoint->QueryExtension(T::EndpointExtensionName())); 66 } 67 68 /// A helper method which returns a valid pointer if the extension is 69 /// supported by the listener. 70 template <typename T> 71 T* QueryExtension(EventEngine::Listener* listener) { 72 return static_cast<T*>(listener->QueryExtension(T::EndpointExtensionName())); 73 } 74 75 /// A helper method which returns a valid pointer if the extension is 76 /// supported by the EventEngine. 77 template <typename T> 78 T* QueryExtension(EventEngine* engine) { 79 return static_cast<T*>(engine->QueryExtension(T::EndpointExtensionName())); 80 } 81 82 } // namespace experimental 83 } // namespace grpc_event_engine 84 85 #endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_QUERY_EXTENSIONS_H 86