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.

reflection.h 30 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // This header defines the RepeatedFieldRef class template used to access
  31. // repeated fields with protobuf reflection API.
  32. #ifndef GOOGLE_PROTOBUF_REFLECTION_H__
  33. #define GOOGLE_PROTOBUF_REFLECTION_H__
  34. #include <memory>
  35. #include <google/protobuf/message.h>
  36. #include <google/protobuf/generated_enum_util.h>
  37. #ifdef SWIG
  38. #error "You cannot SWIG proto headers"
  39. #endif
  40. // Must be included last.
  41. #include <google/protobuf/port_def.inc>
  42. namespace google
  43. {
  44. namespace protobuf
  45. {
  46. namespace internal
  47. {
  48. template<typename T, typename Enable = void>
  49. struct RefTypeTraits;
  50. } // namespace internal
  51. template<typename T>
  52. RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
  53. const Message& message, const FieldDescriptor* field
  54. ) const
  55. {
  56. return RepeatedFieldRef<T>(message, field);
  57. }
  58. template<typename T>
  59. MutableRepeatedFieldRef<T> Reflection::GetMutableRepeatedFieldRef(
  60. Message* message, const FieldDescriptor* field
  61. ) const
  62. {
  63. return MutableRepeatedFieldRef<T>(message, field);
  64. }
  65. // RepeatedFieldRef definition for non-message types.
  66. template<typename T>
  67. class RepeatedFieldRef<
  68. T,
  69. typename std::enable_if<!std::is_base_of<Message, T>::value>::type>
  70. {
  71. typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
  72. typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  73. public:
  74. bool empty() const
  75. {
  76. return accessor_->IsEmpty(data_);
  77. }
  78. int size() const
  79. {
  80. return accessor_->Size(data_);
  81. }
  82. T Get(int index) const
  83. {
  84. return accessor_->template Get<T>(data_, index);
  85. }
  86. typedef IteratorType iterator;
  87. typedef IteratorType const_iterator;
  88. typedef T value_type;
  89. typedef T& reference;
  90. typedef const T& const_reference;
  91. typedef int size_type;
  92. typedef ptrdiff_t difference_type;
  93. iterator begin() const
  94. {
  95. return iterator(data_, accessor_, true);
  96. }
  97. iterator end() const
  98. {
  99. return iterator(data_, accessor_, false);
  100. }
  101. private:
  102. friend class Reflection;
  103. RepeatedFieldRef(const Message& message, const FieldDescriptor* field)
  104. {
  105. const Reflection* reflection = message.GetReflection();
  106. data_ = reflection->RepeatedFieldData(const_cast<Message*>(&message), field, internal::RefTypeTraits<T>::cpp_type, nullptr);
  107. accessor_ = reflection->RepeatedFieldAccessor(field);
  108. }
  109. const void* data_;
  110. const AccessorType* accessor_;
  111. };
  112. // MutableRepeatedFieldRef definition for non-message types.
  113. template<typename T>
  114. class MutableRepeatedFieldRef<
  115. T,
  116. typename std::enable_if<!std::is_base_of<Message, T>::value>::type>
  117. {
  118. typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  119. public:
  120. bool empty() const
  121. {
  122. return accessor_->IsEmpty(data_);
  123. }
  124. int size() const
  125. {
  126. return accessor_->Size(data_);
  127. }
  128. T Get(int index) const
  129. {
  130. return accessor_->template Get<T>(data_, index);
  131. }
  132. void Set(int index, const T& value) const
  133. {
  134. accessor_->template Set<T>(data_, index, value);
  135. }
  136. void Add(const T& value) const
  137. {
  138. accessor_->template Add<T>(data_, value);
  139. }
  140. void RemoveLast() const
  141. {
  142. accessor_->RemoveLast(data_);
  143. }
  144. void SwapElements(int index1, int index2) const
  145. {
  146. accessor_->SwapElements(data_, index1, index2);
  147. }
  148. void Clear() const
  149. {
  150. accessor_->Clear(data_);
  151. }
  152. void Swap(const MutableRepeatedFieldRef& other) const
  153. {
  154. accessor_->Swap(data_, other.accessor_, other.data_);
  155. }
  156. template<typename Container>
  157. void MergeFrom(const Container& container) const
  158. {
  159. typedef typename Container::const_iterator Iterator;
  160. for (Iterator it = container.begin(); it != container.end(); ++it)
  161. {
  162. Add(*it);
  163. }
  164. }
  165. template<typename Container>
  166. void CopyFrom(const Container& container) const
  167. {
  168. Clear();
  169. MergeFrom(container);
  170. }
  171. private:
  172. friend class Reflection;
  173. MutableRepeatedFieldRef(Message* message, const FieldDescriptor* field)
  174. {
  175. const Reflection* reflection = message->GetReflection();
  176. data_ = reflection->RepeatedFieldData(
  177. message, field, internal::RefTypeTraits<T>::cpp_type, nullptr
  178. );
  179. accessor_ = reflection->RepeatedFieldAccessor(field);
  180. }
  181. void* data_;
  182. const AccessorType* accessor_;
  183. };
  184. // RepeatedFieldRef definition for message types.
  185. template<typename T>
  186. class RepeatedFieldRef<
  187. T,
  188. typename std::enable_if<std::is_base_of<Message, T>::value>::type>
  189. {
  190. typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
  191. typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  192. public:
  193. bool empty() const
  194. {
  195. return accessor_->IsEmpty(data_);
  196. }
  197. int size() const
  198. {
  199. return accessor_->Size(data_);
  200. }
  201. // This method returns a reference to the underlying message object if it
  202. // exists. If a message object doesn't exist (e.g., data stored in serialized
  203. // form), scratch_space will be filled with the data and a reference to it
  204. // will be returned.
  205. //
  206. // Example:
  207. // RepeatedFieldRef<Message> h = ...
  208. // unique_ptr<Message> scratch_space(h.NewMessage());
  209. // const Message& item = h.Get(index, scratch_space.get());
  210. const T& Get(int index, T* scratch_space) const
  211. {
  212. return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
  213. }
  214. // Create a new message of the same type as the messages stored in this
  215. // repeated field. Caller takes ownership of the returned object.
  216. T* NewMessage() const
  217. {
  218. return static_cast<T*>(default_instance_->New());
  219. }
  220. typedef IteratorType iterator;
  221. typedef IteratorType const_iterator;
  222. typedef T value_type;
  223. typedef T& reference;
  224. typedef const T& const_reference;
  225. typedef int size_type;
  226. typedef ptrdiff_t difference_type;
  227. iterator begin() const
  228. {
  229. return iterator(data_, accessor_, true, NewMessage());
  230. }
  231. iterator end() const
  232. {
  233. // The end iterator must not be dereferenced, no need for scratch space.
  234. return iterator(data_, accessor_, false, nullptr);
  235. }
  236. private:
  237. friend class Reflection;
  238. RepeatedFieldRef(const Message& message, const FieldDescriptor* field)
  239. {
  240. const Reflection* reflection = message.GetReflection();
  241. data_ = reflection->RepeatedFieldData(
  242. const_cast<Message*>(&message), field, internal::RefTypeTraits<T>::cpp_type, internal::RefTypeTraits<T>::GetMessageFieldDescriptor()
  243. );
  244. accessor_ = reflection->RepeatedFieldAccessor(field);
  245. default_instance_ =
  246. reflection->GetMessageFactory()->GetPrototype(field->message_type());
  247. }
  248. const void* data_;
  249. const AccessorType* accessor_;
  250. const Message* default_instance_;
  251. };
  252. // MutableRepeatedFieldRef definition for message types.
  253. template<typename T>
  254. class MutableRepeatedFieldRef<
  255. T,
  256. typename std::enable_if<std::is_base_of<Message, T>::value>::type>
  257. {
  258. typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  259. public:
  260. bool empty() const
  261. {
  262. return accessor_->IsEmpty(data_);
  263. }
  264. int size() const
  265. {
  266. return accessor_->Size(data_);
  267. }
  268. // See comments for RepeatedFieldRef<Message>::Get()
  269. const T& Get(int index, T* scratch_space) const
  270. {
  271. return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
  272. }
  273. // Create a new message of the same type as the messages stored in this
  274. // repeated field. Caller takes ownership of the returned object.
  275. T* NewMessage() const
  276. {
  277. return static_cast<T*>(default_instance_->New());
  278. }
  279. void Set(int index, const T& value) const
  280. {
  281. accessor_->Set(data_, index, &value);
  282. }
  283. void Add(const T& value) const
  284. {
  285. accessor_->Add(data_, &value);
  286. }
  287. void RemoveLast() const
  288. {
  289. accessor_->RemoveLast(data_);
  290. }
  291. void SwapElements(int index1, int index2) const
  292. {
  293. accessor_->SwapElements(data_, index1, index2);
  294. }
  295. void Clear() const
  296. {
  297. accessor_->Clear(data_);
  298. }
  299. void Swap(const MutableRepeatedFieldRef& other) const
  300. {
  301. accessor_->Swap(data_, other.accessor_, other.data_);
  302. }
  303. template<typename Container>
  304. void MergeFrom(const Container& container) const
  305. {
  306. typedef typename Container::const_iterator Iterator;
  307. for (Iterator it = container.begin(); it != container.end(); ++it)
  308. {
  309. Add(*it);
  310. }
  311. }
  312. template<typename Container>
  313. void CopyFrom(const Container& container) const
  314. {
  315. Clear();
  316. MergeFrom(container);
  317. }
  318. private:
  319. friend class Reflection;
  320. MutableRepeatedFieldRef(Message* message, const FieldDescriptor* field)
  321. {
  322. const Reflection* reflection = message->GetReflection();
  323. data_ = reflection->RepeatedFieldData(
  324. message, field, internal::RefTypeTraits<T>::cpp_type, internal::RefTypeTraits<T>::GetMessageFieldDescriptor()
  325. );
  326. accessor_ = reflection->RepeatedFieldAccessor(field);
  327. default_instance_ =
  328. reflection->GetMessageFactory()->GetPrototype(field->message_type());
  329. }
  330. void* data_;
  331. const AccessorType* accessor_;
  332. const Message* default_instance_;
  333. };
  334. namespace internal
  335. {
  336. // Interfaces used to implement reflection RepeatedFieldRef API.
  337. // Reflection::GetRepeatedAccessor() should return a pointer to an singleton
  338. // object that implements the below interface.
  339. //
  340. // This interface passes/returns values using void pointers. The actual type
  341. // of the value depends on the field's cpp_type. Following is a mapping from
  342. // cpp_type to the type that should be used in this interface:
  343. //
  344. // field->cpp_type() T Actual type of void*
  345. // CPPTYPE_INT32 int32_t int32_t
  346. // CPPTYPE_UINT32 uint32_t uint32_t
  347. // CPPTYPE_INT64 int64_t int64_t
  348. // CPPTYPE_UINT64 uint64_t uint64_t
  349. // CPPTYPE_DOUBLE double double
  350. // CPPTYPE_FLOAT float float
  351. // CPPTYPE_BOOL bool bool
  352. // CPPTYPE_ENUM generated enum type int32_t
  353. // CPPTYPE_STRING string std::string
  354. // CPPTYPE_MESSAGE generated message type google::protobuf::Message
  355. // or google::protobuf::Message
  356. //
  357. // Note that for enums we use int32_t in the interface.
  358. //
  359. // You can map from T to the actual type using RefTypeTraits:
  360. // typedef RefTypeTraits<T>::AccessorValueType ActualType;
  361. class PROTOBUF_EXPORT RepeatedFieldAccessor
  362. {
  363. public:
  364. // Typedefs for clarity.
  365. typedef void Field;
  366. typedef void Value;
  367. typedef void Iterator;
  368. virtual bool IsEmpty(const Field* data) const = 0;
  369. virtual int Size(const Field* data) const = 0;
  370. // Depends on the underlying representation of the repeated field, this
  371. // method can return a pointer to the underlying object if such an object
  372. // exists, or fill the data into scratch_space and return scratch_space.
  373. // Callers of this method must ensure scratch_space is a valid pointer
  374. // to a mutable object of the correct type.
  375. virtual const Value* Get(const Field* data, int index, Value* scratch_space) const = 0;
  376. virtual void Clear(Field* data) const = 0;
  377. virtual void Set(Field* data, int index, const Value* value) const = 0;
  378. virtual void Add(Field* data, const Value* value) const = 0;
  379. virtual void RemoveLast(Field* data) const = 0;
  380. virtual void SwapElements(Field* data, int index1, int index2) const = 0;
  381. virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator, Field* other_data) const = 0;
  382. // Create an iterator that points at the beginning of the repeated field.
  383. virtual Iterator* BeginIterator(const Field* data) const = 0;
  384. // Create an iterator that points at the end of the repeated field.
  385. virtual Iterator* EndIterator(const Field* data) const = 0;
  386. // Make a copy of an iterator and return the new copy.
  387. virtual Iterator* CopyIterator(const Field* data, const Iterator* iterator) const = 0;
  388. // Move an iterator to point to the next element.
  389. virtual Iterator* AdvanceIterator(const Field* data, Iterator* iterator) const = 0;
  390. // Compare whether two iterators point to the same element.
  391. virtual bool EqualsIterator(const Field* data, const Iterator* a, const Iterator* b) const = 0;
  392. // Delete an iterator created by BeginIterator(), EndIterator() and
  393. // CopyIterator().
  394. virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
  395. // Like Get() but for iterators.
  396. virtual const Value* GetIteratorValue(const Field* data, const Iterator* iterator, Value* scratch_space) const = 0;
  397. // Templated methods that make using this interface easier for non-message
  398. // types.
  399. template<typename T>
  400. T Get(const Field* data, int index) const
  401. {
  402. typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
  403. ActualType scratch_space;
  404. return static_cast<T>(*reinterpret_cast<const ActualType*>(
  405. Get(data, index, static_cast<Value*>(&scratch_space))
  406. ));
  407. }
  408. template<typename T, typename ValueType>
  409. void Set(Field* data, int index, const ValueType& value) const
  410. {
  411. typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
  412. // In this RepeatedFieldAccessor interface we pass/return data using
  413. // raw pointers. Type of the data these raw pointers point to should
  414. // be ActualType. Here we have a ValueType object and want a ActualType
  415. // pointer. We can't cast a ValueType pointer to an ActualType pointer
  416. // directly because their type might be different (for enums ValueType
  417. // may be a generated enum type while ActualType is int32_t). To be safe
  418. // we make a copy to get a temporary ActualType object and use it.
  419. ActualType tmp = static_cast<ActualType>(value);
  420. Set(data, index, static_cast<const Value*>(&tmp));
  421. }
  422. template<typename T, typename ValueType>
  423. void Add(Field* data, const ValueType& value) const
  424. {
  425. typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
  426. // In this RepeatedFieldAccessor interface we pass/return data using
  427. // raw pointers. Type of the data these raw pointers point to should
  428. // be ActualType. Here we have a ValueType object and want a ActualType
  429. // pointer. We can't cast a ValueType pointer to an ActualType pointer
  430. // directly because their type might be different (for enums ValueType
  431. // may be a generated enum type while ActualType is int32_t). To be safe
  432. // we make a copy to get a temporary ActualType object and use it.
  433. ActualType tmp = static_cast<ActualType>(value);
  434. Add(data, static_cast<const Value*>(&tmp));
  435. }
  436. protected:
  437. // We want the destructor to be completely trivial as to allow it to be
  438. // a function local static. Hence we make it non-virtual and protected,
  439. // this class only live as part of a global singleton and should not be
  440. // deleted.
  441. ~RepeatedFieldAccessor() = default;
  442. };
  443. // Implement (Mutable)RepeatedFieldRef::iterator
  444. template<typename T>
  445. class RepeatedFieldRefIterator
  446. {
  447. typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
  448. typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
  449. typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
  450. public:
  451. using iterator_category = std::forward_iterator_tag;
  452. using value_type = T;
  453. using pointer = T*;
  454. using reference = T&;
  455. using difference_type = std::ptrdiff_t;
  456. // Constructor for non-message fields.
  457. RepeatedFieldRefIterator(const void* data, const RepeatedFieldAccessor* accessor, bool begin) :
  458. data_(data),
  459. accessor_(accessor),
  460. iterator_(begin ? accessor->BeginIterator(data) : accessor->EndIterator(data)),
  461. // The end iterator must not be dereferenced, no need for scratch space.
  462. scratch_space_(begin ? new AccessorValueType : nullptr)
  463. {
  464. }
  465. // Constructor for message fields.
  466. RepeatedFieldRefIterator(const void* data, const RepeatedFieldAccessor* accessor, bool begin, AccessorValueType* scratch_space) :
  467. data_(data),
  468. accessor_(accessor),
  469. iterator_(begin ? accessor->BeginIterator(data) : accessor->EndIterator(data)),
  470. scratch_space_(scratch_space)
  471. {
  472. }
  473. ~RepeatedFieldRefIterator()
  474. {
  475. accessor_->DeleteIterator(data_, iterator_);
  476. }
  477. RepeatedFieldRefIterator operator++(int)
  478. {
  479. RepeatedFieldRefIterator tmp(*this);
  480. iterator_ = accessor_->AdvanceIterator(data_, iterator_);
  481. return tmp;
  482. }
  483. RepeatedFieldRefIterator& operator++()
  484. {
  485. iterator_ = accessor_->AdvanceIterator(data_, iterator_);
  486. return *this;
  487. }
  488. IteratorValueType operator*() const
  489. {
  490. return static_cast<IteratorValueType>(
  491. *static_cast<const AccessorValueType*>(accessor_->GetIteratorValue(
  492. data_, iterator_, scratch_space_.get()
  493. ))
  494. );
  495. }
  496. IteratorPointerType operator->() const
  497. {
  498. return static_cast<IteratorPointerType>(
  499. accessor_->GetIteratorValue(data_, iterator_, scratch_space_.get())
  500. );
  501. }
  502. bool operator!=(const RepeatedFieldRefIterator& other) const
  503. {
  504. assert(data_ == other.data_);
  505. assert(accessor_ == other.accessor_);
  506. return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
  507. }
  508. bool operator==(const RepeatedFieldRefIterator& other) const
  509. {
  510. return !this->operator!=(other);
  511. }
  512. RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other) :
  513. data_(other.data_),
  514. accessor_(other.accessor_),
  515. iterator_(accessor_->CopyIterator(data_, other.iterator_))
  516. {
  517. }
  518. RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other)
  519. {
  520. if (this != &other)
  521. {
  522. accessor_->DeleteIterator(data_, iterator_);
  523. data_ = other.data_;
  524. accessor_ = other.accessor_;
  525. iterator_ = accessor_->CopyIterator(data_, other.iterator_);
  526. }
  527. return *this;
  528. }
  529. protected:
  530. const void* data_;
  531. const RepeatedFieldAccessor* accessor_;
  532. void* iterator_;
  533. std::unique_ptr<AccessorValueType> scratch_space_;
  534. };
  535. // TypeTraits that maps the type parameter T of RepeatedFieldRef or
  536. // MutableRepeatedFieldRef to corresponding iterator type,
  537. // RepeatedFieldAccessor type, etc.
  538. template<typename T>
  539. struct PrimitiveTraits
  540. {
  541. static constexpr bool is_primitive = false;
  542. };
  543. #define DEFINE_PRIMITIVE(TYPE, type) \
  544. template<> \
  545. struct PrimitiveTraits<type> \
  546. { \
  547. static const bool is_primitive = true; \
  548. static const FieldDescriptor::CppType cpp_type = \
  549. FieldDescriptor::CPPTYPE_##TYPE; \
  550. };
  551. DEFINE_PRIMITIVE(INT32, int32_t)
  552. DEFINE_PRIMITIVE(UINT32, uint32_t)
  553. DEFINE_PRIMITIVE(INT64, int64_t)
  554. DEFINE_PRIMITIVE(UINT64, uint64_t)
  555. DEFINE_PRIMITIVE(FLOAT, float)
  556. DEFINE_PRIMITIVE(DOUBLE, double)
  557. DEFINE_PRIMITIVE(BOOL, bool)
  558. #undef DEFINE_PRIMITIVE
  559. template<typename T>
  560. struct RefTypeTraits<
  561. T,
  562. typename std::enable_if<PrimitiveTraits<T>::is_primitive>::type>
  563. {
  564. typedef RepeatedFieldRefIterator<T> iterator;
  565. typedef RepeatedFieldAccessor AccessorType;
  566. typedef T AccessorValueType;
  567. typedef T IteratorValueType;
  568. typedef T* IteratorPointerType;
  569. static constexpr FieldDescriptor::CppType cpp_type =
  570. PrimitiveTraits<T>::cpp_type;
  571. static const Descriptor* GetMessageFieldDescriptor()
  572. {
  573. return nullptr;
  574. }
  575. };
  576. template<typename T>
  577. struct RefTypeTraits<
  578. T,
  579. typename std::enable_if<is_proto_enum<T>::value>::type>
  580. {
  581. typedef RepeatedFieldRefIterator<T> iterator;
  582. typedef RepeatedFieldAccessor AccessorType;
  583. // We use int32_t for repeated enums in RepeatedFieldAccessor.
  584. typedef int32_t AccessorValueType;
  585. typedef T IteratorValueType;
  586. typedef int32_t* IteratorPointerType;
  587. static constexpr FieldDescriptor::CppType cpp_type =
  588. FieldDescriptor::CPPTYPE_ENUM;
  589. static const Descriptor* GetMessageFieldDescriptor()
  590. {
  591. return nullptr;
  592. }
  593. };
  594. template<typename T>
  595. struct RefTypeTraits<
  596. T,
  597. typename std::enable_if<std::is_same<std::string, T>::value>::type>
  598. {
  599. typedef RepeatedFieldRefIterator<T> iterator;
  600. typedef RepeatedFieldAccessor AccessorType;
  601. typedef std::string AccessorValueType;
  602. typedef const std::string IteratorValueType;
  603. typedef const std::string* IteratorPointerType;
  604. static constexpr FieldDescriptor::CppType cpp_type =
  605. FieldDescriptor::CPPTYPE_STRING;
  606. static const Descriptor* GetMessageFieldDescriptor()
  607. {
  608. return nullptr;
  609. }
  610. };
  611. template<typename T>
  612. struct MessageDescriptorGetter
  613. {
  614. static const Descriptor* get()
  615. {
  616. return T::default_instance().GetDescriptor();
  617. }
  618. };
  619. template<>
  620. struct MessageDescriptorGetter<Message>
  621. {
  622. static const Descriptor* get()
  623. {
  624. return nullptr;
  625. }
  626. };
  627. template<typename T>
  628. struct RefTypeTraits<
  629. T,
  630. typename std::enable_if<std::is_base_of<Message, T>::value>::type>
  631. {
  632. typedef RepeatedFieldRefIterator<T> iterator;
  633. typedef RepeatedFieldAccessor AccessorType;
  634. typedef Message AccessorValueType;
  635. typedef const T& IteratorValueType;
  636. typedef const T* IteratorPointerType;
  637. static constexpr FieldDescriptor::CppType cpp_type =
  638. FieldDescriptor::CPPTYPE_MESSAGE;
  639. static const Descriptor* GetMessageFieldDescriptor()
  640. {
  641. return MessageDescriptorGetter<T>::get();
  642. }
  643. };
  644. } // namespace internal
  645. } // namespace protobuf
  646. } // namespace google
  647. #include <google/protobuf/port_undef.inc>
  648. #endif // GOOGLE_PROTOBUF_REFLECTION_H__