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/event_engine/event_engine.h> 18 #include <grpc/support/port_platform.h> 19 20 #include "absl/strings/string_view.h" 21 22 namespace grpc_event_engine { 23 namespace experimental { 24 25 namespace endpoint_detail { 26 27 template <typename Querying, typename... Es> 28 struct QueryExtensionRecursion; 29 30 template <typename Querying, typename E, typename... Es> 31 struct QueryExtensionRecursion<Querying, E, Es...> { 32 static void* Query(absl::string_view id, Querying* p) { 33 if (id == E::EndpointExtensionName()) return static_cast<E*>(p); 34 return QueryExtensionRecursion<Querying, Es...>::Query(id, p); 35 } 36 }; 37 38 template <typename Querying> 39 struct QueryExtensionRecursion<Querying> { 40 static void* Query(absl::string_view, Querying*) { return nullptr; } 41 }; 42 43 } // namespace endpoint_detail 44 45 // A helper class to derive from some set of base classes and export 46 // QueryExtension for them all. 47 // EventEngine Extensible object implementations which need to support different 48 // extensions just need to derive from this class. 49 template <typename EEClass, typename... Exports> 50 class ExtendedType : public EEClass, public Exports... { 51 public: 52 void* QueryExtension(absl::string_view id) override { 53 return endpoint_detail::QueryExtensionRecursion<ExtendedType, 54 Exports...>::Query(id, 55 this); 56 } 57 }; 58 59 /// A helper method which returns a valid pointer if the extension is 60 /// supported by the endpoint. 61 template <typename T> 62 T* QueryExtension(EventEngine::Endpoint* endpoint) { 63 if (endpoint == nullptr) return nullptr; 64 return static_cast<T*>(endpoint->QueryExtension(T::EndpointExtensionName())); 65 } 66 67 /// A helper method which returns a valid pointer if the extension is 68 /// supported by the listener. 69 template <typename T> 70 T* QueryExtension(EventEngine::Listener* listener) { 71 if (listener == nullptr) return nullptr; 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 if (engine == nullptr) return nullptr; 80 return static_cast<T*>(engine->QueryExtension(T::EndpointExtensionName())); 81 } 82 83 } // namespace experimental 84 } // namespace grpc_event_engine 85 86 #endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_QUERY_EXTENSIONS_H 87