map_entry.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_H__
  31. #define GOOGLE_PROTOBUF_MAP_ENTRY_H__
  32. #include <google/protobuf/generated_message_reflection.h>
  33. #include <google/protobuf/map_entry_lite.h>
  34. #include <google/protobuf/map_type_handler.h>
  35. #include <google/protobuf/metadata.h>
  36. #include <google/protobuf/reflection_ops.h>
  37. #include <google/protobuf/unknown_field_set.h>
  38. #include <google/protobuf/wire_format_lite_inl.h>
  39. namespace google {
  40. namespace protobuf {
  41. class Arena;
  42. namespace internal {
  43. template <typename Key, typename Value,
  44. WireFormatLite::FieldType kKeyFieldType,
  45. WireFormatLite::FieldType kValueFieldType,
  46. int default_enum_value>
  47. class MapField;
  48. }
  49. }
  50. namespace protobuf {
  51. namespace internal {
  52. // Register all MapEntry default instances so we can delete them in
  53. // ShutdownProtobufLibrary().
  54. void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(
  55. MessageLite* default_instance);
  56. // This is the common base class for MapEntry. It is used by MapFieldBase in
  57. // reflection api, in which the static type of key and value is unknown.
  58. class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
  59. public:
  60. ::google::protobuf::Metadata GetMetadata() const {
  61. ::google::protobuf::Metadata metadata;
  62. metadata.descriptor = descriptor_;
  63. metadata.reflection = reflection_;
  64. return metadata;
  65. }
  66. protected:
  67. MapEntryBase() : descriptor_(NULL), reflection_(NULL) { }
  68. virtual ~MapEntryBase() {}
  69. const Descriptor* descriptor_;
  70. const Reflection* reflection_;
  71. };
  72. // MapEntry is the returned google::protobuf::Message when calling AddMessage of
  73. // google::protobuf::Reflection. In order to let it work with generated message
  74. // reflection, its in-memory type is the same as generated message with the same
  75. // fields. However, in order to decide the in-memory type of key/value, we need
  76. // to know both their cpp type in generated api and proto type. In
  77. // implmentation, all in-memory types have related wire format functions to
  78. // support except ArenaStringPtr. Therefore, we need to define another type with
  79. // supporting wire format functions. Since this type is only used as return type
  80. // of MapEntry accessors, it's named MapEntry accessor type.
  81. //
  82. // cpp type: the type visible to users in public API.
  83. // proto type: WireFormatLite::FieldType of the field.
  84. // in-memory type: type of the data member used to stored this field.
  85. // MapEntry accessor type: type used in MapEntry getters/mutators to access the
  86. // field.
  87. //
  88. // cpp type | proto type | in-memory type | MapEntry accessor type
  89. // int32 TYPE_INT32 int32 int32
  90. // int32 TYPE_FIXED32 int32 int32
  91. // string TYPE_STRING ArenaStringPtr string
  92. // FooEnum TYPE_ENUM int int
  93. // FooMessage TYPE_MESSAGE FooMessage* FooMessage
  94. //
  95. // The in-memory types of primitive types can be inferred from its proto type,
  96. // while we need to explicitly specify the cpp type if proto type is
  97. // TYPE_MESSAGE to infer the in-memory type. Moreover, default_enum_value is
  98. // used to initialize enum field in proto2.
  99. template <typename Key, typename Value,
  100. WireFormatLite::FieldType kKeyFieldType,
  101. WireFormatLite::FieldType kValueFieldType,
  102. int default_enum_value>
  103. class MapEntry : public MapEntryBase {
  104. // Provide utilities to parse/serialize key/value. Provide utilities to
  105. // manipulate internal stored type.
  106. typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
  107. typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
  108. // Enum type cannot be used for MapTypeHandler::Read. Define a type
  109. // which will replace Enum with int.
  110. typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
  111. typedef typename ValueTypeHandler::MapEntryAccessorType
  112. ValueMapEntryAccessorType;
  113. // Abbreviation for MapEntry
  114. typedef typename google::protobuf::internal::MapEntry<
  115. Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType;
  116. // Abbreviation for MapEntryLite
  117. typedef typename google::protobuf::internal::MapEntryLite<
  118. Key, Value, kKeyFieldType, kValueFieldType, default_enum_value>
  119. EntryLiteType;
  120. public:
  121. ~MapEntry() {
  122. if (this == default_instance_) {
  123. delete reflection_;
  124. }
  125. }
  126. // accessors ======================================================
  127. virtual inline const KeyMapEntryAccessorType& key() const {
  128. return entry_lite_.key();
  129. }
  130. inline KeyMapEntryAccessorType* mutable_key() {
  131. return entry_lite_.mutable_key();
  132. }
  133. virtual inline const ValueMapEntryAccessorType& value() const {
  134. return entry_lite_.value();
  135. }
  136. inline ValueMapEntryAccessorType* mutable_value() {
  137. return entry_lite_.mutable_value();
  138. }
  139. // implements Message =============================================
  140. bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
  141. return entry_lite_.MergePartialFromCodedStream(input);
  142. }
  143. int ByteSize() const {
  144. return entry_lite_.ByteSize();
  145. }
  146. void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
  147. entry_lite_.SerializeWithCachedSizes(output);
  148. }
  149. ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
  150. return entry_lite_.SerializeWithCachedSizesToArray(output);
  151. }
  152. int GetCachedSize() const {
  153. return entry_lite_.GetCachedSize();
  154. }
  155. bool IsInitialized() const {
  156. return entry_lite_.IsInitialized();
  157. }
  158. Message* New() const {
  159. MapEntry* entry = new MapEntry;
  160. entry->descriptor_ = descriptor_;
  161. entry->reflection_ = reflection_;
  162. entry->set_default_instance(default_instance_);
  163. return entry;
  164. }
  165. Message* New(Arena* arena) const {
  166. MapEntry* entry = Arena::CreateMessage<MapEntry>(arena);
  167. entry->descriptor_ = descriptor_;
  168. entry->reflection_ = reflection_;
  169. entry->set_default_instance(default_instance_);
  170. return entry;
  171. }
  172. int SpaceUsed() const {
  173. int size = sizeof(MapEntry);
  174. size += entry_lite_.SpaceUsed();
  175. return size;
  176. }
  177. void CopyFrom(const ::google::protobuf::Message& from) {
  178. Clear();
  179. MergeFrom(from);
  180. }
  181. void MergeFrom(const ::google::protobuf::Message& from) {
  182. GOOGLE_CHECK_NE(&from, this);
  183. const MapEntry* source = dynamic_cast_if_available<const MapEntry*>(&from);
  184. if (source == NULL) {
  185. ReflectionOps::Merge(from, this);
  186. } else {
  187. MergeFrom(*source);
  188. }
  189. }
  190. void CopyFrom(const MapEntry& from) {
  191. Clear();
  192. MergeFrom(from);
  193. }
  194. void MergeFrom(const MapEntry& from) {
  195. entry_lite_.MergeFrom(from.entry_lite_);
  196. }
  197. void Clear() {
  198. entry_lite_.Clear();
  199. }
  200. void InitAsDefaultInstance() {
  201. entry_lite_.InitAsDefaultInstance();
  202. }
  203. Arena* GetArena() const {
  204. return entry_lite_.GetArena();
  205. }
  206. // Create default MapEntry instance for given descriptor. Descriptor has to be
  207. // given when creating default MapEntry instance because different map field
  208. // may have the same type and MapEntry class. The given descriptor is needed
  209. // to distinguish instances of the same MapEntry class.
  210. static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) {
  211. MapEntry* entry = new MapEntry;
  212. const Reflection* reflection = new GeneratedMessageReflection(
  213. descriptor, entry, offsets_,
  214. GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
  215. GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
  216. DescriptorPool::generated_pool(),
  217. ::google::protobuf::MessageFactory::generated_factory(),
  218. sizeof(MapEntry),
  219. GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_));
  220. entry->descriptor_ = descriptor;
  221. entry->reflection_ = reflection;
  222. entry->set_default_instance(entry);
  223. entry->InitAsDefaultInstance();
  224. RegisterMapEntryDefaultInstance(entry);
  225. return entry;
  226. }
  227. private:
  228. MapEntry()
  229. : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {}
  230. explicit MapEntry(Arena* arena)
  231. : _internal_metadata_(arena),
  232. default_instance_(NULL),
  233. entry_lite_(arena) {}
  234. inline Arena* GetArenaNoVirtual() const {
  235. return entry_lite_.GetArenaNoVirtual();
  236. }
  237. void set_default_instance(MapEntry* default_instance) {
  238. default_instance_ = default_instance;
  239. entry_lite_.set_default_instance(&default_instance->entry_lite_);
  240. }
  241. static int offsets_[2];
  242. UnknownFieldSet _unknown_fields_;
  243. InternalMetadataWithArena _internal_metadata_;
  244. MapEntry* default_instance_;
  245. EntryLiteType entry_lite_;
  246. friend class ::google::protobuf::Arena;
  247. typedef void InternalArenaConstructable_;
  248. typedef void DestructorSkippable_;
  249. template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
  250. WireFormatLite::FieldType, int default_enum>
  251. friend class internal::MapField;
  252. friend class internal::GeneratedMessageReflection;
  253. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
  254. };
  255. template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
  256. WireFormatLite::FieldType kValueFieldType, int default_enum_value>
  257. int MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
  258. default_enum_value>::offsets_[2] = {
  259. GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_),
  260. GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_),
  261. };
  262. } // namespace internal
  263. } // namespace protobuf
  264. } // namespace google
  265. #endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__