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 31 #ifndef GOOGLE_PROTOBUF_MAP_FIELD_H__ 32 #define GOOGLE_PROTOBUF_MAP_FIELD_H__ 33 34 #include <google/protobuf/stubs/atomicops.h> 35 #include <google/protobuf/stubs/mutex.h> 36 #include <google/protobuf/stubs/common.h> 37 #include <google/protobuf/generated_message_reflection.h> 38 #include <google/protobuf/arena.h> 39 #include <google/protobuf/descriptor.h> 40 #include <google/protobuf/map_entry.h> 41 #include <google/protobuf/map_field_lite.h> 42 #include <google/protobuf/map_type_handler.h> 43 #include <google/protobuf/message.h> 44 #include <google/protobuf/repeated_field.h> 45 #include <google/protobuf/unknown_field_set.h> 46 47 48 namespace google { 49 namespace protobuf { 50 class DynamicMessage; 51 class MapKey; 52 namespace internal { 53 54 class ContendedMapCleanTest; 55 class GeneratedMessageReflection; 56 class MapFieldAccessor; 57 58 // This class provides access to map field using reflection, which is the same 59 // as those provided for RepeatedPtrField<Message>. It is used for internal 60 // reflection implentation only. Users should never use this directly. 61 class LIBPROTOBUF_EXPORT MapFieldBase { 62 public: MapFieldBase()63 MapFieldBase() 64 : arena_(NULL), 65 repeated_field_(NULL), 66 state_(STATE_MODIFIED_MAP) {} MapFieldBase(Arena * arena)67 explicit MapFieldBase(Arena* arena) 68 : arena_(arena), 69 repeated_field_(NULL), 70 state_(STATE_MODIFIED_MAP) { 71 // Mutex's destructor needs to be called explicitly to release resources 72 // acquired in its constructor. 73 arena->OwnDestructor(&mutex_); 74 } 75 virtual ~MapFieldBase(); 76 77 // Returns reference to internal repeated field. Data written using 78 // google::protobuf::Map's api prior to calling this function is guarantted to be 79 // included in repeated field. 80 const RepeatedPtrFieldBase& GetRepeatedField() const; 81 82 // Like above. Returns mutable pointer to the internal repeated field. 83 RepeatedPtrFieldBase* MutableRepeatedField(); 84 85 // Pure virtual map APIs for Map Reflection. 86 virtual bool ContainsMapKey(const MapKey& map_key) const = 0; 87 virtual bool InsertOrLookupMapValue( 88 const MapKey& map_key, MapValueRef* val) = 0; 89 // Insures operations after won't get executed before calling this. 90 bool IsMapValid() const; 91 virtual bool DeleteMapValue(const MapKey& map_key) = 0; 92 virtual bool EqualIterator(const MapIterator& a, 93 const MapIterator& b) const = 0; 94 virtual void MapBegin(MapIterator* map_iter) const = 0; 95 virtual void MapEnd(MapIterator* map_iter) const = 0; 96 // Sync Map with repeated field and returns the size of map. 97 virtual int size() const = 0; 98 99 // Returns the number of bytes used by the repeated field, excluding 100 // sizeof(*this) 101 size_t SpaceUsedExcludingSelfLong() const; 102 SpaceUsedExcludingSelf()103 int SpaceUsedExcludingSelf() const { 104 return internal::ToIntSize(SpaceUsedExcludingSelfLong()); 105 } 106 107 protected: 108 // Gets the size of space used by map field. 109 virtual size_t SpaceUsedExcludingSelfNoLock() const; 110 111 // Synchronizes the content in Map to RepeatedPtrField if there is any change 112 // to Map after last synchronization. 113 void SyncRepeatedFieldWithMap() const; 114 virtual void SyncRepeatedFieldWithMapNoLock() const; 115 116 // Synchronizes the content in RepeatedPtrField to Map if there is any change 117 // to RepeatedPtrField after last synchronization. 118 void SyncMapWithRepeatedField() const; SyncMapWithRepeatedFieldNoLock()119 virtual void SyncMapWithRepeatedFieldNoLock() const {} 120 121 // Tells MapFieldBase that there is new change to Map. 122 void SetMapDirty(); 123 124 // Tells MapFieldBase that there is new change to RepeatedPTrField. 125 void SetRepeatedDirty(); 126 127 // Provides derived class the access to repeated field. 128 void* MutableRepeatedPtrField() const; 129 130 enum State { 131 STATE_MODIFIED_MAP = 0, // map has newly added data that has not been 132 // synchronized to repeated field 133 STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that 134 // has not been synchronized to map 135 CLEAN = 2, // data in map and repeated field are same 136 }; 137 138 Arena* arena_; 139 mutable RepeatedPtrField<Message>* repeated_field_; 140 141 mutable Mutex mutex_; // The thread to synchronize map and repeated field 142 // needs to get lock first; 143 mutable volatile Atomic32 state_; // 0: STATE_MODIFIED_MAP 144 // 1: STATE_MODIFIED_REPEATED 145 // 2: CLEAN 146 147 private: 148 friend class ContendedMapCleanTest; 149 friend class GeneratedMessageReflection; 150 friend class MapFieldAccessor; 151 friend class ::google::protobuf::DynamicMessage; 152 153 // Virtual helper methods for MapIterator. MapIterator doesn't have the 154 // type helper for key and value. Call these help methods to deal with 155 // different types. Real helper methods are implemented in 156 // TypeDefinedMapFieldBase. 157 friend class ::google::protobuf::MapIterator; 158 // Allocate map<...>::iterator for MapIterator. 159 virtual void InitializeIterator(MapIterator* map_iter) const = 0; 160 161 // DeleteIterator() is called by the destructor of MapIterator only. 162 // It deletes map<...>::iterator for MapIterator. 163 virtual void DeleteIterator(MapIterator* map_iter) const = 0; 164 165 // Copy the map<...>::iterator from other_iterator to 166 // this_iterator. 167 virtual void CopyIterator(MapIterator* this_iterator, 168 const MapIterator& other_iterator) const = 0; 169 170 // IncreaseIterator() is called by operator++() of MapIterator only. 171 // It implements the ++ operator of MapIterator. 172 virtual void IncreaseIterator(MapIterator* map_iter) const = 0; 173 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase); 174 }; 175 176 // This class provides common Map Reflection implementations for generated 177 // message and dynamic message. 178 template<typename Key, typename T> 179 class TypeDefinedMapFieldBase : public MapFieldBase { 180 public: TypeDefinedMapFieldBase()181 TypeDefinedMapFieldBase() {} TypeDefinedMapFieldBase(Arena * arena)182 explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} ~TypeDefinedMapFieldBase()183 ~TypeDefinedMapFieldBase() {} 184 void MapBegin(MapIterator* map_iter) const; 185 void MapEnd(MapIterator* map_iter) const; 186 bool EqualIterator(const MapIterator& a, const MapIterator& b) const; 187 188 virtual const Map<Key, T>& GetMap() const = 0; 189 virtual Map<Key, T>* MutableMap() = 0; 190 191 protected: 192 typename Map<Key, T>::const_iterator& InternalGetIterator( 193 const MapIterator* map_iter) const; 194 195 private: 196 void InitializeIterator(MapIterator* map_iter) const; 197 void DeleteIterator(MapIterator* map_iter) const; 198 void CopyIterator(MapIterator* this_iteratorm, 199 const MapIterator& that_iterator) const; 200 void IncreaseIterator(MapIterator* map_iter) const; 201 202 virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0; 203 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase); 204 }; 205 206 // This class provides access to map field using generated api. It is used for 207 // internal generated message implentation only. Users should never use this 208 // directly. 209 template <typename Derived, typename Key, typename T, 210 WireFormatLite::FieldType kKeyFieldType, 211 WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0> 212 class MapField : public TypeDefinedMapFieldBase<Key, T> { 213 // Provide utilities to parse/serialize key/value. Provide utilities to 214 // manipulate internal stored type. 215 typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; 216 typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler; 217 218 // Define message type for internal repeated field. 219 typedef Derived EntryType; 220 typedef MapEntryLite<Key, T, kKeyFieldType, kValueFieldType, 221 default_enum_value> EntryLiteType; 222 223 // Define abbreviation for parent MapFieldLite 224 typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType, 225 default_enum_value> 226 MapFieldLiteType; 227 228 // Enum needs to be handled differently from other types because it has 229 // different exposed type in google::protobuf::Map's api and repeated field's api. For 230 // details see the comment in the implementation of 231 // SyncMapWithRepeatedFieldNoLock. 232 static const bool kIsValueEnum = ValueTypeHandler::kIsEnum; 233 typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType; 234 235 public: 236 typedef typename Derived::SuperType EntryTypeTrait; 237 typedef Map<Key, T> MapType; 238 MapField()239 MapField() {} MapField(Arena * arena)240 explicit MapField(Arena* arena) 241 : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {} 242 243 // Implement MapFieldBase 244 bool ContainsMapKey(const MapKey& map_key) const; 245 bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); 246 bool DeleteMapValue(const MapKey& map_key); 247 GetMap()248 const Map<Key, T>& GetMap() const { 249 MapFieldBase::SyncMapWithRepeatedField(); 250 return impl_.GetMap(); 251 } 252 MutableMap()253 Map<Key, T>* MutableMap() { 254 MapFieldBase::SyncMapWithRepeatedField(); 255 Map<Key, T>* result = impl_.MutableMap(); 256 MapFieldBase::SetMapDirty(); 257 return result; 258 } 259 260 // Convenient methods for generated message implementation. 261 int size() const; 262 void Clear(); 263 void MergeFrom(const MapField& other); 264 void Swap(MapField* other); 265 266 // Used in the implementation of parsing. Caller should take the ownership iff 267 // arena_ is NULL. NewEntry()268 EntryType* NewEntry() const { return impl_.NewEntry(); } 269 // Used in the implementation of serializing enum value type. Caller should 270 // take the ownership iff arena_ is NULL. NewEnumEntryWrapper(const Key & key,const T t)271 EntryType* NewEnumEntryWrapper(const Key& key, const T t) const { 272 return impl_.NewEnumEntryWrapper(key, t); 273 } 274 // Used in the implementation of serializing other value types. Caller should 275 // take the ownership iff arena_ is NULL. NewEntryWrapper(const Key & key,const T & t)276 EntryType* NewEntryWrapper(const Key& key, const T& t) const { 277 return impl_.NewEntryWrapper(key, t); 278 } 279 280 private: 281 MapFieldLiteType impl_; 282 283 typedef void InternalArenaConstructable_; 284 typedef void DestructorSkippable_; 285 286 // Implements MapFieldBase 287 void SyncRepeatedFieldWithMapNoLock() const; 288 void SyncMapWithRepeatedFieldNoLock() const; 289 size_t SpaceUsedExcludingSelfNoLock() const; 290 291 void SetMapIteratorValue(MapIterator* map_iter) const; 292 293 friend class ::google::protobuf::Arena; 294 friend class MapFieldStateTest; // For testing, it needs raw access to impl_ 295 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField); 296 }; 297 298 template <typename MEntry> 299 struct MapEntryToMapField { 300 typedef DeconstructMapEntry<typename MEntry::SuperType> T; 301 typedef MapField<MEntry, typename T::Key, typename T::Value, T::kKeyFieldType, 302 T::kValueFieldType, T::default_enum_value> 303 MapFieldType; 304 }; 305 306 class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> { 307 public: 308 explicit DynamicMapField(const Message* default_entry); 309 DynamicMapField(const Message* default_entry, Arena* arena); 310 ~DynamicMapField(); 311 312 // Implement MapFieldBase 313 bool ContainsMapKey(const MapKey& map_key) const; 314 bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); 315 bool DeleteMapValue(const MapKey& map_key); 316 317 const Map<MapKey, MapValueRef>& GetMap() const; 318 Map<MapKey, MapValueRef>* MutableMap(); 319 320 int size() const; 321 322 private: 323 Map<MapKey, MapValueRef> map_; 324 const Message* default_entry_; 325 326 // Implements MapFieldBase 327 void SyncRepeatedFieldWithMapNoLock() const; 328 void SyncMapWithRepeatedFieldNoLock() const; 329 size_t SpaceUsedExcludingSelfNoLock() const; 330 void SetMapIteratorValue(MapIterator* map_iter) const; 331 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField); 332 }; 333 334 } // namespace internal 335 336 #define TYPE_CHECK(EXPECTEDTYPE, METHOD) \ 337 if (type() != EXPECTEDTYPE) { \ 338 GOOGLE_LOG(FATAL) \ 339 << "Protocol Buffer map usage error:\n" \ 340 << METHOD << " type does not match\n" \ 341 << " Expected : " \ 342 << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \ 343 << " Actual : " \ 344 << FieldDescriptor::CppTypeName(type()); \ 345 } 346 347 // MapKey is an union type for representing any possible 348 // map key. 349 class LIBPROTOBUF_EXPORT MapKey { 350 public: MapKey()351 MapKey() : type_(0) { 352 } MapKey(const MapKey & other)353 MapKey(const MapKey& other) : type_(0) { 354 CopyFrom(other); 355 } 356 MapKey& operator=(const MapKey& other) { 357 CopyFrom(other); 358 return *this; 359 } 360 ~MapKey()361 ~MapKey() { 362 if (type_ == FieldDescriptor::CPPTYPE_STRING) { 363 delete val_.string_value_; 364 } 365 } 366 type()367 FieldDescriptor::CppType type() const { 368 if (type_ == 0) { 369 GOOGLE_LOG(FATAL) 370 << "Protocol Buffer map usage error:\n" 371 << "MapKey::type MapKey is not initialized. " 372 << "Call set methods to initialize MapKey."; 373 } 374 return (FieldDescriptor::CppType)type_; 375 } 376 SetInt64Value(int64 value)377 void SetInt64Value(int64 value) { 378 SetType(FieldDescriptor::CPPTYPE_INT64); 379 val_.int64_value_ = value; 380 } SetUInt64Value(uint64 value)381 void SetUInt64Value(uint64 value) { 382 SetType(FieldDescriptor::CPPTYPE_UINT64); 383 val_.uint64_value_ = value; 384 } SetInt32Value(int32 value)385 void SetInt32Value(int32 value) { 386 SetType(FieldDescriptor::CPPTYPE_INT32); 387 val_.int32_value_ = value; 388 } SetUInt32Value(uint32 value)389 void SetUInt32Value(uint32 value) { 390 SetType(FieldDescriptor::CPPTYPE_UINT32); 391 val_.uint32_value_ = value; 392 } SetBoolValue(bool value)393 void SetBoolValue(bool value) { 394 SetType(FieldDescriptor::CPPTYPE_BOOL); 395 val_.bool_value_ = value; 396 } SetStringValue(const string & val)397 void SetStringValue(const string& val) { 398 SetType(FieldDescriptor::CPPTYPE_STRING); 399 *val_.string_value_ = val; 400 } 401 GetInt64Value()402 int64 GetInt64Value() const { 403 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, 404 "MapKey::GetInt64Value"); 405 return val_.int64_value_; 406 } GetUInt64Value()407 uint64 GetUInt64Value() const { 408 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, 409 "MapKey::GetUInt64Value"); 410 return val_.uint64_value_; 411 } GetInt32Value()412 int32 GetInt32Value() const { 413 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, 414 "MapKey::GetInt32Value"); 415 return val_.int32_value_; 416 } GetUInt32Value()417 uint32 GetUInt32Value() const { 418 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, 419 "MapKey::GetUInt32Value"); 420 return val_.uint32_value_; 421 } GetBoolValue()422 bool GetBoolValue() const { 423 TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, 424 "MapKey::GetBoolValue"); 425 return val_.bool_value_; 426 } GetStringValue()427 const string& GetStringValue() const { 428 TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, 429 "MapKey::GetStringValue"); 430 return *val_.string_value_; 431 } 432 433 bool operator<(const MapKey& other) const { 434 if (type_ != other.type_) { 435 // We could define a total order that handles this case, but 436 // there currently no need. So, for now, fail. 437 GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; 438 } 439 switch (type()) { 440 case FieldDescriptor::CPPTYPE_DOUBLE: 441 case FieldDescriptor::CPPTYPE_FLOAT: 442 case FieldDescriptor::CPPTYPE_ENUM: 443 case FieldDescriptor::CPPTYPE_MESSAGE: 444 GOOGLE_LOG(FATAL) << "Unsupported"; 445 return false; 446 case FieldDescriptor::CPPTYPE_STRING: 447 return *val_.string_value_ < *other.val_.string_value_; 448 case FieldDescriptor::CPPTYPE_INT64: 449 return val_.int64_value_ < other.val_.int64_value_; 450 case FieldDescriptor::CPPTYPE_INT32: 451 return val_.int32_value_ < other.val_.int32_value_; 452 case FieldDescriptor::CPPTYPE_UINT64: 453 return val_.uint64_value_ < other.val_.uint64_value_; 454 case FieldDescriptor::CPPTYPE_UINT32: 455 return val_.uint32_value_ < other.val_.uint32_value_; 456 case FieldDescriptor::CPPTYPE_BOOL: 457 return val_.bool_value_ < other.val_.bool_value_; 458 } 459 return false; 460 } 461 462 bool operator==(const MapKey& other) const { 463 if (type_ != other.type_) { 464 // To be consistent with operator<, we don't allow this either. 465 GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; 466 } 467 switch (type()) { 468 case FieldDescriptor::CPPTYPE_DOUBLE: 469 case FieldDescriptor::CPPTYPE_FLOAT: 470 case FieldDescriptor::CPPTYPE_ENUM: 471 case FieldDescriptor::CPPTYPE_MESSAGE: 472 GOOGLE_LOG(FATAL) << "Unsupported"; 473 break; 474 case FieldDescriptor::CPPTYPE_STRING: 475 return *val_.string_value_ == *other.val_.string_value_; 476 case FieldDescriptor::CPPTYPE_INT64: 477 return val_.int64_value_ == other.val_.int64_value_; 478 case FieldDescriptor::CPPTYPE_INT32: 479 return val_.int32_value_ == other.val_.int32_value_; 480 case FieldDescriptor::CPPTYPE_UINT64: 481 return val_.uint64_value_ == other.val_.uint64_value_; 482 case FieldDescriptor::CPPTYPE_UINT32: 483 return val_.uint32_value_ == other.val_.uint32_value_; 484 case FieldDescriptor::CPPTYPE_BOOL: 485 return val_.bool_value_ == other.val_.bool_value_; 486 } 487 GOOGLE_LOG(FATAL) << "Can't get here."; 488 return false; 489 } 490 CopyFrom(const MapKey & other)491 void CopyFrom(const MapKey& other) { 492 SetType(other.type()); 493 switch (type_) { 494 case FieldDescriptor::CPPTYPE_DOUBLE: 495 case FieldDescriptor::CPPTYPE_FLOAT: 496 case FieldDescriptor::CPPTYPE_ENUM: 497 case FieldDescriptor::CPPTYPE_MESSAGE: 498 GOOGLE_LOG(FATAL) << "Unsupported"; 499 break; 500 case FieldDescriptor::CPPTYPE_STRING: 501 *val_.string_value_ = *other.val_.string_value_; 502 break; 503 case FieldDescriptor::CPPTYPE_INT64: 504 val_.int64_value_ = other.val_.int64_value_; 505 break; 506 case FieldDescriptor::CPPTYPE_INT32: 507 val_.int32_value_ = other.val_.int32_value_; 508 break; 509 case FieldDescriptor::CPPTYPE_UINT64: 510 val_.uint64_value_ = other.val_.uint64_value_; 511 break; 512 case FieldDescriptor::CPPTYPE_UINT32: 513 val_.uint32_value_ = other.val_.uint32_value_; 514 break; 515 case FieldDescriptor::CPPTYPE_BOOL: 516 val_.bool_value_ = other.val_.bool_value_; 517 break; 518 } 519 } 520 521 private: 522 template <typename K, typename V> 523 friend class internal::TypeDefinedMapFieldBase; 524 friend class MapIterator; 525 friend class internal::DynamicMapField; 526 527 union KeyValue { KeyValue()528 KeyValue() {} 529 string* string_value_; 530 int64 int64_value_; 531 int32 int32_value_; 532 uint64 uint64_value_; 533 uint32 uint32_value_; 534 bool bool_value_; 535 } val_; 536 SetType(FieldDescriptor::CppType type)537 void SetType(FieldDescriptor::CppType type) { 538 if (type_ == type) return; 539 if (type_ == FieldDescriptor::CPPTYPE_STRING) { 540 delete val_.string_value_; 541 } 542 type_ = type; 543 if (type_ == FieldDescriptor::CPPTYPE_STRING) { 544 val_.string_value_ = new string; 545 } 546 } 547 548 // type_ is 0 or a valid FieldDescriptor::CppType. 549 int type_; 550 }; 551 552 // MapValueRef points to a map value. 553 class LIBPROTOBUF_EXPORT MapValueRef { 554 public: MapValueRef()555 MapValueRef() : data_(NULL), type_(0) {} 556 SetInt64Value(int64 value)557 void SetInt64Value(int64 value) { 558 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, 559 "MapValueRef::SetInt64Value"); 560 *reinterpret_cast<int64*>(data_) = value; 561 } SetUInt64Value(uint64 value)562 void SetUInt64Value(uint64 value) { 563 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, 564 "MapValueRef::SetUInt64Value"); 565 *reinterpret_cast<uint64*>(data_) = value; 566 } SetInt32Value(int32 value)567 void SetInt32Value(int32 value) { 568 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, 569 "MapValueRef::SetInt32Value"); 570 *reinterpret_cast<int32*>(data_) = value; 571 } SetUInt32Value(uint32 value)572 void SetUInt32Value(uint32 value) { 573 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, 574 "MapValueRef::SetUInt32Value"); 575 *reinterpret_cast<uint32*>(data_) = value; 576 } SetBoolValue(bool value)577 void SetBoolValue(bool value) { 578 TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, 579 "MapValueRef::SetBoolValue"); 580 *reinterpret_cast<bool*>(data_) = value; 581 } 582 // TODO(jieluo) - Checks that enum is member. SetEnumValue(int value)583 void SetEnumValue(int value) { 584 TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, 585 "MapValueRef::SetEnumValue"); 586 *reinterpret_cast<int*>(data_) = value; 587 } SetStringValue(const string & value)588 void SetStringValue(const string& value) { 589 TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, 590 "MapValueRef::SetStringValue"); 591 *reinterpret_cast<string*>(data_) = value; 592 } SetFloatValue(float value)593 void SetFloatValue(float value) { 594 TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, 595 "MapValueRef::SetFloatValue"); 596 *reinterpret_cast<float*>(data_) = value; 597 } SetDoubleValue(double value)598 void SetDoubleValue(double value) { 599 TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, 600 "MapValueRef::SetDoubleValue"); 601 *reinterpret_cast<double*>(data_) = value; 602 } 603 GetInt64Value()604 int64 GetInt64Value() const { 605 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, 606 "MapValueRef::GetInt64Value"); 607 return *reinterpret_cast<int64*>(data_); 608 } GetUInt64Value()609 uint64 GetUInt64Value() const { 610 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, 611 "MapValueRef::GetUInt64Value"); 612 return *reinterpret_cast<uint64*>(data_); 613 } GetInt32Value()614 int32 GetInt32Value() const { 615 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, 616 "MapValueRef::GetInt32Value"); 617 return *reinterpret_cast<int32*>(data_); 618 } GetUInt32Value()619 uint32 GetUInt32Value() const { 620 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, 621 "MapValueRef::GetUInt32Value"); 622 return *reinterpret_cast<uint32*>(data_); 623 } GetBoolValue()624 bool GetBoolValue() const { 625 TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, 626 "MapValueRef::GetBoolValue"); 627 return *reinterpret_cast<bool*>(data_); 628 } GetEnumValue()629 int GetEnumValue() const { 630 TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, 631 "MapValueRef::GetEnumValue"); 632 return *reinterpret_cast<int*>(data_); 633 } GetStringValue()634 const string& GetStringValue() const { 635 TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, 636 "MapValueRef::GetStringValue"); 637 return *reinterpret_cast<string*>(data_); 638 } GetFloatValue()639 float GetFloatValue() const { 640 TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, 641 "MapValueRef::GetFloatValue"); 642 return *reinterpret_cast<float*>(data_); 643 } GetDoubleValue()644 double GetDoubleValue() const { 645 TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, 646 "MapValueRef::GetDoubleValue"); 647 return *reinterpret_cast<double*>(data_); 648 } 649 GetMessageValue()650 const Message& GetMessageValue() const { 651 TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, 652 "MapValueRef::GetMessageValue"); 653 return *reinterpret_cast<Message*>(data_); 654 } 655 MutableMessageValue()656 Message* MutableMessageValue() { 657 TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, 658 "MapValueRef::MutableMessageValue"); 659 return reinterpret_cast<Message*>(data_); 660 } 661 662 private: 663 template <typename Derived, typename K, typename V, 664 internal::WireFormatLite::FieldType key_wire_type, 665 internal::WireFormatLite::FieldType value_wire_type, 666 int default_enum_value> 667 friend class internal::MapField; 668 template <typename K, typename V> 669 friend class internal::TypeDefinedMapFieldBase; 670 friend class MapIterator; 671 friend class internal::GeneratedMessageReflection; 672 friend class internal::DynamicMapField; 673 SetType(FieldDescriptor::CppType type)674 void SetType(FieldDescriptor::CppType type) { 675 type_ = type; 676 } 677 type()678 FieldDescriptor::CppType type() const { 679 if (type_ == 0 || data_ == NULL) { 680 GOOGLE_LOG(FATAL) 681 << "Protocol Buffer map usage error:\n" 682 << "MapValueRef::type MapValueRef is not initialized."; 683 } 684 return (FieldDescriptor::CppType)type_; 685 } SetValue(const void * val)686 void SetValue(const void* val) { 687 data_ = const_cast<void*>(val); 688 } CopyFrom(const MapValueRef & other)689 void CopyFrom(const MapValueRef& other) { 690 type_ = other.type_; 691 data_ = other.data_; 692 } 693 // Only used in DynamicMapField DeleteData()694 void DeleteData() { 695 switch (type_) { 696 #define HANDLE_TYPE(CPPTYPE, TYPE) \ 697 case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \ 698 delete reinterpret_cast<TYPE*>(data_); \ 699 break; \ 700 } 701 HANDLE_TYPE(INT32, int32); 702 HANDLE_TYPE(INT64, int64); 703 HANDLE_TYPE(UINT32, uint32); 704 HANDLE_TYPE(UINT64, uint64); 705 HANDLE_TYPE(DOUBLE, double); 706 HANDLE_TYPE(FLOAT, float); 707 HANDLE_TYPE(BOOL, bool); 708 HANDLE_TYPE(STRING, string); 709 HANDLE_TYPE(ENUM, int32); 710 HANDLE_TYPE(MESSAGE, Message); 711 #undef HANDLE_TYPE 712 } 713 } 714 // data_ point to a map value. MapValueRef does not 715 // own this value. 716 void* data_; 717 // type_ is 0 or a valid FieldDescriptor::CppType. 718 int type_; 719 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapValueRef); 720 }; 721 722 #undef TYPE_CHECK 723 724 class LIBPROTOBUF_EXPORT MapIterator { 725 public: MapIterator(Message * message,const FieldDescriptor * field)726 MapIterator(Message* message, const FieldDescriptor* field) { 727 const Reflection* reflection = message->GetReflection(); 728 map_ = reflection->MapData(message, field); 729 key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type()); 730 value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type()); 731 map_->InitializeIterator(this); 732 } MapIterator(const MapIterator & other)733 MapIterator(const MapIterator& other) { 734 map_ = other.map_; 735 map_->InitializeIterator(this); 736 map_->CopyIterator(this, other); 737 } ~MapIterator()738 ~MapIterator() { 739 map_->DeleteIterator(this); 740 } 741 MapIterator& operator=(const MapIterator& other) { 742 map_ = other.map_; 743 map_->CopyIterator(this, other); 744 return *this; 745 } 746 friend bool operator==(const MapIterator& a, const MapIterator& b) { 747 return a.map_->EqualIterator(a, b); 748 } 749 friend bool operator!=(const MapIterator& a, const MapIterator& b) { 750 return !a.map_->EqualIterator(a, b); 751 } 752 MapIterator& operator++() { 753 map_->IncreaseIterator(this); 754 return *this; 755 } 756 MapIterator operator++(int) { 757 // iter_ is copied from Map<...>::iterator, no need to 758 // copy from its self again. Use the same implementation 759 // with operator++() 760 map_->IncreaseIterator(this); 761 return *this; 762 } GetKey()763 const MapKey& GetKey() { 764 return key_; 765 } GetValueRef()766 const MapValueRef& GetValueRef() { 767 return value_; 768 } MutableValueRef()769 MapValueRef* MutableValueRef() { 770 map_->SetMapDirty(); 771 return &value_; 772 } 773 774 private: 775 template <typename Key, typename T> 776 friend class internal::TypeDefinedMapFieldBase; 777 friend class internal::DynamicMapField; 778 template <typename Derived, typename Key, typename T, 779 internal::WireFormatLite::FieldType kKeyFieldType, 780 internal::WireFormatLite::FieldType kValueFieldType, 781 int default_enum_value> 782 friend class internal::MapField; 783 784 // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns 785 // the iterator. It is allocated by MapField<...>::InitializeIterator() called 786 // in constructor and deleted by MapField<...>::DeleteIterator() called in 787 // destructor. 788 void* iter_; 789 // Point to a MapField to call helper methods implemented in MapField. 790 // MapIterator does not own this object. 791 internal::MapFieldBase* map_; 792 MapKey key_; 793 MapValueRef value_; 794 }; 795 796 } // namespace protobuf 797 } // namespace google 798 799 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START 800 template<> 801 struct hash<google::protobuf::MapKey> { 802 size_t 803 operator()(const google::protobuf::MapKey& map_key) const { 804 switch (map_key.type()) { 805 case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: 806 case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: 807 case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: 808 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: 809 GOOGLE_LOG(FATAL) << "Unsupported"; 810 break; 811 case google::protobuf::FieldDescriptor::CPPTYPE_STRING: 812 return hash<string>()(map_key.GetStringValue()); 813 case google::protobuf::FieldDescriptor::CPPTYPE_INT64: 814 return hash< ::google::protobuf::int64>()(map_key.GetInt64Value()); 815 case google::protobuf::FieldDescriptor::CPPTYPE_INT32: 816 return hash< ::google::protobuf::int32>()(map_key.GetInt32Value()); 817 case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: 818 return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value()); 819 case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: 820 return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value()); 821 case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: 822 return hash<bool>()(map_key.GetBoolValue()); 823 } 824 GOOGLE_LOG(FATAL) << "Can't get here."; 825 return 0; 826 } 827 bool 828 operator()(const google::protobuf::MapKey& map_key1, 829 const google::protobuf::MapKey& map_key2) const { 830 return map_key1 < map_key2; 831 } 832 }; 833 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END 834 835 #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__ 836