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