• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2024 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef GOOGLE_PROTOBUF_HPB_EXTENSION_H__
9 #define GOOGLE_PROTOBUF_HPB_EXTENSION_H__
10 
11 #include <cstdint>
12 #include <vector>
13 
14 #include "upb/mem/arena.hpp"
15 #include "upb/mini_table/extension.h"
16 #include "upb/mini_table/extension_registry.h"
17 
18 namespace hpb {
19 class ExtensionRegistry;
20 
21 namespace internal {
22 
23 class ExtensionMiniTableProvider {
24  public:
ExtensionMiniTableProvider(const upb_MiniTableExtension * mini_table_ext)25   constexpr explicit ExtensionMiniTableProvider(
26       const upb_MiniTableExtension* mini_table_ext)
27       : mini_table_ext_(mini_table_ext) {}
mini_table_ext()28   const upb_MiniTableExtension* mini_table_ext() const {
29     return mini_table_ext_;
30   }
31 
32  private:
33   const upb_MiniTableExtension* mini_table_ext_;
34 };
35 
36 // -------------------------------------------------------------------
37 // ExtensionIdentifier
38 // This is the type of actual extension objects.  E.g. if you have:
39 //   extend Foo {
40 //     optional MyExtension bar = 1234;
41 //   }
42 // then "bar" will be defined in C++ as:
43 //   ExtensionIdentifier<Foo, MyExtension> bar(&namespace_bar_ext);
44 template <typename ExtendeeType, typename ExtensionType>
45 class ExtensionIdentifier : public ExtensionMiniTableProvider {
46  public:
47   using Extension = ExtensionType;
48   using Extendee = ExtendeeType;
49 
ExtensionIdentifier(const upb_MiniTableExtension * mini_table_ext)50   constexpr explicit ExtensionIdentifier(
51       const upb_MiniTableExtension* mini_table_ext)
52       : ExtensionMiniTableProvider(mini_table_ext) {}
53 
54  private:
number()55   constexpr uint32_t number() const {
56     return upb_MiniTableExtension_Number(mini_table_ext());
57   }
58   friend struct PrivateAccess;
59 };
60 
61 upb_ExtensionRegistry* GetUpbExtensions(
62     const ExtensionRegistry& extension_registry);
63 
64 }  // namespace internal
65 
66 class ExtensionRegistry {
67  public:
ExtensionRegistry(const std::vector<const internal::ExtensionMiniTableProvider * > & extensions,const upb::Arena & arena)68   ExtensionRegistry(
69       const std::vector<const internal::ExtensionMiniTableProvider*>&
70           extensions,
71       const upb::Arena& arena)
72       : registry_(upb_ExtensionRegistry_New(arena.ptr())) {
73     if (registry_) {
74       for (const auto& ext_provider : extensions) {
75         const auto* ext = ext_provider->mini_table_ext();
76         bool success = upb_ExtensionRegistry_AddArray(registry_, &ext, 1);
77         if (!success) {
78           registry_ = nullptr;
79           break;
80         }
81       }
82     }
83   }
84 
85  private:
86   friend upb_ExtensionRegistry* ::hpb::internal::GetUpbExtensions(
87       const ExtensionRegistry& extension_registry);
88   upb_ExtensionRegistry* registry_;
89 };
90 }  // namespace hpb
91 
92 #endif  // GOOGLE_PROTOBUF_HPB_EXTENSION_H__
93