| // Protocol Buffers - Google's data interchange format |
| // Copyright 2024 Google LLC. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file or at |
| // https://developers.google.com/open-source/licenses/bsd |
| |
| #ifndef GOOGLE_PROTOBUF_HPB_EXTENSION_H__ |
| #define GOOGLE_PROTOBUF_HPB_EXTENSION_H__ |
| |
| #include <cstdint> |
| #include <vector> |
| |
| #include "upb/mem/arena.hpp" |
| #include "upb/mini_table/extension.h" |
| #include "upb/mini_table/extension_registry.h" |
| |
| namespace hpb { |
| class ExtensionRegistry; |
| |
| namespace internal { |
| |
| class ExtensionMiniTableProvider { |
| public: |
| constexpr explicit ExtensionMiniTableProvider( |
| const upb_MiniTableExtension* mini_table_ext) |
| : mini_table_ext_(mini_table_ext) {} |
| const upb_MiniTableExtension* mini_table_ext() const { |
| return mini_table_ext_; |
| } |
| |
| private: |
| const upb_MiniTableExtension* mini_table_ext_; |
| }; |
| |
| // ------------------------------------------------------------------- |
| // ExtensionIdentifier |
| // This is the type of actual extension objects. E.g. if you have: |
| // extend Foo { |
| // optional MyExtension bar = 1234; |
| // } |
| // then "bar" will be defined in C++ as: |
| // ExtensionIdentifier<Foo, MyExtension> bar(&namespace_bar_ext); |
| template <typename ExtendeeType, typename ExtensionType> |
| class ExtensionIdentifier : public ExtensionMiniTableProvider { |
| public: |
| using Extension = ExtensionType; |
| using Extendee = ExtendeeType; |
| |
| constexpr explicit ExtensionIdentifier( |
| const upb_MiniTableExtension* mini_table_ext) |
| : ExtensionMiniTableProvider(mini_table_ext) {} |
| |
| private: |
| constexpr uint32_t number() const { |
| return upb_MiniTableExtension_Number(mini_table_ext()); |
| } |
| friend struct PrivateAccess; |
| }; |
| |
| upb_ExtensionRegistry* GetUpbExtensions( |
| const ExtensionRegistry& extension_registry); |
| |
| } // namespace internal |
| |
| class ExtensionRegistry { |
| public: |
| ExtensionRegistry( |
| const std::vector<const internal::ExtensionMiniTableProvider*>& |
| extensions, |
| const upb::Arena& arena) |
| : registry_(upb_ExtensionRegistry_New(arena.ptr())) { |
| if (registry_) { |
| for (const auto& ext_provider : extensions) { |
| const auto* ext = ext_provider->mini_table_ext(); |
| bool success = upb_ExtensionRegistry_AddArray(registry_, &ext, 1); |
| if (!success) { |
| registry_ = nullptr; |
| break; |
| } |
| } |
| } |
| } |
| |
| private: |
| friend upb_ExtensionRegistry* ::hpb::internal::GetUpbExtensions( |
| const ExtensionRegistry& extension_registry); |
| upb_ExtensionRegistry* registry_; |
| }; |
| } // namespace hpb |
| |
| #endif // GOOGLE_PROTOBUF_HPB_EXTENSION_H__ |