Home | History | Annotate | Download | only in protobuf
      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/map_entry.h>
     40 #include <google/protobuf/map_field_lite.h>
     41 #include <google/protobuf/map_type_handler.h>
     42 #include <google/protobuf/message.h>
     43 #include <google/protobuf/repeated_field.h>
     44 #include <google/protobuf/unknown_field_set.h>
     45 
     46 
     47 namespace google {
     48 namespace protobuf {
     49 class DynamicMessage;
     50 class MapKey;
     51 namespace internal {
     52 
     53 class ContendedMapCleanTest;
     54 class GeneratedMessageReflection;
     55 class MapFieldAccessor;
     56 
     57 // This class provides accesss to map field using reflection, which is the same
     58 // as those provided for RepeatedPtrField<Message>. It is used for internal
     59 // reflection implentation only. Users should never use this directly.
     60 class LIBPROTOBUF_EXPORT MapFieldBase {
     61  public:
     62   MapFieldBase()
     63       : arena_(NULL),
     64         repeated_field_(NULL),
     65         entry_descriptor_(NULL),
     66         assign_descriptor_callback_(NULL),
     67         state_(STATE_MODIFIED_MAP) {}
     68   explicit MapFieldBase(Arena* arena)
     69       : arena_(arena),
     70         repeated_field_(NULL),
     71         entry_descriptor_(NULL),
     72         assign_descriptor_callback_(NULL),
     73         state_(STATE_MODIFIED_MAP) {
     74     // Mutex's destructor needs to be called explicitly to release resources
     75     // acquired in its constructor.
     76     arena->OwnDestructor(&mutex_);
     77   }
     78   virtual ~MapFieldBase();
     79 
     80   // Returns reference to internal repeated field. Data written using
     81   // google::protobuf::Map's api prior to calling this function is guarantted to be
     82   // included in repeated field.
     83   const RepeatedPtrFieldBase& GetRepeatedField() const;
     84 
     85   // Like above. Returns mutable pointer to the internal repeated field.
     86   RepeatedPtrFieldBase* MutableRepeatedField();
     87 
     88   // Pure virtual map APIs for Map Reflection.
     89   virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
     90   virtual bool InsertOrLookupMapValue(
     91       const MapKey& map_key, MapValueRef* val) = 0;
     92   virtual bool DeleteMapValue(const MapKey& map_key) = 0;
     93   virtual bool EqualIterator(const MapIterator& a,
     94                              const MapIterator& b) const = 0;
     95   virtual void MapBegin(MapIterator* map_iter) const = 0;
     96   virtual void MapEnd(MapIterator* map_iter) const = 0;
     97   // Sync Map with repeated field and returns the size of map.
     98   virtual int size() const = 0;
     99 
    100   // Returns the number of bytes used by the repeated field, excluding
    101   // sizeof(*this)
    102   int SpaceUsedExcludingSelf() const;
    103 
    104  protected:
    105   // Gets the size of space used by map field.
    106   virtual int SpaceUsedExcludingSelfNoLock() const;
    107 
    108   // Synchronizes the content in Map to RepeatedPtrField if there is any change
    109   // to Map after last synchronization.
    110   void SyncRepeatedFieldWithMap() const;
    111   virtual void SyncRepeatedFieldWithMapNoLock() const;
    112 
    113   // Synchronizes the content in RepeatedPtrField to Map if there is any change
    114   // to RepeatedPtrField after last synchronization.
    115   void SyncMapWithRepeatedField() const;
    116   virtual void SyncMapWithRepeatedFieldNoLock() const {}
    117 
    118   // Tells MapFieldBase that there is new change to Map.
    119   void SetMapDirty();
    120 
    121   // Tells MapFieldBase that there is new change to RepeatedPTrField.
    122   void SetRepeatedDirty();
    123 
    124   // Provides derived class the access to repeated field.
    125   void* MutableRepeatedPtrField() const;
    126 
    127   // Creates descriptor for only one time.
    128   void InitMetadataOnce() 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   // MapEntry can only be created from MapField. To create MapEntry, MapField
    141   // needs to know its descriptor, because MapEntry is not generated class which
    142   // cannot initialize its own descriptor by calling generated
    143   // descriptor-assign-function. Thus, we need to register a callback to
    144   // initialize MapEntry's descriptor.
    145   const Descriptor** entry_descriptor_;
    146   void (*assign_descriptor_callback_)();
    147 
    148   mutable Mutex mutex_;  // The thread to synchronize map and repeated field
    149                          // needs to get lock first;
    150   mutable volatile Atomic32 state_;  // 0: STATE_MODIFIED_MAP
    151                                      // 1: STATE_MODIFIED_REPEATED
    152                                      // 2: CLEAN
    153 
    154  private:
    155   friend class ContendedMapCleanTest;
    156   friend class GeneratedMessageReflection;
    157   friend class MapFieldAccessor;
    158   friend class ::google::protobuf::DynamicMessage;
    159 
    160   // Virtual helper methods for MapIterator. MapIterator doesn't have the
    161   // type helper for key and value. Call these help methods to deal with
    162   // different types. Real helper methods are implemented in
    163   // TypeDefinedMapFieldBase.
    164   friend class ::google::protobuf::MapIterator;
    165   // Allocate map<...>::iterator for MapIterator.
    166   virtual void InitializeIterator(MapIterator* map_iter) const = 0;
    167 
    168   // DeleteIterator() is called by the destructor of MapIterator only.
    169   // It deletes map<...>::iterator for MapIterator.
    170   virtual void DeleteIterator(MapIterator* map_iter) const = 0;
    171 
    172   // Copy the map<...>::iterator from other_iterator to
    173   // this_iterator.
    174   virtual void CopyIterator(MapIterator* this_iterator,
    175                             const MapIterator& other_iterator) const = 0;
    176 
    177   // IncreaseIterator() is called by operator++() of MapIterator only.
    178   // It implements the ++ operator of MapIterator.
    179   virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
    180 };
    181 
    182 // This class provides common Map Reflection implementations for generated
    183 // message and dynamic message.
    184 template<typename Key, typename T>
    185 class TypeDefinedMapFieldBase : public MapFieldBase {
    186  public:
    187   TypeDefinedMapFieldBase() {}
    188   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
    189   ~TypeDefinedMapFieldBase() {}
    190   void MapBegin(MapIterator* map_iter) const;
    191   void MapEnd(MapIterator* map_iter) const;
    192   bool EqualIterator(const MapIterator& a, const MapIterator& b) const;
    193 
    194   virtual const Map<Key, T>& GetMap() const = 0;
    195   virtual Map<Key, T>* MutableMap() = 0;
    196 
    197  protected:
    198   typename Map<Key, T>::const_iterator& InternalGetIterator(
    199       const MapIterator* map_iter) const;
    200 
    201  private:
    202   void InitializeIterator(MapIterator* map_iter) const;
    203   void DeleteIterator(MapIterator* map_iter) const;
    204   void CopyIterator(MapIterator* this_iteratorm,
    205                     const MapIterator& that_iterator) const;
    206   void IncreaseIterator(MapIterator* map_iter) const;
    207 
    208   virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
    209 };
    210 
    211 // This class provides accesss to map field using generated api. It is used for
    212 // internal generated message implentation only. Users should never use this
    213 // directly.
    214 template <typename Key, typename T,
    215           WireFormatLite::FieldType kKeyFieldType,
    216           WireFormatLite::FieldType kValueFieldType,
    217           int default_enum_value = 0>
    218 class MapField : public TypeDefinedMapFieldBase<Key, T>,
    219                  public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
    220                                      default_enum_value> {
    221   // Provide utilities to parse/serialize key/value.  Provide utilities to
    222   // manipulate internal stored type.
    223   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
    224   typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
    225 
    226   // Define message type for internal repeated field.
    227   typedef MapEntry<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>
    228       EntryType;
    229   typedef MapEntryLite<Key, T, kKeyFieldType, kValueFieldType,
    230                        default_enum_value> EntryLiteType;
    231 
    232   // Define abbreviation for parent MapFieldLite
    233   typedef MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
    234                        default_enum_value> MapFieldLiteType;
    235 
    236   // Enum needs to be handled differently from other types because it has
    237   // different exposed type in google::protobuf::Map's api and repeated field's api. For
    238   // details see the comment in the implementation of
    239   // SyncMapWithRepeatedFieldNoLock.
    240   static const bool kIsValueEnum = ValueTypeHandler::kIsEnum;
    241   typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
    242 
    243  public:
    244   MapField();
    245   explicit MapField(Arena* arena);
    246   // MapField doesn't own the default_entry, which means default_entry must
    247   // outlive the lifetime of MapField.
    248   MapField(const Message* default_entry);
    249   // For tests only.
    250   MapField(Arena* arena, const Message* default_entry);
    251   ~MapField();
    252 
    253   // Implement MapFieldBase
    254   bool ContainsMapKey(const MapKey& map_key) const;
    255   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
    256   bool DeleteMapValue(const MapKey& map_key);
    257 
    258   // Accessors
    259   const Map<Key, T>& GetMap() const;
    260   Map<Key, T>* MutableMap();
    261 
    262   // Convenient methods for generated message implementation.
    263   int size() const;
    264   void Clear();
    265   void MergeFrom(const MapFieldLiteType& other);
    266   void Swap(MapFieldLiteType* other);
    267 
    268   // Allocates metadata only if this MapField is part of a generated message.
    269   void SetEntryDescriptor(const Descriptor** descriptor);
    270   void SetAssignDescriptorCallback(void (*callback)());
    271 
    272  private:
    273   typedef void InternalArenaConstructable_;
    274   typedef void DestructorSkippable_;
    275 
    276   // MapField needs MapEntry's default instance to create new MapEntry.
    277   void InitDefaultEntryOnce() const;
    278 
    279   // Manually set default entry instance. For test only.
    280   void SetDefaultEntryOnce(const EntryType* default_entry) const;
    281 
    282   // Convenient methods to get internal google::protobuf::Map
    283   const Map<Key, T>& GetInternalMap() const;
    284   Map<Key, T>* MutableInternalMap();
    285 
    286   // Implements MapFieldBase
    287   void SyncRepeatedFieldWithMapNoLock() const;
    288   void SyncMapWithRepeatedFieldNoLock() const;
    289   int SpaceUsedExcludingSelfNoLock() const;
    290 
    291   void SetMapIteratorValue(MapIterator* map_iter) const;
    292 
    293   mutable const EntryType* default_entry_;
    294 
    295   friend class ::google::protobuf::Arena;
    296 };
    297 
    298 class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
    299  public:
    300   explicit DynamicMapField(const Message* default_entry);
    301   DynamicMapField(const Message* default_entry, Arena* arena);
    302   ~DynamicMapField();
    303 
    304   // Implement MapFieldBase
    305   bool ContainsMapKey(const MapKey& map_key) const;
    306   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
    307   bool DeleteMapValue(const MapKey& map_key);
    308 
    309   const Map<MapKey, MapValueRef>& GetMap() const;
    310   Map<MapKey, MapValueRef>* MutableMap();
    311 
    312   int size() const;
    313 
    314  private:
    315   Map<MapKey, MapValueRef> map_;
    316   const Message* default_entry_;
    317 
    318   // Implements MapFieldBase
    319   void SyncRepeatedFieldWithMapNoLock() const;
    320   void SyncMapWithRepeatedFieldNoLock() const;
    321   int SpaceUsedExcludingSelfNoLock() const;
    322   void SetMapIteratorValue(MapIterator* map_iter) const;
    323 };
    324 
    325 }  // namespace internal
    326 
    327 class LIBPROTOBUF_EXPORT MapIterator {
    328  public:
    329   MapIterator(Message* message, const FieldDescriptor* field) {
    330     const Reflection* reflection = message->GetReflection();
    331     map_ = reflection->MapData(message, field);
    332     key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
    333     value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
    334     map_->InitializeIterator(this);
    335   }
    336   MapIterator(const MapIterator& other) {
    337     map_ = other.map_;
    338     map_->InitializeIterator(this);
    339     map_->CopyIterator(this, other);
    340   }
    341   ~MapIterator() {
    342     map_->DeleteIterator(this);
    343   }
    344   friend bool operator==(const MapIterator& a, const MapIterator& b) {
    345     return a.map_->EqualIterator(a, b);
    346   }
    347   friend bool operator!=(const MapIterator& a, const MapIterator& b) {
    348     return !a.map_->EqualIterator(a, b);
    349   }
    350   MapIterator& operator++() {
    351     map_->IncreaseIterator(this);
    352     return *this;
    353   }
    354   MapIterator operator++(int) {
    355     // iter_ is copied from Map<...>::iterator, no need to
    356     // copy from its self again. Use the same implementation
    357     // with operator++()
    358     map_->IncreaseIterator(this);
    359     return *this;
    360   }
    361   const MapKey& GetKey() {
    362     return key_;
    363   }
    364   const MapValueRef& GetValueRef() {
    365     return value_;
    366   }
    367   MapValueRef* MutableValueRef() {
    368     map_->SetMapDirty();
    369     return &value_;
    370   }
    371 
    372  private:
    373   template <typename Key, typename T>
    374   friend class internal::TypeDefinedMapFieldBase;
    375   friend class internal::DynamicMapField;
    376   template <typename Key, typename T,
    377             internal::WireFormatLite::FieldType kKeyFieldType,
    378             internal::WireFormatLite::FieldType kValueFieldType,
    379             int default_enum_value>
    380   friend class internal::MapField;
    381 
    382   // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
    383   // the iterator. It is allocated by MapField<...>::InitializeIterator() called
    384   // in constructor and deleted by MapField<...>::DeleteIterator() called in
    385   // destructor.
    386   void* iter_;
    387   // Point to a MapField to call helper methods implemented in MapField.
    388   // MapIterator does not own this object.
    389   internal::MapFieldBase* map_;
    390   MapKey key_;
    391   MapValueRef value_;
    392 };
    393 
    394 }  // namespace protobuf
    395 
    396 }  // namespace google
    397 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
    398