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