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