You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

def.hpp 20 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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. #ifndef UPB_DEF_HPP_
  26. #define UPB_DEF_HPP_
  27. #include <cstring>
  28. #include <memory>
  29. #include <string>
  30. #include <vector>
  31. #include "upb/def.h"
  32. #include "upb/reflection.h"
  33. #include "upb/upb.hpp"
  34. namespace upb
  35. {
  36. typedef upb_MessageValue MessageValue;
  37. class EnumDefPtr;
  38. class FileDefPtr;
  39. class MessageDefPtr;
  40. class OneofDefPtr;
  41. // A upb::FieldDefPtr describes a single field in a message. It is most often
  42. // found as a part of a upb_MessageDef, but can also stand alone to represent
  43. // an extension.
  44. class FieldDefPtr
  45. {
  46. public:
  47. FieldDefPtr() :
  48. ptr_(nullptr)
  49. {
  50. }
  51. explicit FieldDefPtr(const upb_FieldDef* ptr) :
  52. ptr_(ptr)
  53. {
  54. }
  55. const upb_FieldDef* ptr() const
  56. {
  57. return ptr_;
  58. }
  59. explicit operator bool() const
  60. {
  61. return ptr_ != nullptr;
  62. }
  63. typedef upb_CType Type;
  64. typedef upb_Label Label;
  65. typedef upb_FieldType DescriptorType;
  66. const char* full_name() const
  67. {
  68. return upb_FieldDef_FullName(ptr_);
  69. }
  70. Type type() const
  71. {
  72. return upb_FieldDef_CType(ptr_);
  73. }
  74. Label label() const
  75. {
  76. return upb_FieldDef_Label(ptr_);
  77. }
  78. const char* name() const
  79. {
  80. return upb_FieldDef_Name(ptr_);
  81. }
  82. const char* json_name() const
  83. {
  84. return upb_FieldDef_JsonName(ptr_);
  85. }
  86. uint32_t number() const
  87. {
  88. return upb_FieldDef_Number(ptr_);
  89. }
  90. bool is_extension() const
  91. {
  92. return upb_FieldDef_IsExtension(ptr_);
  93. }
  94. // For non-string, non-submessage fields, this indicates whether binary
  95. // protobufs are encoded in packed or non-packed format.
  96. //
  97. // Note: this accessor reflects the fact that "packed" has different defaults
  98. // depending on whether the proto is proto2 or proto3.
  99. bool packed() const
  100. {
  101. return upb_FieldDef_IsPacked(ptr_);
  102. }
  103. // An integer that can be used as an index into an array of fields for
  104. // whatever message this field belongs to. Guaranteed to be less than
  105. // f->containing_type()->field_count(). May only be accessed once the def has
  106. // been finalized.
  107. uint32_t index() const
  108. {
  109. return upb_FieldDef_Index(ptr_);
  110. }
  111. // The MessageDef to which this field belongs.
  112. //
  113. // If this field has been added to a MessageDef, that message can be retrieved
  114. // directly (this is always the case for frozen FieldDefs).
  115. //
  116. // If the field has not yet been added to a MessageDef, you can set the name
  117. // of the containing type symbolically instead. This is mostly useful for
  118. // extensions, where the extension is declared separately from the message.
  119. MessageDefPtr containing_type() const;
  120. // The OneofDef to which this field belongs, or NULL if this field is not part
  121. // of a oneof.
  122. OneofDefPtr containing_oneof() const;
  123. // The field's type according to the enum in descriptor.proto. This is not
  124. // the same as UPB_TYPE_*, because it distinguishes between (for example)
  125. // INT32 and SINT32, whereas our "type" enum does not. This return of
  126. // descriptor_type() is a function of type(), integer_format(), and
  127. // is_tag_delimited().
  128. DescriptorType descriptor_type() const
  129. {
  130. return upb_FieldDef_Type(ptr_);
  131. }
  132. // Convenient field type tests.
  133. bool IsSubMessage() const
  134. {
  135. return upb_FieldDef_IsSubMessage(ptr_);
  136. }
  137. bool IsString() const
  138. {
  139. return upb_FieldDef_IsString(ptr_);
  140. }
  141. bool IsSequence() const
  142. {
  143. return upb_FieldDef_IsRepeated(ptr_);
  144. }
  145. bool IsPrimitive() const
  146. {
  147. return upb_FieldDef_IsPrimitive(ptr_);
  148. }
  149. bool IsMap() const
  150. {
  151. return upb_FieldDef_IsMap(ptr_);
  152. }
  153. MessageValue default_value() const
  154. {
  155. return upb_FieldDef_Default(ptr_);
  156. }
  157. // Returns the enum or submessage def for this field, if any. The field's
  158. // type must match (ie. you may only call enum_subdef() for fields where
  159. // type() == kUpb_CType_Enum).
  160. EnumDefPtr enum_subdef() const;
  161. MessageDefPtr message_subdef() const;
  162. private:
  163. const upb_FieldDef* ptr_;
  164. };
  165. // Class that represents a oneof.
  166. class OneofDefPtr
  167. {
  168. public:
  169. OneofDefPtr() :
  170. ptr_(nullptr)
  171. {
  172. }
  173. explicit OneofDefPtr(const upb_OneofDef* ptr) :
  174. ptr_(ptr)
  175. {
  176. }
  177. const upb_OneofDef* ptr() const
  178. {
  179. return ptr_;
  180. }
  181. explicit operator bool() const
  182. {
  183. return ptr_ != nullptr;
  184. }
  185. // Returns the MessageDef that contains this OneofDef.
  186. MessageDefPtr containing_type() const;
  187. // Returns the name of this oneof.
  188. const char* name() const
  189. {
  190. return upb_OneofDef_Name(ptr_);
  191. }
  192. // Returns the number of fields in the oneof.
  193. int field_count() const
  194. {
  195. return upb_OneofDef_FieldCount(ptr_);
  196. }
  197. FieldDefPtr field(int i) const
  198. {
  199. return FieldDefPtr(upb_OneofDef_Field(ptr_, i));
  200. }
  201. // Looks up by name.
  202. FieldDefPtr FindFieldByName(const char* name, size_t len) const
  203. {
  204. return FieldDefPtr(upb_OneofDef_LookupNameWithSize(ptr_, name, len));
  205. }
  206. FieldDefPtr FindFieldByName(const char* name) const
  207. {
  208. return FieldDefPtr(upb_OneofDef_LookupName(ptr_, name));
  209. }
  210. template<class T>
  211. FieldDefPtr FindFieldByName(const T& str) const
  212. {
  213. return FindFieldByName(str.c_str(), str.size());
  214. }
  215. // Looks up by tag number.
  216. FieldDefPtr FindFieldByNumber(uint32_t num) const
  217. {
  218. return FieldDefPtr(upb_OneofDef_LookupNumber(ptr_, num));
  219. }
  220. private:
  221. const upb_OneofDef* ptr_;
  222. };
  223. // Structure that describes a single .proto message type.
  224. class MessageDefPtr
  225. {
  226. public:
  227. MessageDefPtr() :
  228. ptr_(nullptr)
  229. {
  230. }
  231. explicit MessageDefPtr(const upb_MessageDef* ptr) :
  232. ptr_(ptr)
  233. {
  234. }
  235. const upb_MessageDef* ptr() const
  236. {
  237. return ptr_;
  238. }
  239. explicit operator bool() const
  240. {
  241. return ptr_ != nullptr;
  242. }
  243. FileDefPtr file() const;
  244. const char* full_name() const
  245. {
  246. return upb_MessageDef_FullName(ptr_);
  247. }
  248. const char* name() const
  249. {
  250. return upb_MessageDef_Name(ptr_);
  251. }
  252. // The number of fields that belong to the MessageDef.
  253. int field_count() const
  254. {
  255. return upb_MessageDef_FieldCount(ptr_);
  256. }
  257. FieldDefPtr field(int i) const
  258. {
  259. return FieldDefPtr(upb_MessageDef_Field(ptr_, i));
  260. }
  261. // The number of oneofs that belong to the MessageDef.
  262. int oneof_count() const
  263. {
  264. return upb_MessageDef_OneofCount(ptr_);
  265. }
  266. OneofDefPtr oneof(int i) const
  267. {
  268. return OneofDefPtr(upb_MessageDef_Oneof(ptr_, i));
  269. }
  270. upb_Syntax syntax() const
  271. {
  272. return upb_MessageDef_Syntax(ptr_);
  273. }
  274. // These return null pointers if the field is not found.
  275. FieldDefPtr FindFieldByNumber(uint32_t number) const
  276. {
  277. return FieldDefPtr(upb_MessageDef_FindFieldByNumber(ptr_, number));
  278. }
  279. FieldDefPtr FindFieldByName(const char* name, size_t len) const
  280. {
  281. return FieldDefPtr(upb_MessageDef_FindFieldByNameWithSize(ptr_, name, len));
  282. }
  283. FieldDefPtr FindFieldByName(const char* name) const
  284. {
  285. return FieldDefPtr(upb_MessageDef_FindFieldByName(ptr_, name));
  286. }
  287. template<class T>
  288. FieldDefPtr FindFieldByName(const T& str) const
  289. {
  290. return FindFieldByName(str.c_str(), str.size());
  291. }
  292. OneofDefPtr FindOneofByName(const char* name, size_t len) const
  293. {
  294. return OneofDefPtr(upb_MessageDef_FindOneofByNameWithSize(ptr_, name, len));
  295. }
  296. OneofDefPtr FindOneofByName(const char* name) const
  297. {
  298. return OneofDefPtr(upb_MessageDef_FindOneofByName(ptr_, name));
  299. }
  300. template<class T>
  301. OneofDefPtr FindOneofByName(const T& str) const
  302. {
  303. return FindOneofByName(str.c_str(), str.size());
  304. }
  305. // Is this message a map entry?
  306. bool mapentry() const
  307. {
  308. return upb_MessageDef_IsMapEntry(ptr_);
  309. }
  310. // Return the type of well known type message. kUpb_WellKnown_Unspecified for
  311. // non-well-known message.
  312. upb_WellKnown wellknowntype() const
  313. {
  314. return upb_MessageDef_WellKnownType(ptr_);
  315. }
  316. private:
  317. class FieldIter
  318. {
  319. public:
  320. explicit FieldIter(const upb_MessageDef* m, int i) :
  321. m_(m),
  322. i_(i)
  323. {
  324. }
  325. void operator++()
  326. {
  327. i_++;
  328. }
  329. FieldDefPtr operator*()
  330. {
  331. return FieldDefPtr(upb_MessageDef_Field(m_, i_));
  332. }
  333. bool operator!=(const FieldIter& other)
  334. {
  335. return i_ != other.i_;
  336. }
  337. bool operator==(const FieldIter& other)
  338. {
  339. return i_ == other.i_;
  340. }
  341. private:
  342. const upb_MessageDef* m_;
  343. int i_;
  344. };
  345. class FieldAccessor
  346. {
  347. public:
  348. explicit FieldAccessor(const upb_MessageDef* md) :
  349. md_(md)
  350. {
  351. }
  352. FieldIter begin()
  353. {
  354. return FieldIter(md_, 0);
  355. }
  356. FieldIter end()
  357. {
  358. return FieldIter(md_, upb_MessageDef_FieldCount(md_));
  359. }
  360. private:
  361. const upb_MessageDef* md_;
  362. };
  363. class OneofIter
  364. {
  365. public:
  366. explicit OneofIter(const upb_MessageDef* m, int i) :
  367. m_(m),
  368. i_(i)
  369. {
  370. }
  371. void operator++()
  372. {
  373. i_++;
  374. }
  375. OneofDefPtr operator*()
  376. {
  377. return OneofDefPtr(upb_MessageDef_Oneof(m_, i_));
  378. }
  379. bool operator!=(const OneofIter& other)
  380. {
  381. return i_ != other.i_;
  382. }
  383. bool operator==(const OneofIter& other)
  384. {
  385. return i_ == other.i_;
  386. }
  387. private:
  388. const upb_MessageDef* m_;
  389. int i_;
  390. };
  391. class OneofAccessor
  392. {
  393. public:
  394. explicit OneofAccessor(const upb_MessageDef* md) :
  395. md_(md)
  396. {
  397. }
  398. OneofIter begin()
  399. {
  400. return OneofIter(md_, 0);
  401. }
  402. OneofIter end()
  403. {
  404. return OneofIter(md_, upb_MessageDef_OneofCount(md_));
  405. }
  406. private:
  407. const upb_MessageDef* md_;
  408. };
  409. public:
  410. FieldAccessor fields() const
  411. {
  412. return FieldAccessor(ptr());
  413. }
  414. OneofAccessor oneofs() const
  415. {
  416. return OneofAccessor(ptr());
  417. }
  418. private:
  419. const upb_MessageDef* ptr_;
  420. };
  421. class EnumValDefPtr
  422. {
  423. public:
  424. EnumValDefPtr() :
  425. ptr_(nullptr)
  426. {
  427. }
  428. explicit EnumValDefPtr(const upb_EnumValueDef* ptr) :
  429. ptr_(ptr)
  430. {
  431. }
  432. int32_t number() const
  433. {
  434. return upb_EnumValueDef_Number(ptr_);
  435. }
  436. const char* full_name() const
  437. {
  438. return upb_EnumValueDef_FullName(ptr_);
  439. }
  440. const char* name() const
  441. {
  442. return upb_EnumValueDef_Name(ptr_);
  443. }
  444. private:
  445. const upb_EnumValueDef* ptr_;
  446. };
  447. class EnumDefPtr
  448. {
  449. public:
  450. EnumDefPtr() :
  451. ptr_(nullptr)
  452. {
  453. }
  454. explicit EnumDefPtr(const upb_EnumDef* ptr) :
  455. ptr_(ptr)
  456. {
  457. }
  458. const upb_EnumDef* ptr() const
  459. {
  460. return ptr_;
  461. }
  462. explicit operator bool() const
  463. {
  464. return ptr_ != nullptr;
  465. }
  466. const char* full_name() const
  467. {
  468. return upb_EnumDef_FullName(ptr_);
  469. }
  470. const char* name() const
  471. {
  472. return upb_EnumDef_Name(ptr_);
  473. }
  474. // The value that is used as the default when no field default is specified.
  475. // If not set explicitly, the first value that was added will be used.
  476. // The default value must be a member of the enum.
  477. // Requires that value_count() > 0.
  478. int32_t default_value() const
  479. {
  480. return upb_EnumDef_Default(ptr_);
  481. }
  482. // Returns the number of values currently defined in the enum. Note that
  483. // multiple names can refer to the same number, so this may be greater than
  484. // the total number of unique numbers.
  485. int value_count() const
  486. {
  487. return upb_EnumDef_ValueCount(ptr_);
  488. }
  489. // Lookups from name to integer, returning true if found.
  490. EnumValDefPtr FindValueByName(const char* name) const
  491. {
  492. return EnumValDefPtr(upb_EnumDef_FindValueByName(ptr_, name));
  493. }
  494. // Finds the name corresponding to the given number, or NULL if none was
  495. // found. If more than one name corresponds to this number, returns the
  496. // first one that was added.
  497. EnumValDefPtr FindValueByNumber(int32_t num) const
  498. {
  499. return EnumValDefPtr(upb_EnumDef_FindValueByNumber(ptr_, num));
  500. }
  501. private:
  502. const upb_EnumDef* ptr_;
  503. };
  504. // Class that represents a .proto file with some things defined in it.
  505. //
  506. // Many users won't care about FileDefs, but they are necessary if you want to
  507. // read the values of file-level options.
  508. class FileDefPtr
  509. {
  510. public:
  511. explicit FileDefPtr(const upb_FileDef* ptr) :
  512. ptr_(ptr)
  513. {
  514. }
  515. const upb_FileDef* ptr() const
  516. {
  517. return ptr_;
  518. }
  519. explicit operator bool() const
  520. {
  521. return ptr_ != nullptr;
  522. }
  523. // Get/set name of the file (eg. "foo/bar.proto").
  524. const char* name() const
  525. {
  526. return upb_FileDef_Name(ptr_);
  527. }
  528. // Package name for definitions inside the file (eg. "foo.bar").
  529. const char* package() const
  530. {
  531. return upb_FileDef_Package(ptr_);
  532. }
  533. // Syntax for the file. Defaults to proto2.
  534. upb_Syntax syntax() const
  535. {
  536. return upb_FileDef_Syntax(ptr_);
  537. }
  538. // Get the list of dependencies from the file. These are returned in the
  539. // order that they were added to the FileDefPtr.
  540. int dependency_count() const
  541. {
  542. return upb_FileDef_DependencyCount(ptr_);
  543. }
  544. const FileDefPtr dependency(int index) const
  545. {
  546. return FileDefPtr(upb_FileDef_Dependency(ptr_, index));
  547. }
  548. private:
  549. const upb_FileDef* ptr_;
  550. };
  551. // Non-const methods in upb::DefPool are NOT thread-safe.
  552. class DefPool
  553. {
  554. public:
  555. DefPool() :
  556. ptr_(upb_DefPool_New(), upb_DefPool_Free)
  557. {
  558. }
  559. explicit DefPool(upb_DefPool* s) :
  560. ptr_(s, upb_DefPool_Free)
  561. {
  562. }
  563. const upb_DefPool* ptr() const
  564. {
  565. return ptr_.get();
  566. }
  567. upb_DefPool* ptr()
  568. {
  569. return ptr_.get();
  570. }
  571. // Finds an entry in the symbol table with this exact name. If not found,
  572. // returns NULL.
  573. MessageDefPtr FindMessageByName(const char* sym) const
  574. {
  575. return MessageDefPtr(upb_DefPool_FindMessageByName(ptr_.get(), sym));
  576. }
  577. EnumDefPtr FindEnumByName(const char* sym) const
  578. {
  579. return EnumDefPtr(upb_DefPool_FindEnumByName(ptr_.get(), sym));
  580. }
  581. FileDefPtr FindFileByName(const char* name) const
  582. {
  583. return FileDefPtr(upb_DefPool_FindFileByName(ptr_.get(), name));
  584. }
  585. // TODO: iteration?
  586. // Adds the given serialized FileDescriptorProto to the pool.
  587. FileDefPtr AddFile(const google_protobuf_FileDescriptorProto* file_proto, Status* status)
  588. {
  589. return FileDefPtr(
  590. upb_DefPool_AddFile(ptr_.get(), file_proto, status->ptr())
  591. );
  592. }
  593. private:
  594. std::unique_ptr<upb_DefPool, decltype(&upb_DefPool_Free)> ptr_;
  595. };
  596. // TODO(b/236632406): This typedef is deprecated. Delete it.
  597. using SymbolTable = DefPool;
  598. inline FileDefPtr MessageDefPtr::file() const
  599. {
  600. return FileDefPtr(upb_MessageDef_File(ptr_));
  601. }
  602. inline MessageDefPtr FieldDefPtr::message_subdef() const
  603. {
  604. return MessageDefPtr(upb_FieldDef_MessageSubDef(ptr_));
  605. }
  606. inline MessageDefPtr FieldDefPtr::containing_type() const
  607. {
  608. return MessageDefPtr(upb_FieldDef_ContainingType(ptr_));
  609. }
  610. inline MessageDefPtr OneofDefPtr::containing_type() const
  611. {
  612. return MessageDefPtr(upb_OneofDef_ContainingType(ptr_));
  613. }
  614. inline OneofDefPtr FieldDefPtr::containing_oneof() const
  615. {
  616. return OneofDefPtr(upb_FieldDef_ContainingOneof(ptr_));
  617. }
  618. inline EnumDefPtr FieldDefPtr::enum_subdef() const
  619. {
  620. return EnumDefPtr(upb_FieldDef_EnumSubDef(ptr_));
  621. }
  622. } // namespace upb
  623. #endif // UPB_DEF_HPP_