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
38namespace google {
39namespace protobuf {
40namespace 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.
44class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor {
45 public:
46 Iterator* BeginIterator(const Field* /*data*/) const override {
47 return PositionToIterator(position: 0);
48 }
49 Iterator* EndIterator(const Field* data) const override {
50 return PositionToIterator(position: this->Size(data));
51 }
52 Iterator* CopyIterator(const Field* /*data*/,
53 const Iterator* iterator) const override {
54 return const_cast<Iterator*>(iterator);
55 }
56 Iterator* AdvanceIterator(const Field* /*data*/,
57 Iterator* iterator) const override {
58 return PositionToIterator(position: IteratorToPosition(iterator) + 1);
59 }
60 bool EqualsIterator(const Field* /*data*/, const Iterator* a,
61 const Iterator* b) const override {
62 return a == b;
63 }
64 void DeleteIterator(const Field* /*data*/,
65 Iterator* /*iterator*/) const override {}
66 const Value* GetIteratorValue(const Field* data, const Iterator* iterator,
67 Value* scratch_space) const override {
68 return Get(data, index: static_cast<int>(IteratorToPosition(iterator)),
69 scratch_space);
70 }
71
72 protected:
73 ~RandomAccessRepeatedFieldAccessor() = default;
74
75 private:
76 static intptr_t IteratorToPosition(const Iterator* iterator) {
77 return reinterpret_cast<intptr_t>(iterator);
78 }
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>.
86template <typename T>
87class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor {
88 public:
89 RepeatedFieldWrapper() {}
90 bool IsEmpty(const Field* data) const override {
91 return GetRepeatedField(data)->empty();
92 }
93 int Size(const Field* data) const override {
94 return GetRepeatedField(data)->size();
95 }
96 const Value* Get(const Field* data, int index,
97 Value* scratch_space) const override {
98 return ConvertFromT(value: GetRepeatedField(data)->Get(index), scratch_space);
99 }
100 void Clear(Field* data) const override {
101 MutableRepeatedField(data)->Clear();
102 }
103 void Set(Field* data, int index, const Value* value) const override {
104 MutableRepeatedField(data)->Set(index, ConvertToT(value));
105 }
106 void Add(Field* data, const Value* value) const override {
107 MutableRepeatedField(data)->Add(ConvertToT(value));
108 }
109 void RemoveLast(Field* data) const override {
110 MutableRepeatedField(data)->RemoveLast();
111 }
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;
119 static const RepeatedFieldType* GetRepeatedField(const Field* data) {
120 return reinterpret_cast<const RepeatedFieldType*>(data);
121 }
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>.
141template <typename T>
142class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor {
143 public:
144 bool IsEmpty(const Field* data) const override {
145 return GetRepeatedField(data)->empty();
146 }
147 int Size(const Field* data) const override {
148 return GetRepeatedField(data)->size();
149 }
150 const Value* Get(const Field* data, int index,
151 Value* scratch_space) const override {
152 return ConvertFromT(value: GetRepeatedField(data)->Get(index), scratch_space);
153 }
154 void Clear(Field* data) const override {
155 MutableRepeatedField(data)->Clear();
156 }
157 void Set(Field* data, int index, const Value* value) const override {
158 ConvertToT(value, result: MutableRepeatedField(data)->Mutable(index));
159 }
160 void Add(Field* data, const Value* value) const override {
161 T* allocated = New(value);
162 ConvertToT(value, result: allocated);
163 MutableRepeatedField(data)->AddAllocated(allocated);
164 }
165 void RemoveLast(Field* data) const override {
166 MutableRepeatedField(data)->RemoveLast();
167 }
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;
175 static const RepeatedFieldType* GetRepeatedField(const Field* data) {
176 return reinterpret_cast<const RepeatedFieldType*>(data);
177 }
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.
203class MapFieldAccessor final : public RandomAccessRepeatedFieldAccessor {
204 public:
205 MapFieldAccessor() {}
206 virtual ~MapFieldAccessor() {}
207 bool IsEmpty(const Field* data) const override {
208 return GetRepeatedField(data)->empty();
209 }
210 int Size(const Field* data) const override {
211 return GetRepeatedField(data)->size();
212 }
213 const Value* Get(const Field* data, int index,
214 Value* scratch_space) const override {
215 return ConvertFromEntry(value: GetRepeatedField(data)->Get(index), scratch_space);
216 }
217 void Clear(Field* data) const override {
218 MutableRepeatedField(data)->Clear();
219 }
220 void Set(Field* data, int index, const Value* value) const override {
221 ConvertToEntry(value, result: MutableRepeatedField(data)->Mutable(index));
222 }
223 void Add(Field* data, const Value* value) const override {
224 Message* allocated = New(value);
225 ConvertToEntry(value, result: allocated);
226 MutableRepeatedField(data)->AddAllocated(value: allocated);
227 }
228 void RemoveLast(Field* data) const override {
229 MutableRepeatedField(data)->RemoveLast();
230 }
231 void SwapElements(Field* data, int index1, int index2) const override {
232 MutableRepeatedField(data)->SwapElements(index1, index2);
233 }
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(other: MutableRepeatedField(data: other_data));
238 }
239
240 protected:
241 typedef RepeatedPtrField<Message> RepeatedFieldType;
242 static const RepeatedFieldType* GetRepeatedField(const Field* data) {
243 return reinterpret_cast<const RepeatedFieldType*>(
244 (&reinterpret_cast<const MapFieldBase*>(data)->GetRepeatedField()));
245 }
246 static RepeatedFieldType* MutableRepeatedField(Field* data) {
247 return reinterpret_cast<RepeatedFieldType*>(
248 reinterpret_cast<MapFieldBase*>(data)->MutableRepeatedField());
249 }
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.
255 virtual void ConvertToEntry(const Value* value, Message* result) const {
256 result->CopyFrom(from: *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.
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.
267template <typename T>
268class RepeatedFieldPrimitiveAccessor final : public RepeatedFieldWrapper<T> {
269 typedef void Field;
270 typedef void Value;
271 using RepeatedFieldWrapper<T>::MutableRepeatedField;
272
273 public:
274 RepeatedFieldPrimitiveAccessor() {}
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:
285 T ConvertToT(const Value* value) const override {
286 return *static_cast<const T*>(value);
287 }
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.
296class RepeatedPtrFieldStringAccessor final
297 : public RepeatedPtrFieldWrapper<std::string> {
298 typedef void Field;
299 typedef void Value;
300 using RepeatedFieldAccessor::Add;
301
302 public:
303 RepeatedPtrFieldStringAccessor() {}
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(other: MutableRepeatedField(data: other_data));
308 } else {
309 RepeatedPtrField<std::string> tmp;
310 tmp.Swap(other: MutableRepeatedField(data));
311 int other_size = other_mutator->Size(data: other_data);
312 for (int i = 0; i < other_size; ++i) {
313 Add<std::string>(data, value: other_mutator->Get<std::string>(data: other_data, index: i));
314 }
315 int size = Size(data);
316 other_mutator->Clear(data: other_data);
317 for (int i = 0; i < size; ++i) {
318 other_mutator->Add<std::string>(data: other_data, value: tmp.Get(index: i));
319 }
320 }
321 }
322
323 protected:
324 std::string* New(const Value*) const override { return new std::string(); }
325 void ConvertToT(const Value* value, std::string* result) const override {
326 *result = *static_cast<const std::string*>(value);
327 }
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
335class RepeatedPtrFieldMessageAccessor final
336 : public RepeatedPtrFieldWrapper<Message> {
337 typedef void Field;
338 typedef void Value;
339
340 public:
341 RepeatedPtrFieldMessageAccessor() {}
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(other: MutableRepeatedField(data: other_data));
346 }
347
348 protected:
349 Message* New(const Value* value) const override {
350 return static_cast<const Message*>(value)->New();
351 }
352 void ConvertToT(const Value* value, Message* result) const override {
353 result->CopyFrom(from: *static_cast<const Message*>(value));
354 }
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