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_REFLECTION_INTERNAL_H__
     32 #define GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
     33 
     34 #include <google/protobuf/map_field.h>
     35 #include <google/protobuf/reflection.h>
     36 #include <google/protobuf/repeated_field.h>
     37 
     38 namespace google {
     39 namespace protobuf {
     40 namespace internal {
     41 // A base class for RepeatedFieldAccessor implementations that can support
     42 // random-access efficiently. All iterator methods delegates the work to
     43 // corresponding random-access methods.
     44 class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor {
     45  public:
     46   virtual ~RandomAccessRepeatedFieldAccessor() {}
     47 
     48   virtual Iterator* BeginIterator(const Field* data) const {
     49     return PositionToIterator(0);
     50   }
     51   virtual Iterator* EndIterator(const Field* data) const {
     52     return PositionToIterator(this->Size(data));
     53   }
     54   virtual Iterator* CopyIterator(const Field* data,
     55                                  const Iterator* iterator) const {
     56     return const_cast<Iterator*>(iterator);
     57   }
     58   virtual Iterator* AdvanceIterator(const Field* data,
     59                                     Iterator* iterator) const {
     60     return PositionToIterator(IteratorToPosition(iterator) + 1);
     61   }
     62   virtual bool EqualsIterator(const Field* data,
     63                               const Iterator* a,
     64                               const Iterator* b) const {
     65     return a == b;
     66   }
     67   virtual void DeleteIterator(const Field* data, Iterator* iterator) const {
     68   }
     69   virtual const Value* GetIteratorValue(const Field* data,
     70                                         const Iterator* iterator,
     71                                         Value* scratch_space) const {
     72     return Get(data, static_cast<int>(IteratorToPosition(iterator)),
     73                scratch_space);
     74   }
     75 
     76  private:
     77   static intptr_t IteratorToPosition(const Iterator* iterator) {
     78     return reinterpret_cast<intptr_t>(iterator);
     79   }
     80   static Iterator* PositionToIterator(intptr_t position) {
     81     return reinterpret_cast<Iterator*>(position);
     82   }
     83 };
     84 
     85 // Base class for RepeatedFieldAccessor implementations that manipulates
     86 // RepeatedField<T>.
     87 template<typename T>
     88 class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor {
     89  public:
     90   RepeatedFieldWrapper() {}
     91   virtual ~RepeatedFieldWrapper() {}
     92   virtual bool IsEmpty(const Field* data) const {
     93     return GetRepeatedField(data)->empty();
     94   }
     95   virtual int Size(const Field* data) const {
     96     return GetRepeatedField(data)->size();
     97   }
     98   virtual const Value* Get(const Field* data, int index,
     99                           Value* scratch_space) const {
    100     return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
    101   }
    102   virtual void Clear(Field* data) const {
    103     MutableRepeatedField(data)->Clear();
    104   }
    105   virtual void Set(Field* data, int index, const Value* value) const {
    106     MutableRepeatedField(data)->Set(index, ConvertToT(value));
    107   }
    108   virtual void Add(Field* data, const Value* value) const {
    109     MutableRepeatedField(data)->Add(ConvertToT(value));
    110   }
    111   virtual void RemoveLast(Field* data) const {
    112     MutableRepeatedField(data)->RemoveLast();
    113   }
    114   virtual void SwapElements(Field* data, int index1, int index2) const {
    115     MutableRepeatedField(data)->SwapElements(index1, index2);
    116   }
    117 
    118  protected:
    119   typedef RepeatedField<T> RepeatedFieldType;
    120   static const RepeatedFieldType* GetRepeatedField(const Field* data) {
    121     return reinterpret_cast<const RepeatedFieldType*>(data);
    122   }
    123   static RepeatedFieldType* MutableRepeatedField(Field* data) {
    124     return reinterpret_cast<RepeatedFieldType*>(data);
    125   }
    126 
    127   // Convert an object recevied by this accessor to an object to be stored in
    128   // the underlying RepeatedField.
    129   virtual T ConvertToT(const Value* value) const = 0;
    130 
    131   // Convert an object stored in RepeatedPtrField to an object that will be
    132   // returned by this accessor. If the two objects have the same type (true
    133   // for string fields with ctype=STRING), a pointer to the source object can
    134   // be returned directly. Otherwise, data should be copied from value to
    135   // scratch_space and scratch_space should be returned.
    136   virtual const Value* ConvertFromT(const T& value,
    137                                     Value* scratch_space) const = 0;
    138 };
    139 
    140 // Base class for RepeatedFieldAccessor implementations that manipulates
    141 // RepeatedPtrField<T>.
    142 template<typename T>
    143 class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor {
    144  public:
    145   RepeatedPtrFieldWrapper() {}
    146   virtual ~RepeatedPtrFieldWrapper() {}
    147   virtual bool IsEmpty(const Field* data) const {
    148     return GetRepeatedField(data)->empty();
    149   }
    150   virtual int Size(const Field* data) const {
    151     return GetRepeatedField(data)->size();
    152   }
    153   virtual const Value* Get(const Field* data, int index,
    154                            Value* scratch_space) const {
    155     return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
    156   }
    157   virtual void Clear(Field* data) const {
    158     MutableRepeatedField(data)->Clear();
    159   }
    160   virtual void Set(Field* data, int index, const Value* value) const {
    161     ConvertToT(value, MutableRepeatedField(data)->Mutable(index));
    162   }
    163   virtual void Add(Field* data, const Value* value) const {
    164     T* allocated = New(value);
    165     ConvertToT(value, allocated);
    166     MutableRepeatedField(data)->AddAllocated(allocated);
    167   }
    168   virtual void RemoveLast(Field* data) const {
    169     MutableRepeatedField(data)->RemoveLast();
    170   }
    171   virtual void SwapElements(Field* data, int index1, int index2) const {
    172     MutableRepeatedField(data)->SwapElements(index1, index2);
    173   }
    174 
    175  protected:
    176   typedef RepeatedPtrField<T> RepeatedFieldType;
    177   static const RepeatedFieldType* GetRepeatedField(const Field* data) {
    178     return reinterpret_cast<const RepeatedFieldType*>(data);
    179   }
    180   static RepeatedFieldType* MutableRepeatedField(Field* data) {
    181     return reinterpret_cast<RepeatedFieldType*>(data);
    182   }
    183 
    184   // Create a new T instance. For repeated message fields, T can be specified
    185   // as google::protobuf::Message so we can't use "new T()" directly. In that case, value
    186   // should be a message of the same type (it's ensured by the caller) and a
    187   // new message object will be created using it.
    188   virtual T* New(const Value* value) const = 0;
    189 
    190   // Convert an object received by this accessor to an object that will be
    191   // stored in the underlying RepeatedPtrField.
    192   virtual void ConvertToT(const Value* value, T* result) const = 0;
    193 
    194   // Convert an object stored in RepeatedPtrField to an object that will be
    195   // returned by this accessor. If the two objects have the same type (true
    196   // for string fields with ctype=STRING), a pointer to the source object can
    197   // be returned directly. Otherwise, data should be copied from value to
    198   // scratch_space and scratch_space should be returned.
    199   virtual const Value* ConvertFromT(const T& value,
    200                                     Value* scratch_space) const = 0;
    201 };
    202 
    203 // An implementation of RandomAccessRepeatedFieldAccessor that manipulates
    204 // MapFieldBase.
    205 class MapFieldAccessor : public RandomAccessRepeatedFieldAccessor {
    206  public:
    207   MapFieldAccessor() {}
    208   virtual ~MapFieldAccessor() {}
    209   virtual bool IsEmpty(const Field* data) const {
    210     return GetRepeatedField(data)->empty();
    211   }
    212   virtual int Size(const Field* data) const {
    213     return GetRepeatedField(data)->size();
    214   }
    215   virtual const Value* Get(const Field* data, int index,
    216                            Value* scratch_space) const {
    217     return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space);
    218   }
    219   virtual void Clear(Field* data) const {
    220     MutableRepeatedField(data)->Clear();
    221   }
    222   virtual void Set(Field* data, int index, const Value* value) const {
    223     ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index));
    224   }
    225   virtual void Add(Field* data, const Value* value) const {
    226     Message* allocated = New(value);
    227     ConvertToEntry(value, allocated);
    228     MutableRepeatedField(data)->AddAllocated(allocated);
    229   }
    230   virtual void RemoveLast(Field* data) const {
    231     MutableRepeatedField(data)->RemoveLast();
    232   }
    233   virtual void SwapElements(Field* data, int index1, int index2) const {
    234     MutableRepeatedField(data)->SwapElements(index1, index2);
    235   }
    236   virtual void Swap(
    237       Field* data,
    238       const internal::RepeatedFieldAccessor* other_mutator,
    239       Field* other_data) const {
    240     GOOGLE_CHECK(this == other_mutator);
    241     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
    242   }
    243 
    244  protected:
    245   typedef RepeatedPtrField<Message> RepeatedFieldType;
    246   static const RepeatedFieldType* GetRepeatedField(const Field* data) {
    247     return reinterpret_cast<const RepeatedFieldType*>(
    248         (&reinterpret_cast<const MapFieldBase*>(data)->GetRepeatedField()));
    249   }
    250   static RepeatedFieldType* MutableRepeatedField(Field* data) {
    251     return reinterpret_cast<RepeatedFieldType*>(
    252         reinterpret_cast<MapFieldBase*>(data)->MutableRepeatedField());
    253   }
    254   virtual Message* New(const Value* value) const {
    255     return static_cast<const Message*>(value)->New();
    256   }
    257   // Convert an object received by this accessor to an MapEntry message to be
    258   // stored in the underlying MapFieldBase.
    259   virtual void ConvertToEntry(const Value* value, Message* result) const {
    260     result->CopyFrom(*static_cast<const Message*>(value));
    261   }
    262   // Convert a MapEntry message stored in the underlying MapFieldBase to an
    263   // object that will be returned by this accessor.
    264   virtual const Value* ConvertFromEntry(const Message& value,
    265                                         Value* scratch_space) const {
    266     return static_cast<const Value*>(&value);
    267   }
    268 };
    269 
    270 // Default implementations of RepeatedFieldAccessor for primitive types.
    271 template<typename T>
    272 class RepeatedFieldPrimitiveAccessor : public RepeatedFieldWrapper<T> {
    273   typedef void Field;
    274   typedef void Value;
    275   using RepeatedFieldWrapper<T>::MutableRepeatedField;
    276 
    277  public:
    278   RepeatedFieldPrimitiveAccessor() {}
    279   virtual ~RepeatedFieldPrimitiveAccessor() {}
    280   virtual void Swap(
    281       Field* data,
    282       const internal::RepeatedFieldAccessor* other_mutator,
    283       Field* other_data) const {
    284     // Currently RepeatedFieldPrimitiveAccessor is the only implementation of
    285     // RepeatedFieldAccessor for primitive types. As we are using singletons
    286     // for these accessors, here "other_mutator" must be "this".
    287     GOOGLE_CHECK(this == other_mutator);
    288     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
    289   }
    290 
    291  protected:
    292   virtual T ConvertToT(const Value* value) const {
    293     return *static_cast<const T*>(value);
    294   }
    295   virtual const Value* ConvertFromT(const T& value,
    296                                     Value* scratch_space) const {
    297     return static_cast<const Value*>(&value);
    298   }
    299 };
    300 
    301 // Default implementation of RepeatedFieldAccessor for string fields with
    302 // ctype=STRING.
    303 class RepeatedPtrFieldStringAccessor : public RepeatedPtrFieldWrapper<string> {
    304   typedef void Field;
    305   typedef void Value;
    306   using RepeatedFieldAccessor::Add;
    307 
    308  public:
    309   RepeatedPtrFieldStringAccessor() {}
    310   virtual ~RepeatedPtrFieldStringAccessor() {}
    311   virtual void Swap(
    312       Field* data,
    313       const internal::RepeatedFieldAccessor* other_mutator,
    314       Field* other_data) const {
    315     if (this == other_mutator) {
    316       MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
    317     } else {
    318       RepeatedPtrField<string> tmp;
    319       tmp.Swap(MutableRepeatedField(data));
    320       int other_size = other_mutator->Size(other_data);
    321       for (int i = 0; i < other_size; ++i) {
    322         Add<string>(data, other_mutator->Get<string>(other_data, i));
    323       }
    324       int size = Size(data);
    325       other_mutator->Clear(other_data);
    326       for (int i = 0; i < size; ++i) {
    327         other_mutator->Add<string>(other_data, tmp.Get(i));
    328       }
    329     }
    330   }
    331 
    332  protected:
    333   virtual string* New(const Value*) const {
    334     return new string();
    335   }
    336   virtual void ConvertToT(const Value* value, string* result) const {
    337     *result = *static_cast<const string*>(value);
    338   }
    339   virtual const Value* ConvertFromT(const string& value,
    340                                     Value* scratch_space) const {
    341     return static_cast<const Value*>(&value);
    342   }
    343 };
    344 
    345 
    346 class RepeatedPtrFieldMessageAccessor
    347     : public RepeatedPtrFieldWrapper<Message> {
    348   typedef void Field;
    349   typedef void Value;
    350 
    351  public:
    352   RepeatedPtrFieldMessageAccessor() {}
    353   virtual ~RepeatedPtrFieldMessageAccessor() {}
    354   virtual void Swap(
    355       Field* data,
    356       const internal::RepeatedFieldAccessor* other_mutator,
    357       Field* other_data) const {
    358     GOOGLE_CHECK(this == other_mutator);
    359     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
    360   }
    361 
    362  protected:
    363   virtual Message* New(const Value* value) const {
    364     return static_cast<const Message*>(value)->New();
    365   }
    366   virtual void ConvertToT(const Value* value, Message* result) const {
    367     result->CopyFrom(*static_cast<const Message*>(value));
    368   }
    369   virtual const Value* ConvertFromT(const Message& value,
    370                                     Value* scratch_space) const {
    371     return static_cast<const Value*>(&value);
    372   }
    373 };
    374 }  // namespace internal
    375 }  // namespace protobuf
    376 
    377 }  // namespace google
    378 #endif  // GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
    379