1 // Copyright (c) 2009-2021, Google LLC
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above copyright
9 //       notice, this list of conditions and the following disclaimer in the
10 //       documentation and/or other materials provided with the distribution.
11 //     * Neither the name of Google LLC nor the
12 //       names of its contributors may be used to endorse or promote products
13 //       derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
19 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #ifndef UPB_REFLECTION_DEF_HPP_
27 #define UPB_REFLECTION_DEF_HPP_
28 
29 #include <cstring>
30 #include <memory>
31 #include <string>
32 #include <vector>
33 
34 #include "upb/reflection/def.h"
35 #include "upb/reflection/def_pool_internal.h"
36 #include "upb/reflection/enum_def_internal.h"
37 #include "upb/reflection/message.h"
38 #include "upb/upb.hpp"
39 
40 // Must be last
41 #include "upb/port/def.inc"
42 
43 namespace upb {
44 
45 typedef upb_MessageValue MessageValue;
46 
47 class EnumDefPtr;
48 class FileDefPtr;
49 class MessageDefPtr;
50 class OneofDefPtr;
51 
52 // A upb::FieldDefPtr describes a single field in a message.  It is most often
53 // found as a part of a upb_MessageDef, but can also stand alone to represent
54 // an extension.
55 class FieldDefPtr {
56  public:
FieldDefPtr()57   FieldDefPtr() : ptr_(nullptr) {}
FieldDefPtr(const upb_FieldDef * ptr)58   explicit FieldDefPtr(const upb_FieldDef* ptr) : ptr_(ptr) {}
59 
ptr() const60   const upb_FieldDef* ptr() const { return ptr_; }
61 
62   typedef upb_FieldType Type;
63   typedef upb_CType CType;
64   typedef upb_Label Label;
65 
66   FileDefPtr file() const;
full_name() const67   const char* full_name() const { return upb_FieldDef_FullName(ptr_); }
68 
mini_table() const69   const upb_MiniTableField* mini_table() const {
70     return upb_FieldDef_MiniTable(ptr_);
71   }
72 
UPB_DESC(FieldOptions)73   const UPB_DESC(FieldOptions) * options() const {
74     return upb_FieldDef_Options(ptr_);
75   }
76 
type() const77   Type type() const { return upb_FieldDef_Type(ptr_); }
ctype() const78   CType ctype() const { return upb_FieldDef_CType(ptr_); }
label() const79   Label label() const { return upb_FieldDef_Label(ptr_); }
name() const80   const char* name() const { return upb_FieldDef_Name(ptr_); }
json_name() const81   const char* json_name() const { return upb_FieldDef_JsonName(ptr_); }
number() const82   uint32_t number() const { return upb_FieldDef_Number(ptr_); }
is_extension() const83   bool is_extension() const { return upb_FieldDef_IsExtension(ptr_); }
is_required() const84   bool is_required() const { return upb_FieldDef_IsRequired(ptr_); }
has_presence() const85   bool has_presence() const { return upb_FieldDef_HasPresence(ptr_); }
86 
87   // For non-string, non-submessage fields, this indicates whether binary
88   // protobufs are encoded in packed or non-packed format.
89   //
90   // Note: this accessor reflects the fact that "packed" has different defaults
91   // depending on whether the proto is proto2 or proto3.
packed() const92   bool packed() const { return upb_FieldDef_IsPacked(ptr_); }
93 
94   // An integer that can be used as an index into an array of fields for
95   // whatever message this field belongs to.  Guaranteed to be less than
96   // f->containing_type()->field_count().  May only be accessed once the def has
97   // been finalized.
index() const98   uint32_t index() const { return upb_FieldDef_Index(ptr_); }
99 
100   // The MessageDef to which this field belongs (for extensions, the extended
101   // message).
102   MessageDefPtr containing_type() const;
103 
104   // For extensions, the message the extension is declared inside, or NULL if
105   // none.
106   MessageDefPtr extension_scope() const;
107 
108   // The OneofDef to which this field belongs, or NULL if this field is not part
109   // of a oneof.
110   OneofDefPtr containing_oneof() const;
111   OneofDefPtr real_containing_oneof() const;
112 
113   // Convenient field type tests.
IsSubMessage() const114   bool IsSubMessage() const { return upb_FieldDef_IsSubMessage(ptr_); }
IsString() const115   bool IsString() const { return upb_FieldDef_IsString(ptr_); }
IsSequence() const116   bool IsSequence() const { return upb_FieldDef_IsRepeated(ptr_); }
IsPrimitive() const117   bool IsPrimitive() const { return upb_FieldDef_IsPrimitive(ptr_); }
IsMap() const118   bool IsMap() const { return upb_FieldDef_IsMap(ptr_); }
119 
default_value() const120   MessageValue default_value() const { return upb_FieldDef_Default(ptr_); }
121 
122   // Returns the enum or submessage def for this field, if any.  The field's
123   // type must match (ie. you may only call enum_subdef() for fields where
124   // type() == kUpb_CType_Enum).
125   EnumDefPtr enum_subdef() const;
126   MessageDefPtr message_type() const;
127 
operator bool() const128   explicit operator bool() const { return ptr_ != nullptr; }
129 
operator ==(FieldDefPtr lhs,FieldDefPtr rhs)130   friend bool operator==(FieldDefPtr lhs, FieldDefPtr rhs) {
131     return lhs.ptr_ == rhs.ptr_;
132   }
133 
operator !=(FieldDefPtr lhs,FieldDefPtr rhs)134   friend bool operator!=(FieldDefPtr lhs, FieldDefPtr rhs) {
135     return !(lhs == rhs);
136   }
137 
138  private:
139   const upb_FieldDef* ptr_;
140 };
141 
142 // Class that represents a oneof.
143 class OneofDefPtr {
144  public:
OneofDefPtr()145   OneofDefPtr() : ptr_(nullptr) {}
OneofDefPtr(const upb_OneofDef * ptr)146   explicit OneofDefPtr(const upb_OneofDef* ptr) : ptr_(ptr) {}
147 
ptr() const148   const upb_OneofDef* ptr() const { return ptr_; }
operator bool() const149   explicit operator bool() const { return ptr_ != nullptr; }
150 
UPB_DESC(OneofOptions)151   const UPB_DESC(OneofOptions) * options() const {
152     return upb_OneofDef_Options(ptr_);
153   }
154 
155   // Returns the MessageDef that contains this OneofDef.
156   MessageDefPtr containing_type() const;
157 
158   // Returns the name of this oneof.
name() const159   const char* name() const { return upb_OneofDef_Name(ptr_); }
full_name() const160   const char* full_name() const { return upb_OneofDef_FullName(ptr_); }
161 
162   // Returns the number of fields in the oneof.
field_count() const163   int field_count() const { return upb_OneofDef_FieldCount(ptr_); }
field(int i) const164   FieldDefPtr field(int i) const {
165     return FieldDefPtr(upb_OneofDef_Field(ptr_, i));
166   }
167 
168   // Looks up by name.
FindFieldByName(const char * name,size_t len) const169   FieldDefPtr FindFieldByName(const char* name, size_t len) const {
170     return FieldDefPtr(upb_OneofDef_LookupNameWithSize(ptr_, name, len));
171   }
FindFieldByName(const char * name) const172   FieldDefPtr FindFieldByName(const char* name) const {
173     return FieldDefPtr(upb_OneofDef_LookupName(ptr_, name));
174   }
175 
176   template <class T>
FindFieldByName(const T & str) const177   FieldDefPtr FindFieldByName(const T& str) const {
178     return FindFieldByName(str.c_str(), str.size());
179   }
180 
181   // Looks up by tag number.
FindFieldByNumber(uint32_t num) const182   FieldDefPtr FindFieldByNumber(uint32_t num) const {
183     return FieldDefPtr(upb_OneofDef_LookupNumber(ptr_, num));
184   }
185 
186  private:
187   const upb_OneofDef* ptr_;
188 };
189 
190 // Structure that describes a single .proto message type.
191 class MessageDefPtr {
192  public:
MessageDefPtr()193   MessageDefPtr() : ptr_(nullptr) {}
MessageDefPtr(const upb_MessageDef * ptr)194   explicit MessageDefPtr(const upb_MessageDef* ptr) : ptr_(ptr) {}
195 
UPB_DESC(MessageOptions)196   const UPB_DESC(MessageOptions) * options() const {
197     return upb_MessageDef_Options(ptr_);
198   }
199 
MiniDescriptorEncode() const200   std::string MiniDescriptorEncode() const {
201     upb::Arena arena;
202     upb_StringView md;
203     upb_MessageDef_MiniDescriptorEncode(ptr_, arena.ptr(), &md);
204     return std::string(md.data, md.size);
205   }
206 
ptr() const207   const upb_MessageDef* ptr() const { return ptr_; }
208 
209   FileDefPtr file() const;
210 
full_name() const211   const char* full_name() const { return upb_MessageDef_FullName(ptr_); }
name() const212   const char* name() const { return upb_MessageDef_Name(ptr_); }
213 
mini_table() const214   const upb_MiniTable* mini_table() const {
215     return upb_MessageDef_MiniTable(ptr_);
216   }
217 
218   // The number of fields that belong to the MessageDef.
field_count() const219   int field_count() const { return upb_MessageDef_FieldCount(ptr_); }
field(int i) const220   FieldDefPtr field(int i) const {
221     return FieldDefPtr(upb_MessageDef_Field(ptr_, i));
222   }
223 
224   // The number of oneofs that belong to the MessageDef.
oneof_count() const225   int oneof_count() const { return upb_MessageDef_OneofCount(ptr_); }
real_oneof_count() const226   int real_oneof_count() const { return upb_MessageDef_RealOneofCount(ptr_); }
oneof(int i) const227   OneofDefPtr oneof(int i) const {
228     return OneofDefPtr(upb_MessageDef_Oneof(ptr_, i));
229   }
230 
enum_type_count() const231   int enum_type_count() const { return upb_MessageDef_NestedEnumCount(ptr_); }
232   EnumDefPtr enum_type(int i) const;
233 
nested_message_count() const234   int nested_message_count() const {
235     return upb_MessageDef_NestedMessageCount(ptr_);
236   }
nested_message(int i) const237   MessageDefPtr nested_message(int i) const {
238     return MessageDefPtr(upb_MessageDef_NestedMessage(ptr_, i));
239   }
240 
nested_extension_count() const241   int nested_extension_count() const {
242     return upb_MessageDef_NestedExtensionCount(ptr_);
243   }
nested_extension(int i) const244   FieldDefPtr nested_extension(int i) const {
245     return FieldDefPtr(upb_MessageDef_NestedExtension(ptr_, i));
246   }
247 
extension_range_count() const248   int extension_range_count() const {
249     return upb_MessageDef_ExtensionRangeCount(ptr_);
250   }
251 
syntax() const252   upb_Syntax syntax() const { return upb_MessageDef_Syntax(ptr_); }
253 
254   // These return null pointers if the field is not found.
FindFieldByNumber(uint32_t number) const255   FieldDefPtr FindFieldByNumber(uint32_t number) const {
256     return FieldDefPtr(upb_MessageDef_FindFieldByNumber(ptr_, number));
257   }
FindFieldByName(const char * name,size_t len) const258   FieldDefPtr FindFieldByName(const char* name, size_t len) const {
259     return FieldDefPtr(upb_MessageDef_FindFieldByNameWithSize(ptr_, name, len));
260   }
FindFieldByName(const char * name) const261   FieldDefPtr FindFieldByName(const char* name) const {
262     return FieldDefPtr(upb_MessageDef_FindFieldByName(ptr_, name));
263   }
264 
265   template <class T>
FindFieldByName(const T & str) const266   FieldDefPtr FindFieldByName(const T& str) const {
267     return FindFieldByName(str.c_str(), str.size());
268   }
269 
FindOneofByName(const char * name,size_t len) const270   OneofDefPtr FindOneofByName(const char* name, size_t len) const {
271     return OneofDefPtr(upb_MessageDef_FindOneofByNameWithSize(ptr_, name, len));
272   }
273 
FindOneofByName(const char * name) const274   OneofDefPtr FindOneofByName(const char* name) const {
275     return OneofDefPtr(upb_MessageDef_FindOneofByName(ptr_, name));
276   }
277 
278   template <class T>
FindOneofByName(const T & str) const279   OneofDefPtr FindOneofByName(const T& str) const {
280     return FindOneofByName(str.c_str(), str.size());
281   }
282 
283   // Is this message a map entry?
mapentry() const284   bool mapentry() const { return upb_MessageDef_IsMapEntry(ptr_); }
285 
map_key() const286   FieldDefPtr map_key() const {
287     if (!mapentry()) return FieldDefPtr();
288     return FieldDefPtr(upb_MessageDef_Field(ptr_, 0));
289   }
290 
map_value() const291   FieldDefPtr map_value() const {
292     if (!mapentry()) return FieldDefPtr();
293     return FieldDefPtr(upb_MessageDef_Field(ptr_, 1));
294   }
295 
296   // Return the type of well known type message. kUpb_WellKnown_Unspecified for
297   // non-well-known message.
wellknowntype() const298   upb_WellKnown wellknowntype() const {
299     return upb_MessageDef_WellKnownType(ptr_);
300   }
301 
operator bool() const302   explicit operator bool() const { return ptr_ != nullptr; }
303 
operator ==(MessageDefPtr lhs,MessageDefPtr rhs)304   friend bool operator==(MessageDefPtr lhs, MessageDefPtr rhs) {
305     return lhs.ptr_ == rhs.ptr_;
306   }
307 
operator !=(MessageDefPtr lhs,MessageDefPtr rhs)308   friend bool operator!=(MessageDefPtr lhs, MessageDefPtr rhs) {
309     return !(lhs == rhs);
310   }
311 
312  private:
313   class FieldIter {
314    public:
FieldIter(const upb_MessageDef * m,int i)315     explicit FieldIter(const upb_MessageDef* m, int i) : m_(m), i_(i) {}
operator ++()316     void operator++() { i_++; }
317 
operator *()318     FieldDefPtr operator*() {
319       return FieldDefPtr(upb_MessageDef_Field(m_, i_));
320     }
operator !=(const FieldIter & other)321     bool operator!=(const FieldIter& other) { return i_ != other.i_; }
operator ==(const FieldIter & other)322     bool operator==(const FieldIter& other) { return i_ == other.i_; }
323 
324    private:
325     const upb_MessageDef* m_;
326     int i_;
327   };
328 
329   class FieldAccessor {
330    public:
FieldAccessor(const upb_MessageDef * md)331     explicit FieldAccessor(const upb_MessageDef* md) : md_(md) {}
begin()332     FieldIter begin() { return FieldIter(md_, 0); }
end()333     FieldIter end() { return FieldIter(md_, upb_MessageDef_FieldCount(md_)); }
334 
335    private:
336     const upb_MessageDef* md_;
337   };
338 
339   class OneofIter {
340    public:
OneofIter(const upb_MessageDef * m,int i)341     explicit OneofIter(const upb_MessageDef* m, int i) : m_(m), i_(i) {}
operator ++()342     void operator++() { i_++; }
343 
operator *()344     OneofDefPtr operator*() {
345       return OneofDefPtr(upb_MessageDef_Oneof(m_, i_));
346     }
operator !=(const OneofIter & other)347     bool operator!=(const OneofIter& other) { return i_ != other.i_; }
operator ==(const OneofIter & other)348     bool operator==(const OneofIter& other) { return i_ == other.i_; }
349 
350    private:
351     const upb_MessageDef* m_;
352     int i_;
353   };
354 
355   class OneofAccessor {
356    public:
OneofAccessor(const upb_MessageDef * md)357     explicit OneofAccessor(const upb_MessageDef* md) : md_(md) {}
begin()358     OneofIter begin() { return OneofIter(md_, 0); }
end()359     OneofIter end() { return OneofIter(md_, upb_MessageDef_OneofCount(md_)); }
360 
361    private:
362     const upb_MessageDef* md_;
363   };
364 
365  public:
fields() const366   FieldAccessor fields() const { return FieldAccessor(ptr()); }
oneofs() const367   OneofAccessor oneofs() const { return OneofAccessor(ptr()); }
368 
369  private:
370   const upb_MessageDef* ptr_;
371 };
372 
373 class EnumValDefPtr {
374  public:
EnumValDefPtr()375   EnumValDefPtr() : ptr_(nullptr) {}
EnumValDefPtr(const upb_EnumValueDef * ptr)376   explicit EnumValDefPtr(const upb_EnumValueDef* ptr) : ptr_(ptr) {}
377 
UPB_DESC(EnumValueOptions)378   const UPB_DESC(EnumValueOptions) * options() const {
379     return upb_EnumValueDef_Options(ptr_);
380   }
381 
number() const382   int32_t number() const { return upb_EnumValueDef_Number(ptr_); }
full_name() const383   const char* full_name() const { return upb_EnumValueDef_FullName(ptr_); }
name() const384   const char* name() const { return upb_EnumValueDef_Name(ptr_); }
385 
386  private:
387   const upb_EnumValueDef* ptr_;
388 };
389 
390 class EnumDefPtr {
391  public:
EnumDefPtr()392   EnumDefPtr() : ptr_(nullptr) {}
EnumDefPtr(const upb_EnumDef * ptr)393   explicit EnumDefPtr(const upb_EnumDef* ptr) : ptr_(ptr) {}
394 
UPB_DESC(EnumOptions)395   const UPB_DESC(EnumOptions) * options() const {
396     return upb_EnumDef_Options(ptr_);
397   }
398 
mini_table() const399   const upb_MiniTableEnum* mini_table() const {
400     return _upb_EnumDef_MiniTable(ptr_);
401   }
402 
MiniDescriptorEncode() const403   std::string MiniDescriptorEncode() const {
404     upb::Arena arena;
405     upb_StringView md;
406     upb_EnumDef_MiniDescriptorEncode(ptr_, arena.ptr(), &md);
407     return std::string(md.data, md.size);
408   }
409 
ptr() const410   const upb_EnumDef* ptr() const { return ptr_; }
operator bool() const411   explicit operator bool() const { return ptr_ != nullptr; }
412 
full_name() const413   const char* full_name() const { return upb_EnumDef_FullName(ptr_); }
name() const414   const char* name() const { return upb_EnumDef_Name(ptr_); }
is_closed() const415   bool is_closed() const { return upb_EnumDef_IsClosed(ptr_); }
416 
417   // The value that is used as the default when no field default is specified.
418   // If not set explicitly, the first value that was added will be used.
419   // The default value must be a member of the enum.
420   // Requires that value_count() > 0.
default_value() const421   int32_t default_value() const { return upb_EnumDef_Default(ptr_); }
422 
423   // Returns the number of values currently defined in the enum.  Note that
424   // multiple names can refer to the same number, so this may be greater than
425   // the total number of unique numbers.
value_count() const426   int value_count() const { return upb_EnumDef_ValueCount(ptr_); }
value(int i) const427   EnumValDefPtr value(int i) const {
428     return EnumValDefPtr(upb_EnumDef_Value(ptr_, i));
429   }
430 
431   // Lookups from name to integer, returning true if found.
FindValueByName(const char * name) const432   EnumValDefPtr FindValueByName(const char* name) const {
433     return EnumValDefPtr(upb_EnumDef_FindValueByName(ptr_, name));
434   }
435 
436   // Finds the name corresponding to the given number, or NULL if none was
437   // found.  If more than one name corresponds to this number, returns the
438   // first one that was added.
FindValueByNumber(int32_t num) const439   EnumValDefPtr FindValueByNumber(int32_t num) const {
440     return EnumValDefPtr(upb_EnumDef_FindValueByNumber(ptr_, num));
441   }
442 
443  private:
444   const upb_EnumDef* ptr_;
445 };
446 
447 // Class that represents a .proto file with some things defined in it.
448 //
449 // Many users won't care about FileDefs, but they are necessary if you want to
450 // read the values of file-level options.
451 class FileDefPtr {
452  public:
FileDefPtr(const upb_FileDef * ptr)453   explicit FileDefPtr(const upb_FileDef* ptr) : ptr_(ptr) {}
454 
UPB_DESC(FileOptions)455   const UPB_DESC(FileOptions) * options() const {
456     return upb_FileDef_Options(ptr_);
457   }
458 
ptr() const459   const upb_FileDef* ptr() const { return ptr_; }
460 
461   // Get/set name of the file (eg. "foo/bar.proto").
name() const462   const char* name() const { return upb_FileDef_Name(ptr_); }
463 
464   // Package name for definitions inside the file (eg. "foo.bar").
package() const465   const char* package() const { return upb_FileDef_Package(ptr_); }
466 
467   // Syntax for the file.  Defaults to proto2.
syntax() const468   upb_Syntax syntax() const { return upb_FileDef_Syntax(ptr_); }
469 
470   // Get the list of dependencies from the file.  These are returned in the
471   // order that they were added to the FileDefPtr.
dependency_count() const472   int dependency_count() const { return upb_FileDef_DependencyCount(ptr_); }
dependency(int index) const473   FileDefPtr dependency(int index) const {
474     return FileDefPtr(upb_FileDef_Dependency(ptr_, index));
475   }
476 
public_dependency_count() const477   int public_dependency_count() const {
478     return upb_FileDef_PublicDependencyCount(ptr_);
479   }
public_dependency(int index) const480   FileDefPtr public_dependency(int index) const {
481     return FileDefPtr(upb_FileDef_PublicDependency(ptr_, index));
482   }
483 
toplevel_enum_count() const484   int toplevel_enum_count() const {
485     return upb_FileDef_TopLevelEnumCount(ptr_);
486   }
toplevel_enum(int index) const487   EnumDefPtr toplevel_enum(int index) const {
488     return EnumDefPtr(upb_FileDef_TopLevelEnum(ptr_, index));
489   }
490 
toplevel_message_count() const491   int toplevel_message_count() const {
492     return upb_FileDef_TopLevelMessageCount(ptr_);
493   }
toplevel_message(int index) const494   MessageDefPtr toplevel_message(int index) const {
495     return MessageDefPtr(upb_FileDef_TopLevelMessage(ptr_, index));
496   }
497 
toplevel_extension_count() const498   int toplevel_extension_count() const {
499     return upb_FileDef_TopLevelExtensionCount(ptr_);
500   }
toplevel_extension(int index) const501   FieldDefPtr toplevel_extension(int index) const {
502     return FieldDefPtr(upb_FileDef_TopLevelExtension(ptr_, index));
503   }
504 
operator bool() const505   explicit operator bool() const { return ptr_ != nullptr; }
506 
operator ==(FileDefPtr lhs,FileDefPtr rhs)507   friend bool operator==(FileDefPtr lhs, FileDefPtr rhs) {
508     return lhs.ptr_ == rhs.ptr_;
509   }
510 
operator !=(FileDefPtr lhs,FileDefPtr rhs)511   friend bool operator!=(FileDefPtr lhs, FileDefPtr rhs) {
512     return !(lhs == rhs);
513   }
514 
515  private:
516   const upb_FileDef* ptr_;
517 };
518 
519 // Non-const methods in upb::DefPool are NOT thread-safe.
520 class DefPool {
521  public:
DefPool()522   DefPool() : ptr_(upb_DefPool_New(), upb_DefPool_Free) {}
DefPool(upb_DefPool * s)523   explicit DefPool(upb_DefPool* s) : ptr_(s, upb_DefPool_Free) {}
524 
ptr() const525   const upb_DefPool* ptr() const { return ptr_.get(); }
ptr()526   upb_DefPool* ptr() { return ptr_.get(); }
527 
528   // Finds an entry in the symbol table with this exact name.  If not found,
529   // returns NULL.
FindMessageByName(const char * sym) const530   MessageDefPtr FindMessageByName(const char* sym) const {
531     return MessageDefPtr(upb_DefPool_FindMessageByName(ptr_.get(), sym));
532   }
533 
FindEnumByName(const char * sym) const534   EnumDefPtr FindEnumByName(const char* sym) const {
535     return EnumDefPtr(upb_DefPool_FindEnumByName(ptr_.get(), sym));
536   }
537 
FindFileByName(const char * name) const538   FileDefPtr FindFileByName(const char* name) const {
539     return FileDefPtr(upb_DefPool_FindFileByName(ptr_.get(), name));
540   }
541 
FindExtensionByName(const char * name) const542   FieldDefPtr FindExtensionByName(const char* name) const {
543     return FieldDefPtr(upb_DefPool_FindExtensionByName(ptr_.get(), name));
544   }
545 
_SetPlatform(upb_MiniTablePlatform platform)546   void _SetPlatform(upb_MiniTablePlatform platform) {
547     _upb_DefPool_SetPlatform(ptr_.get(), platform);
548   }
549 
550   // TODO: iteration?
551 
552   // Adds the given serialized FileDescriptorProto to the pool.
AddFile(const UPB_DESC (FileDescriptorProto)* file_proto,Status * status)553   FileDefPtr AddFile(const UPB_DESC(FileDescriptorProto) * file_proto,
554                      Status* status) {
555     return FileDefPtr(
556         upb_DefPool_AddFile(ptr_.get(), file_proto, status->ptr()));
557   }
558 
559  private:
560   std::unique_ptr<upb_DefPool, decltype(&upb_DefPool_Free)> ptr_;
561 };
562 
563 // TODO(b/236632406): This typedef is deprecated. Delete it.
564 using SymbolTable = DefPool;
565 
file() const566 inline FileDefPtr FieldDefPtr::file() const {
567   return FileDefPtr(upb_FieldDef_File(ptr_));
568 }
569 
file() const570 inline FileDefPtr MessageDefPtr::file() const {
571   return FileDefPtr(upb_MessageDef_File(ptr_));
572 }
573 
enum_type(int i) const574 inline EnumDefPtr MessageDefPtr::enum_type(int i) const {
575   return EnumDefPtr(upb_MessageDef_NestedEnum(ptr_, i));
576 }
577 
message_type() const578 inline MessageDefPtr FieldDefPtr::message_type() const {
579   return MessageDefPtr(upb_FieldDef_MessageSubDef(ptr_));
580 }
581 
containing_type() const582 inline MessageDefPtr FieldDefPtr::containing_type() const {
583   return MessageDefPtr(upb_FieldDef_ContainingType(ptr_));
584 }
585 
extension_scope() const586 inline MessageDefPtr FieldDefPtr::extension_scope() const {
587   return MessageDefPtr(upb_FieldDef_ExtensionScope(ptr_));
588 }
589 
containing_type() const590 inline MessageDefPtr OneofDefPtr::containing_type() const {
591   return MessageDefPtr(upb_OneofDef_ContainingType(ptr_));
592 }
593 
containing_oneof() const594 inline OneofDefPtr FieldDefPtr::containing_oneof() const {
595   return OneofDefPtr(upb_FieldDef_ContainingOneof(ptr_));
596 }
597 
real_containing_oneof() const598 inline OneofDefPtr FieldDefPtr::real_containing_oneof() const {
599   return OneofDefPtr(upb_FieldDef_RealContainingOneof(ptr_));
600 }
601 
enum_subdef() const602 inline EnumDefPtr FieldDefPtr::enum_subdef() const {
603   return EnumDefPtr(upb_FieldDef_EnumSubDef(ptr_));
604 }
605 
606 }  // namespace upb
607 
608 #include "upb/port/undef.inc"
609 
610 #endif  // UPB_REFLECTION_DEF_HPP_
611