/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/extension_set.h

http://github.com/tomahawk-player/tomahawk · C++ Header · 904 lines · 543 code · 102 blank · 259 comment · 0 complexity · fe3ad94e16def7dbbde450b880b449c8 MD5 · raw file

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // This header is logically internal, but is made public because it is used
  35. // from protocol-compiler-generated code, which may reside in other components.
  36. #ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
  37. #define GOOGLE_PROTOBUF_EXTENSION_SET_H__
  38. #include <vector>
  39. #include <map>
  40. #include <utility>
  41. #include <string>
  42. #include <google/protobuf/stubs/common.h>
  43. namespace google {
  44. namespace protobuf {
  45. class Descriptor; // descriptor.h
  46. class FieldDescriptor; // descriptor.h
  47. class DescriptorPool; // descriptor.h
  48. class MessageLite; // message_lite.h
  49. class Message; // message.h
  50. class MessageFactory; // message.h
  51. class UnknownFieldSet; // unknown_field_set.h
  52. namespace io {
  53. class CodedInputStream; // coded_stream.h
  54. class CodedOutputStream; // coded_stream.h
  55. }
  56. namespace internal {
  57. class FieldSkipper; // wire_format_lite.h
  58. class RepeatedPtrFieldBase; // repeated_field.h
  59. }
  60. template <typename Element> class RepeatedField; // repeated_field.h
  61. template <typename Element> class RepeatedPtrField; // repeated_field.h
  62. }
  63. namespace protobuf {
  64. namespace internal {
  65. // Used to store values of type WireFormatLite::FieldType without having to
  66. // #include wire_format_lite.h. Also, ensures that we use only one byte to
  67. // store these values, which is important to keep the layout of
  68. // ExtensionSet::Extension small.
  69. typedef uint8 FieldType;
  70. // A function which, given an integer value, returns true if the number
  71. // matches one of the defined values for the corresponding enum type. This
  72. // is used with RegisterEnumExtension, below.
  73. typedef bool EnumValidityFunc(int number);
  74. // Version of the above which takes an argument. This is needed to deal with
  75. // extensions that are not compiled in.
  76. typedef bool EnumValidityFuncWithArg(const void* arg, int number);
  77. // Information about a registered extension.
  78. struct ExtensionInfo {
  79. inline ExtensionInfo() {}
  80. inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
  81. : type(type), is_repeated(is_repeated), is_packed(is_packed),
  82. descriptor(NULL) {}
  83. FieldType type;
  84. bool is_repeated;
  85. bool is_packed;
  86. struct EnumValidityCheck {
  87. EnumValidityFuncWithArg* func;
  88. const void* arg;
  89. };
  90. union {
  91. EnumValidityCheck enum_validity_check;
  92. const MessageLite* message_prototype;
  93. };
  94. // The descriptor for this extension, if one exists and is known. May be
  95. // NULL. Must not be NULL if the descriptor for the extension does not
  96. // live in the same pool as the descriptor for the containing type.
  97. const FieldDescriptor* descriptor;
  98. };
  99. // Abstract interface for an object which looks up extension definitions. Used
  100. // when parsing.
  101. class LIBPROTOBUF_EXPORT ExtensionFinder {
  102. public:
  103. virtual ~ExtensionFinder();
  104. // Find the extension with the given containing type and number.
  105. virtual bool Find(int number, ExtensionInfo* output) = 0;
  106. };
  107. // Implementation of ExtensionFinder which finds extensions defined in .proto
  108. // files which have been compiled into the binary.
  109. class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
  110. public:
  111. GeneratedExtensionFinder(const MessageLite* containing_type)
  112. : containing_type_(containing_type) {}
  113. virtual ~GeneratedExtensionFinder() {}
  114. // Returns true and fills in *output if found, otherwise returns false.
  115. virtual bool Find(int number, ExtensionInfo* output);
  116. private:
  117. const MessageLite* containing_type_;
  118. };
  119. // Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
  120. // finding extensions from a DescriptorPool.
  121. // This is an internal helper class intended for use within the protocol buffer
  122. // library and generated classes. Clients should not use it directly. Instead,
  123. // use the generated accessors such as GetExtension() of the class being
  124. // extended.
  125. //
  126. // This class manages extensions for a protocol message object. The
  127. // message's HasExtension(), GetExtension(), MutableExtension(), and
  128. // ClearExtension() methods are just thin wrappers around the embedded
  129. // ExtensionSet. When parsing, if a tag number is encountered which is
  130. // inside one of the message type's extension ranges, the tag is passed
  131. // off to the ExtensionSet for parsing. Etc.
  132. class LIBPROTOBUF_EXPORT ExtensionSet {
  133. public:
  134. ExtensionSet();
  135. ~ExtensionSet();
  136. // These are called at startup by protocol-compiler-generated code to
  137. // register known extensions. The registrations are used by ParseField()
  138. // to look up extensions for parsed field numbers. Note that dynamic parsing
  139. // does not use ParseField(); only protocol-compiler-generated parsing
  140. // methods do.
  141. static void RegisterExtension(const MessageLite* containing_type,
  142. int number, FieldType type,
  143. bool is_repeated, bool is_packed);
  144. static void RegisterEnumExtension(const MessageLite* containing_type,
  145. int number, FieldType type,
  146. bool is_repeated, bool is_packed,
  147. EnumValidityFunc* is_valid);
  148. static void RegisterMessageExtension(const MessageLite* containing_type,
  149. int number, FieldType type,
  150. bool is_repeated, bool is_packed,
  151. const MessageLite* prototype);
  152. // =================================================================
  153. // Add all fields which are currently present to the given vector. This
  154. // is useful to implement Reflection::ListFields().
  155. void AppendToList(const Descriptor* containing_type,
  156. const DescriptorPool* pool,
  157. vector<const FieldDescriptor*>* output) const;
  158. // =================================================================
  159. // Accessors
  160. //
  161. // Generated message classes include type-safe templated wrappers around
  162. // these methods. Generally you should use those rather than call these
  163. // directly, unless you are doing low-level memory management.
  164. //
  165. // When calling any of these accessors, the extension number requested
  166. // MUST exist in the DescriptorPool provided to the constructor. Otheriwse,
  167. // the method will fail an assert. Normally, though, you would not call
  168. // these directly; you would either call the generated accessors of your
  169. // message class (e.g. GetExtension()) or you would call the accessors
  170. // of the reflection interface. In both cases, it is impossible to
  171. // trigger this assert failure: the generated accessors only accept
  172. // linked-in extension types as parameters, while the Reflection interface
  173. // requires you to provide the FieldDescriptor describing the extension.
  174. //
  175. // When calling any of these accessors, a protocol-compiler-generated
  176. // implementation of the extension corresponding to the number MUST
  177. // be linked in, and the FieldDescriptor used to refer to it MUST be
  178. // the one generated by that linked-in code. Otherwise, the method will
  179. // die on an assert failure. The message objects returned by the message
  180. // accessors are guaranteed to be of the correct linked-in type.
  181. //
  182. // These methods pretty much match Reflection except that:
  183. // - They're not virtual.
  184. // - They identify fields by number rather than FieldDescriptors.
  185. // - They identify enum values using integers rather than descriptors.
  186. // - Strings provide Mutable() in addition to Set() accessors.
  187. bool Has(int number) const;
  188. int ExtensionSize(int number) const; // Size of a repeated extension.
  189. FieldType ExtensionType(int number) const;
  190. void ClearExtension(int number);
  191. // singular fields -------------------------------------------------
  192. int32 GetInt32 (int number, int32 default_value) const;
  193. int64 GetInt64 (int number, int64 default_value) const;
  194. uint32 GetUInt32(int number, uint32 default_value) const;
  195. uint64 GetUInt64(int number, uint64 default_value) const;
  196. float GetFloat (int number, float default_value) const;
  197. double GetDouble(int number, double default_value) const;
  198. bool GetBool (int number, bool default_value) const;
  199. int GetEnum (int number, int default_value) const;
  200. const string & GetString (int number, const string& default_value) const;
  201. const MessageLite& GetMessage(int number,
  202. const MessageLite& default_value) const;
  203. const MessageLite& GetMessage(int number, const Descriptor* message_type,
  204. MessageFactory* factory) const;
  205. // |descriptor| may be NULL so long as it is known that the descriptor for
  206. // the extension lives in the same pool as the descriptor for the containing
  207. // type.
  208. #define desc const FieldDescriptor* descriptor // avoid line wrapping
  209. void SetInt32 (int number, FieldType type, int32 value, desc);
  210. void SetInt64 (int number, FieldType type, int64 value, desc);
  211. void SetUInt32(int number, FieldType type, uint32 value, desc);
  212. void SetUInt64(int number, FieldType type, uint64 value, desc);
  213. void SetFloat (int number, FieldType type, float value, desc);
  214. void SetDouble(int number, FieldType type, double value, desc);
  215. void SetBool (int number, FieldType type, bool value, desc);
  216. void SetEnum (int number, FieldType type, int value, desc);
  217. void SetString(int number, FieldType type, const string& value, desc);
  218. string * MutableString (int number, FieldType type, desc);
  219. MessageLite* MutableMessage(int number, FieldType type,
  220. const MessageLite& prototype, desc);
  221. MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
  222. MessageFactory* factory);
  223. #undef desc
  224. // repeated fields -------------------------------------------------
  225. int32 GetRepeatedInt32 (int number, int index) const;
  226. int64 GetRepeatedInt64 (int number, int index) const;
  227. uint32 GetRepeatedUInt32(int number, int index) const;
  228. uint64 GetRepeatedUInt64(int number, int index) const;
  229. float GetRepeatedFloat (int number, int index) const;
  230. double GetRepeatedDouble(int number, int index) const;
  231. bool GetRepeatedBool (int number, int index) const;
  232. int GetRepeatedEnum (int number, int index) const;
  233. const string & GetRepeatedString (int number, int index) const;
  234. const MessageLite& GetRepeatedMessage(int number, int index) const;
  235. void SetRepeatedInt32 (int number, int index, int32 value);
  236. void SetRepeatedInt64 (int number, int index, int64 value);
  237. void SetRepeatedUInt32(int number, int index, uint32 value);
  238. void SetRepeatedUInt64(int number, int index, uint64 value);
  239. void SetRepeatedFloat (int number, int index, float value);
  240. void SetRepeatedDouble(int number, int index, double value);
  241. void SetRepeatedBool (int number, int index, bool value);
  242. void SetRepeatedEnum (int number, int index, int value);
  243. void SetRepeatedString(int number, int index, const string& value);
  244. string * MutableRepeatedString (int number, int index);
  245. MessageLite* MutableRepeatedMessage(int number, int index);
  246. #define desc const FieldDescriptor* descriptor // avoid line wrapping
  247. void AddInt32 (int number, FieldType type, bool packed, int32 value, desc);
  248. void AddInt64 (int number, FieldType type, bool packed, int64 value, desc);
  249. void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
  250. void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
  251. void AddFloat (int number, FieldType type, bool packed, float value, desc);
  252. void AddDouble(int number, FieldType type, bool packed, double value, desc);
  253. void AddBool (int number, FieldType type, bool packed, bool value, desc);
  254. void AddEnum (int number, FieldType type, bool packed, int value, desc);
  255. void AddString(int number, FieldType type, const string& value, desc);
  256. string * AddString (int number, FieldType type, desc);
  257. MessageLite* AddMessage(int number, FieldType type,
  258. const MessageLite& prototype, desc);
  259. MessageLite* AddMessage(const FieldDescriptor* descriptor,
  260. MessageFactory* factory);
  261. #undef desc
  262. void RemoveLast(int number);
  263. void SwapElements(int number, int index1, int index2);
  264. // -----------------------------------------------------------------
  265. // TODO(kenton): Hardcore memory management accessors
  266. // =================================================================
  267. // convenience methods for implementing methods of Message
  268. //
  269. // These could all be implemented in terms of the other methods of this
  270. // class, but providing them here helps keep the generated code size down.
  271. void Clear();
  272. void MergeFrom(const ExtensionSet& other);
  273. void Swap(ExtensionSet* other);
  274. bool IsInitialized() const;
  275. // Parses a single extension from the input. The input should start out
  276. // positioned immediately after the tag. |containing_type| is the default
  277. // instance for the containing message; it is used only to look up the
  278. // extension by number. See RegisterExtension(), above. Unlike the other
  279. // methods of ExtensionSet, this only works for generated message types --
  280. // it looks up extensions registered using RegisterExtension().
  281. bool ParseField(uint32 tag, io::CodedInputStream* input,
  282. ExtensionFinder* extension_finder,
  283. FieldSkipper* field_skipper);
  284. // Specific versions for lite or full messages (constructs the appropriate
  285. // FieldSkipper automatically).
  286. bool ParseField(uint32 tag, io::CodedInputStream* input,
  287. const MessageLite* containing_type);
  288. bool ParseField(uint32 tag, io::CodedInputStream* input,
  289. const Message* containing_type,
  290. UnknownFieldSet* unknown_fields);
  291. // Parse an entire message in MessageSet format. Such messages have no
  292. // fields, only extensions.
  293. bool ParseMessageSet(io::CodedInputStream* input,
  294. ExtensionFinder* extension_finder,
  295. FieldSkipper* field_skipper);
  296. // Specific versions for lite or full messages (constructs the appropriate
  297. // FieldSkipper automatically).
  298. bool ParseMessageSet(io::CodedInputStream* input,
  299. const MessageLite* containing_type);
  300. bool ParseMessageSet(io::CodedInputStream* input,
  301. const Message* containing_type,
  302. UnknownFieldSet* unknown_fields);
  303. // Write all extension fields with field numbers in the range
  304. // [start_field_number, end_field_number)
  305. // to the output stream, using the cached sizes computed when ByteSize() was
  306. // last called. Note that the range bounds are inclusive-exclusive.
  307. void SerializeWithCachedSizes(int start_field_number,
  308. int end_field_number,
  309. io::CodedOutputStream* output) const;
  310. // Same as SerializeWithCachedSizes, but without any bounds checking.
  311. // The caller must ensure that target has sufficient capacity for the
  312. // serialized extensions.
  313. //
  314. // Returns a pointer past the last written byte.
  315. uint8* SerializeWithCachedSizesToArray(int start_field_number,
  316. int end_field_number,
  317. uint8* target) const;
  318. // Like above but serializes in MessageSet format.
  319. void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
  320. uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
  321. // Returns the total serialized size of all the extensions.
  322. int ByteSize() const;
  323. // Like ByteSize() but uses MessageSet format.
  324. int MessageSetByteSize() const;
  325. // Returns (an estimate of) the total number of bytes used for storing the
  326. // extensions in memory, excluding sizeof(*this). If the ExtensionSet is
  327. // for a lite message (and thus possibly contains lite messages), the results
  328. // are undefined (might work, might crash, might corrupt data, might not even
  329. // be linked in). It's up to the protocol compiler to avoid calling this on
  330. // such ExtensionSets (easy enough since lite messages don't implement
  331. // SpaceUsed()).
  332. int SpaceUsedExcludingSelf() const;
  333. private:
  334. struct Extension {
  335. union {
  336. int32 int32_value;
  337. int64 int64_value;
  338. uint32 uint32_value;
  339. uint64 uint64_value;
  340. float float_value;
  341. double double_value;
  342. bool bool_value;
  343. int enum_value;
  344. string* string_value;
  345. MessageLite* message_value;
  346. RepeatedField <int32 >* repeated_int32_value;
  347. RepeatedField <int64 >* repeated_int64_value;
  348. RepeatedField <uint32 >* repeated_uint32_value;
  349. RepeatedField <uint64 >* repeated_uint64_value;
  350. RepeatedField <float >* repeated_float_value;
  351. RepeatedField <double >* repeated_double_value;
  352. RepeatedField <bool >* repeated_bool_value;
  353. RepeatedField <int >* repeated_enum_value;
  354. RepeatedPtrField<string >* repeated_string_value;
  355. RepeatedPtrField<MessageLite>* repeated_message_value;
  356. };
  357. FieldType type;
  358. bool is_repeated;
  359. // For singular types, indicates if the extension is "cleared". This
  360. // happens when an extension is set and then later cleared by the caller.
  361. // We want to keep the Extension object around for reuse, so instead of
  362. // removing it from the map, we just set is_cleared = true. This has no
  363. // meaning for repeated types; for those, the size of the RepeatedField
  364. // simply becomes zero when cleared.
  365. bool is_cleared;
  366. // For repeated types, this indicates if the [packed=true] option is set.
  367. bool is_packed;
  368. // The descriptor for this extension, if one exists and is known. May be
  369. // NULL. Must not be NULL if the descriptor for the extension does not
  370. // live in the same pool as the descriptor for the containing type.
  371. const FieldDescriptor* descriptor;
  372. // For packed fields, the size of the packed data is recorded here when
  373. // ByteSize() is called then used during serialization.
  374. // TODO(kenton): Use atomic<int> when C++ supports it.
  375. mutable int cached_size;
  376. // Some helper methods for operations on a single Extension.
  377. void SerializeFieldWithCachedSizes(
  378. int number,
  379. io::CodedOutputStream* output) const;
  380. uint8* SerializeFieldWithCachedSizesToArray(
  381. int number,
  382. uint8* target) const;
  383. void SerializeMessageSetItemWithCachedSizes(
  384. int number,
  385. io::CodedOutputStream* output) const;
  386. uint8* SerializeMessageSetItemWithCachedSizesToArray(
  387. int number,
  388. uint8* target) const;
  389. int ByteSize(int number) const;
  390. int MessageSetItemByteSize(int number) const;
  391. void Clear();
  392. int GetSize() const;
  393. void Free();
  394. int SpaceUsedExcludingSelf() const;
  395. };
  396. // Gets the extension with the given number, creating it if it does not
  397. // already exist. Returns true if the extension did not already exist.
  398. bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
  399. Extension** result);
  400. // Parse a single MessageSet item -- called just after the item group start
  401. // tag has been read.
  402. bool ParseMessageSetItem(io::CodedInputStream* input,
  403. ExtensionFinder* extension_finder,
  404. FieldSkipper* field_skipper);
  405. // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
  406. // friendship should automatically extend to ExtensionSet::Extension, but
  407. // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
  408. // correctly. So, we must provide helpers for calling methods of that
  409. // class.
  410. // Defined in extension_set_heavy.cc.
  411. static inline int RepeatedMessage_SpaceUsedExcludingSelf(
  412. RepeatedPtrFieldBase* field);
  413. // The Extension struct is small enough to be passed by value, so we use it
  414. // directly as the value type in the map rather than use pointers. We use
  415. // a map rather than hash_map here because we expect most ExtensionSets will
  416. // only contain a small number of extensions whereas hash_map is optimized
  417. // for 100 elements or more. Also, we want AppendToList() to order fields
  418. // by field number.
  419. map<int, Extension> extensions_;
  420. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
  421. };
  422. // These are just for convenience...
  423. inline void ExtensionSet::SetString(int number, FieldType type,
  424. const string& value,
  425. const FieldDescriptor* descriptor) {
  426. MutableString(number, type, descriptor)->assign(value);
  427. }
  428. inline void ExtensionSet::SetRepeatedString(int number, int index,
  429. const string& value) {
  430. MutableRepeatedString(number, index)->assign(value);
  431. }
  432. inline void ExtensionSet::AddString(int number, FieldType type,
  433. const string& value,
  434. const FieldDescriptor* descriptor) {
  435. AddString(number, type, descriptor)->assign(value);
  436. }
  437. // ===================================================================
  438. // Glue for generated extension accessors
  439. // -------------------------------------------------------------------
  440. // Template magic
  441. // First we have a set of classes representing "type traits" for different
  442. // field types. A type traits class knows how to implement basic accessors
  443. // for extensions of a particular type given an ExtensionSet. The signature
  444. // for a type traits class looks like this:
  445. //
  446. // class TypeTraits {
  447. // public:
  448. // typedef ? ConstType;
  449. // typedef ? MutableType;
  450. //
  451. // static inline ConstType Get(int number, const ExtensionSet& set);
  452. // static inline void Set(int number, ConstType value, ExtensionSet* set);
  453. // static inline MutableType Mutable(int number, ExtensionSet* set);
  454. //
  455. // // Variants for repeated fields.
  456. // static inline ConstType Get(int number, const ExtensionSet& set,
  457. // int index);
  458. // static inline void Set(int number, int index,
  459. // ConstType value, ExtensionSet* set);
  460. // static inline MutableType Mutable(int number, int index,
  461. // ExtensionSet* set);
  462. // static inline void Add(int number, ConstType value, ExtensionSet* set);
  463. // static inline MutableType Add(int number, ExtensionSet* set);
  464. // };
  465. //
  466. // Not all of these methods make sense for all field types. For example, the
  467. // "Mutable" methods only make sense for strings and messages, and the
  468. // repeated methods only make sense for repeated types. So, each type
  469. // traits class implements only the set of methods from this signature that it
  470. // actually supports. This will cause a compiler error if the user tries to
  471. // access an extension using a method that doesn't make sense for its type.
  472. // For example, if "foo" is an extension of type "optional int32", then if you
  473. // try to write code like:
  474. // my_message.MutableExtension(foo)
  475. // you will get a compile error because PrimitiveTypeTraits<int32> does not
  476. // have a "Mutable()" method.
  477. // -------------------------------------------------------------------
  478. // PrimitiveTypeTraits
  479. // Since the ExtensionSet has different methods for each primitive type,
  480. // we must explicitly define the methods of the type traits class for each
  481. // known type.
  482. template <typename Type>
  483. class PrimitiveTypeTraits {
  484. public:
  485. typedef Type ConstType;
  486. static inline ConstType Get(int number, const ExtensionSet& set,
  487. ConstType default_value);
  488. static inline void Set(int number, FieldType field_type,
  489. ConstType value, ExtensionSet* set);
  490. };
  491. template <typename Type>
  492. class RepeatedPrimitiveTypeTraits {
  493. public:
  494. typedef Type ConstType;
  495. static inline Type Get(int number, const ExtensionSet& set, int index);
  496. static inline void Set(int number, int index, Type value, ExtensionSet* set);
  497. static inline void Add(int number, FieldType field_type,
  498. bool is_packed, Type value, ExtensionSet* set);
  499. };
  500. #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \
  501. template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get( \
  502. int number, const ExtensionSet& set, TYPE default_value) { \
  503. return set.Get##METHOD(number, default_value); \
  504. } \
  505. template<> inline void PrimitiveTypeTraits<TYPE>::Set( \
  506. int number, FieldType field_type, TYPE value, ExtensionSet* set) { \
  507. set->Set##METHOD(number, field_type, value, NULL); \
  508. } \
  509. \
  510. template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \
  511. int number, const ExtensionSet& set, int index) { \
  512. return set.GetRepeated##METHOD(number, index); \
  513. } \
  514. template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \
  515. int number, int index, TYPE value, ExtensionSet* set) { \
  516. set->SetRepeated##METHOD(number, index, value); \
  517. } \
  518. template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
  519. int number, FieldType field_type, bool is_packed, \
  520. TYPE value, ExtensionSet* set) { \
  521. set->Add##METHOD(number, field_type, is_packed, value, NULL); \
  522. }
  523. PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32)
  524. PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64)
  525. PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
  526. PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
  527. PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float)
  528. PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
  529. PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool)
  530. #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
  531. // -------------------------------------------------------------------
  532. // StringTypeTraits
  533. // Strings support both Set() and Mutable().
  534. class LIBPROTOBUF_EXPORT StringTypeTraits {
  535. public:
  536. typedef const string& ConstType;
  537. typedef string* MutableType;
  538. static inline const string& Get(int number, const ExtensionSet& set,
  539. ConstType default_value) {
  540. return set.GetString(number, default_value);
  541. }
  542. static inline void Set(int number, FieldType field_type,
  543. const string& value, ExtensionSet* set) {
  544. set->SetString(number, field_type, value, NULL);
  545. }
  546. static inline string* Mutable(int number, FieldType field_type,
  547. ExtensionSet* set) {
  548. return set->MutableString(number, field_type, NULL);
  549. }
  550. };
  551. class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
  552. public:
  553. typedef const string& ConstType;
  554. typedef string* MutableType;
  555. static inline const string& Get(int number, const ExtensionSet& set,
  556. int index) {
  557. return set.GetRepeatedString(number, index);
  558. }
  559. static inline void Set(int number, int index,
  560. const string& value, ExtensionSet* set) {
  561. set->SetRepeatedString(number, index, value);
  562. }
  563. static inline string* Mutable(int number, int index, ExtensionSet* set) {
  564. return set->MutableRepeatedString(number, index);
  565. }
  566. static inline void Add(int number, FieldType field_type,
  567. bool /*is_packed*/, const string& value,
  568. ExtensionSet* set) {
  569. set->AddString(number, field_type, value, NULL);
  570. }
  571. static inline string* Add(int number, FieldType field_type,
  572. ExtensionSet* set) {
  573. return set->AddString(number, field_type, NULL);
  574. }
  575. };
  576. // -------------------------------------------------------------------
  577. // EnumTypeTraits
  578. // ExtensionSet represents enums using integers internally, so we have to
  579. // static_cast around.
  580. template <typename Type, bool IsValid(int)>
  581. class EnumTypeTraits {
  582. public:
  583. typedef Type ConstType;
  584. static inline ConstType Get(int number, const ExtensionSet& set,
  585. ConstType default_value) {
  586. return static_cast<Type>(set.GetEnum(number, default_value));
  587. }
  588. static inline void Set(int number, FieldType field_type,
  589. ConstType value, ExtensionSet* set) {
  590. GOOGLE_DCHECK(IsValid(value));
  591. set->SetEnum(number, field_type, value, NULL);
  592. }
  593. };
  594. template <typename Type, bool IsValid(int)>
  595. class RepeatedEnumTypeTraits {
  596. public:
  597. typedef Type ConstType;
  598. static inline ConstType Get(int number, const ExtensionSet& set, int index) {
  599. return static_cast<Type>(set.GetRepeatedEnum(number, index));
  600. }
  601. static inline void Set(int number, int index,
  602. ConstType value, ExtensionSet* set) {
  603. GOOGLE_DCHECK(IsValid(value));
  604. set->SetRepeatedEnum(number, index, value);
  605. }
  606. static inline void Add(int number, FieldType field_type,
  607. bool is_packed, ConstType value, ExtensionSet* set) {
  608. GOOGLE_DCHECK(IsValid(value));
  609. set->AddEnum(number, field_type, is_packed, value, NULL);
  610. }
  611. };
  612. // -------------------------------------------------------------------
  613. // MessageTypeTraits
  614. // ExtensionSet guarantees that when manipulating extensions with message
  615. // types, the implementation used will be the compiled-in class representing
  616. // that type. So, we can static_cast down to the exact type we expect.
  617. template <typename Type>
  618. class MessageTypeTraits {
  619. public:
  620. typedef const Type& ConstType;
  621. typedef Type* MutableType;
  622. static inline ConstType Get(int number, const ExtensionSet& set,
  623. ConstType default_value) {
  624. return static_cast<const Type&>(
  625. set.GetMessage(number, default_value));
  626. }
  627. static inline MutableType Mutable(int number, FieldType field_type,
  628. ExtensionSet* set) {
  629. return static_cast<Type*>(
  630. set->MutableMessage(number, field_type, Type::default_instance(), NULL));
  631. }
  632. };
  633. template <typename Type>
  634. class RepeatedMessageTypeTraits {
  635. public:
  636. typedef const Type& ConstType;
  637. typedef Type* MutableType;
  638. static inline ConstType Get(int number, const ExtensionSet& set, int index) {
  639. return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
  640. }
  641. static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
  642. return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
  643. }
  644. static inline MutableType Add(int number, FieldType field_type,
  645. ExtensionSet* set) {
  646. return static_cast<Type*>(
  647. set->AddMessage(number, field_type, Type::default_instance(), NULL));
  648. }
  649. };
  650. // -------------------------------------------------------------------
  651. // ExtensionIdentifier
  652. // This is the type of actual extension objects. E.g. if you have:
  653. // extends Foo with optional int32 bar = 1234;
  654. // then "bar" will be defined in C++ as:
  655. // ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 1, false> bar(1234);
  656. //
  657. // Note that we could, in theory, supply the field number as a template
  658. // parameter, and thus make an instance of ExtensionIdentifier have no
  659. // actual contents. However, if we did that, then using at extension
  660. // identifier would not necessarily cause the compiler to output any sort
  661. // of reference to any simple defined in the extension's .pb.o file. Some
  662. // linkers will actually drop object files that are not explicitly referenced,
  663. // but that would be bad because it would cause this extension to not be
  664. // registered at static initialization, and therefore using it would crash.
  665. template <typename ExtendeeType, typename TypeTraitsType,
  666. FieldType field_type, bool is_packed>
  667. class ExtensionIdentifier {
  668. public:
  669. typedef TypeTraitsType TypeTraits;
  670. typedef ExtendeeType Extendee;
  671. ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
  672. : number_(number), default_value_(default_value) {}
  673. inline int number() const { return number_; }
  674. typename TypeTraits::ConstType default_value() const {
  675. return default_value_;
  676. }
  677. private:
  678. const int number_;
  679. typename TypeTraits::ConstType default_value_;
  680. };
  681. // -------------------------------------------------------------------
  682. // Generated accessors
  683. // This macro should be expanded in the context of a generated type which
  684. // has extensions.
  685. //
  686. // We use "_proto_TypeTraits" as a type name below because "TypeTraits"
  687. // causes problems if the class has a nested message or enum type with that
  688. // name and "_TypeTraits" is technically reserved for the C++ library since
  689. // it starts with an underscore followed by a capital letter.
  690. #define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \
  691. /* Has, Size, Clear */ \
  692. template <typename _proto_TypeTraits, \
  693. ::google::protobuf::internal::FieldType field_type, \
  694. bool is_packed> \
  695. inline bool HasExtension( \
  696. const ::google::protobuf::internal::ExtensionIdentifier< \
  697. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
  698. return _extensions_.Has(id.number()); \
  699. } \
  700. \
  701. template <typename _proto_TypeTraits, \
  702. ::google::protobuf::internal::FieldType field_type, \
  703. bool is_packed> \
  704. inline void ClearExtension( \
  705. const ::google::protobuf::internal::ExtensionIdentifier< \
  706. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
  707. _extensions_.ClearExtension(id.number()); \
  708. } \
  709. \
  710. template <typename _proto_TypeTraits, \
  711. ::google::protobuf::internal::FieldType field_type, \
  712. bool is_packed> \
  713. inline int ExtensionSize( \
  714. const ::google::protobuf::internal::ExtensionIdentifier< \
  715. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
  716. return _extensions_.ExtensionSize(id.number()); \
  717. } \
  718. \
  719. /* Singular accessors */ \
  720. template <typename _proto_TypeTraits, \
  721. ::google::protobuf::internal::FieldType field_type, \
  722. bool is_packed> \
  723. inline typename _proto_TypeTraits::ConstType GetExtension( \
  724. const ::google::protobuf::internal::ExtensionIdentifier< \
  725. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
  726. return _proto_TypeTraits::Get(id.number(), _extensions_, \
  727. id.default_value()); \
  728. } \
  729. \
  730. template <typename _proto_TypeTraits, \
  731. ::google::protobuf::internal::FieldType field_type, \
  732. bool is_packed> \
  733. inline typename _proto_TypeTraits::MutableType MutableExtension( \
  734. const ::google::protobuf::internal::ExtensionIdentifier< \
  735. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
  736. return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\
  737. } \
  738. \
  739. template <typename _proto_TypeTraits, \
  740. ::google::protobuf::internal::FieldType field_type, \
  741. bool is_packed> \
  742. inline void SetExtension( \
  743. const ::google::protobuf::internal::ExtensionIdentifier< \
  744. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
  745. typename _proto_TypeTraits::ConstType value) { \
  746. _proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_); \
  747. } \
  748. \
  749. /* Repeated accessors */ \
  750. template <typename _proto_TypeTraits, \
  751. ::google::protobuf::internal::FieldType field_type, \
  752. bool is_packed> \
  753. inline typename _proto_TypeTraits::ConstType GetExtension( \
  754. const ::google::protobuf::internal::ExtensionIdentifier< \
  755. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
  756. int index) const { \
  757. return _proto_TypeTraits::Get(id.number(), _extensions_, index); \
  758. } \
  759. \
  760. template <typename _proto_TypeTraits, \
  761. ::google::protobuf::internal::FieldType field_type, \
  762. bool is_packed> \
  763. inline typename _proto_TypeTraits::MutableType MutableExtension( \
  764. const ::google::protobuf::internal::ExtensionIdentifier< \
  765. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
  766. int index) { \
  767. return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \
  768. } \
  769. \
  770. template <typename _proto_TypeTraits, \
  771. ::google::protobuf::internal::FieldType field_type, \
  772. bool is_packed> \
  773. inline void SetExtension( \
  774. const ::google::protobuf::internal::ExtensionIdentifier< \
  775. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
  776. int index, typename _proto_TypeTraits::ConstType value) { \
  777. _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \
  778. } \
  779. \
  780. template <typename _proto_TypeTraits, \
  781. ::google::protobuf::internal::FieldType field_type, \
  782. bool is_packed> \
  783. inline typename _proto_TypeTraits::MutableType AddExtension( \
  784. const ::google::protobuf::internal::ExtensionIdentifier< \
  785. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
  786. return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_); \
  787. } \
  788. \
  789. template <typename _proto_TypeTraits, \
  790. ::google::protobuf::internal::FieldType field_type, \
  791. bool is_packed> \
  792. inline void AddExtension( \
  793. const ::google::protobuf::internal::ExtensionIdentifier< \
  794. CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
  795. typename _proto_TypeTraits::ConstType value) { \
  796. _proto_TypeTraits::Add(id.number(), field_type, is_packed, \
  797. value, &_extensions_); \
  798. }
  799. } // namespace internal
  800. } // namespace protobuf
  801. } // namespace google
  802. #endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__