blob: 671aafdc4e276e6e30752fda3c6dded6e6f0bbfd [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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// This header defines the RepeatedFieldRef class template used to access
32// repeated fields with protobuf reflection API.
33#ifndef GOOGLE_PROTOBUF_REFLECTION_H__
34#define GOOGLE_PROTOBUF_REFLECTION_H__
35
36#include <memory>
37#ifndef _SHARED_PTR_H
38#include <google/protobuf/stubs/shared_ptr.h>
39#endif
40
41#include <google/protobuf/message.h>
42#include <google/protobuf/generated_enum_util.h>
43
44namespace google {
45namespace protobuf {
46namespace internal {
47template<typename T, typename Enable = void>
48struct RefTypeTraits;
49} // namespace internal
50
51template<typename T>
52RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
53 const Message& message, const FieldDescriptor* field) const {
54 return RepeatedFieldRef<T>(message, field);
55}
56
57template<typename T>
58MutableRepeatedFieldRef<T> Reflection::GetMutableRepeatedFieldRef(
59 Message* message, const FieldDescriptor* field) const {
60 return MutableRepeatedFieldRef<T>(message, field);
61}
62
63// RepeatedFieldRef definition for non-message types.
64template<typename T>
65class RepeatedFieldRef<
66 T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
67 typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
68 typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
69
70 public:
71 bool empty() const {
72 return accessor_->IsEmpty(data_);
73 }
74 int size() const {
75 return accessor_->Size(data_);
76 }
77 T Get(int index) const {
78 return accessor_->template Get<T>(data_, index);
79 }
80
81 typedef IteratorType iterator;
82 typedef IteratorType const_iterator;
83 iterator begin() const {
84 return iterator(data_, accessor_, true);
85 }
86 iterator end() const {
87 return iterator(data_, accessor_, false);
88 }
89
90 private:
91 friend class Reflection;
92 RepeatedFieldRef(
93 const Message& message,
94 const FieldDescriptor* field) {
95 const Reflection* reflection = message.GetReflection();
96 data_ = reflection->RepeatedFieldData(
97 const_cast<Message*>(&message), field,
98 internal::RefTypeTraits<T>::cpp_type, NULL);
99 accessor_ = reflection->RepeatedFieldAccessor(field);
100 }
101
102 const void* data_;
103 const AccessorType* accessor_;
104};
105
106// MutableRepeatedFieldRef definition for non-message types.
107template<typename T>
108class MutableRepeatedFieldRef<
109 T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
110 typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
111
112 public:
113 bool empty() const {
114 return accessor_->IsEmpty(data_);
115 }
116 int size() const {
117 return accessor_->Size(data_);
118 }
119 T Get(int index) const {
120 return accessor_->template Get<T>(data_, index);
121 }
122
123 void Set(int index, const T& value) const {
124 accessor_->template Set<T>(data_, index, value);
125 }
126 void Add(const T& value) const {
127 accessor_->template Add<T>(data_, value);
128 }
129 void RemoveLast() const {
130 accessor_->RemoveLast(data_);
131 }
132 void SwapElements(int index1, int index2) const {
133 accessor_->SwapElements(data_, index1, index2);
134 }
135 void Clear() const {
136 accessor_->Clear(data_);
137 }
138
139 void Swap(const MutableRepeatedFieldRef& other) const {
140 accessor_->Swap(data_, other.accessor_, other.data_);
141 }
142
143 template<typename Container>
144 void MergeFrom(const Container& container) const {
145 typedef typename Container::const_iterator Iterator;
146 for (Iterator it = container.begin(); it != container.end(); ++it) {
147 Add(*it);
148 }
149 }
150 template<typename Container>
151 void CopyFrom(const Container& container) const {
152 Clear();
153 MergeFrom(container);
154 }
155
156 private:
157 friend class Reflection;
158 MutableRepeatedFieldRef(
159 Message* message,
160 const FieldDescriptor* field) {
161 const Reflection* reflection = message->GetReflection();
162 data_ = reflection->RepeatedFieldData(
163 message, field, internal::RefTypeTraits<T>::cpp_type, NULL);
164 accessor_ = reflection->RepeatedFieldAccessor(field);
165 }
166
167 void* data_;
168 const AccessorType* accessor_;
169};
170
171// RepeatedFieldRef definition for message types.
172template<typename T>
173class RepeatedFieldRef<
174 T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
175 typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
176 typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
177
178 public:
179 bool empty() const {
180 return accessor_->IsEmpty(data_);
181 }
182 int size() const {
183 return accessor_->Size(data_);
184 }
185 // This method returns a reference to the underlying message object if it
186 // exists. If a message object doesn't exist (e.g., data stored in serialized
187 // form), scratch_space will be filled with the data and a reference to it
188 // will be returned.
189 //
190 // Example:
191 // RepeatedFieldRef<Message> h = ...
192 // unique_ptr<Message> scratch_space(h.NewMessage());
193 // const Message& item = h.Get(index, scratch_space.get());
194 const T& Get(int index, T* scratch_space) const {
195 return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
196 }
197 // Create a new message of the same type as the messages stored in this
198 // repeated field. Caller takes ownership of the returned object.
199 T* NewMessage() const {
200 return static_cast<T*>(default_instance_->New());
201 }
202
203 typedef IteratorType iterator;
204 typedef IteratorType const_iterator;
205 iterator begin() const {
206 return iterator(data_, accessor_, true, NewMessage());
207 }
208 iterator end() const {
209 return iterator(data_, accessor_, false, NewMessage());
210 }
211
212 private:
213 friend class Reflection;
214 RepeatedFieldRef(
215 const Message& message,
216 const FieldDescriptor* field) {
217 const Reflection* reflection = message.GetReflection();
218 data_ = reflection->RepeatedFieldData(
219 const_cast<Message*>(&message), field,
220 internal::RefTypeTraits<T>::cpp_type,
221 internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
222 accessor_ = reflection->RepeatedFieldAccessor(field);
223 default_instance_ =
224 reflection->GetMessageFactory()->GetPrototype(field->message_type());
225 }
226
227 const void* data_;
228 const AccessorType* accessor_;
229 const Message* default_instance_;
230};
231
232// MutableRepeatedFieldRef definition for message types.
233template<typename T>
234class MutableRepeatedFieldRef<
235 T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
236 typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
237
238 public:
239 bool empty() const {
240 return accessor_->IsEmpty(data_);
241 }
242 int size() const {
243 return accessor_->Size(data_);
244 }
245 // See comments for RepeatedFieldRef<Message>::Get()
246 const T& Get(int index, T* scratch_space) const {
247 return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
248 }
249 // Create a new message of the same type as the messages stored in this
250 // repeated field. Caller takes ownership of the returned object.
251 T* NewMessage() const {
252 return static_cast<T*>(default_instance_->New());
253 }
254
255 void Set(int index, const T& value) const {
256 accessor_->Set(data_, index, &value);
257 }
258 void Add(const T& value) const {
259 accessor_->Add(data_, &value);
260 }
261 void RemoveLast() const {
262 accessor_->RemoveLast(data_);
263 }
264 void SwapElements(int index1, int index2) const {
265 accessor_->SwapElements(data_, index1, index2);
266 }
267 void Clear() const {
268 accessor_->Clear(data_);
269 }
270
271 void Swap(const MutableRepeatedFieldRef& other) const {
272 accessor_->Swap(data_, other.accessor_, other.data_);
273 }
274
275 template<typename Container>
276 void MergeFrom(const Container& container) const {
277 typedef typename Container::const_iterator Iterator;
278 for (Iterator it = container.begin(); it != container.end(); ++it) {
279 Add(*it);
280 }
281 }
282 template<typename Container>
283 void CopyFrom(const Container& container) const {
284 Clear();
285 MergeFrom(container);
286 }
287
288 private:
289 friend class Reflection;
290 MutableRepeatedFieldRef(
291 Message* message,
292 const FieldDescriptor* field) {
293 const Reflection* reflection = message->GetReflection();
294 data_ = reflection->RepeatedFieldData(
295 message, field, internal::RefTypeTraits<T>::cpp_type,
296 internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
297 accessor_ = reflection->RepeatedFieldAccessor(field);
298 default_instance_ =
299 reflection->GetMessageFactory()->GetPrototype(field->message_type());
300 }
301
302 void* data_;
303 const AccessorType* accessor_;
304 const Message* default_instance_;
305};
306
307namespace internal {
308// Interfaces used to implement reflection RepeatedFieldRef API.
309// Reflection::GetRepeatedAccessor() should return a pointer to an singleton
310// object that implements the below interface.
311//
312// This interface passes/returns values using void pointers. The actual type
313// of the value depends on the field's cpp_type. Following is a mapping from
314// cpp_type to the type that should be used in this interface:
315//
316// field->cpp_type() T Actual type of void*
317// CPPTYPE_INT32 int32 int32
318// CPPTYPE_UINT32 uint32 uint32
319// CPPTYPE_INT64 int64 int64
320// CPPTYPE_UINT64 uint64 uint64
321// CPPTYPE_DOUBLE double double
322// CPPTYPE_FLOAT float float
323// CPPTYPE_BOOL bool bool
324// CPPTYPE_ENUM generated enum type int32
325// CPPTYPE_STRING string string
326// CPPTYPE_MESSAGE generated message type google::protobuf::Message
327// or google::protobuf::Message
328//
329// Note that for enums we use int32 in the interface.
330//
331// You can map from T to the actual type using RefTypeTraits:
332// typedef RefTypeTraits<T>::AccessorValueType ActualType;
333class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
334 public:
335 // Typedefs for clarity.
336 typedef void Field;
337 typedef void Value;
338 typedef void Iterator;
339
340 virtual ~RepeatedFieldAccessor();
341 virtual bool IsEmpty(const Field* data) const = 0;
342 virtual int Size(const Field* data) const = 0;
343 // Depends on the underlying representation of the repeated field, this
344 // method can return a pointer to the underlying object if such an object
345 // exists, or fill the data into scratch_space and return scratch_space.
346 // Callers of this method must ensure scratch_space is a valid pointer
347 // to a mutable object of the correct type.
348 virtual const Value* Get(
349 const Field* data, int index, Value* scratch_space) const = 0;
350
351 virtual void Clear(Field* data) const = 0;
352 virtual void Set(Field* data, int index, const Value* value) const = 0;
353 virtual void Add(Field* data, const Value* value) const = 0;
354 virtual void RemoveLast(Field* data) const = 0;
355 virtual void SwapElements(Field* data, int index1, int index2) const = 0;
356 virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
357 Field* other_data) const = 0;
358
359 // Create an iterator that points at the begining of the repeated field.
360 virtual Iterator* BeginIterator(const Field* data) const = 0;
361 // Create an iterator that points at the end of the repeated field.
362 virtual Iterator* EndIterator(const Field* data) const = 0;
363 // Make a copy of an iterator and return the new copy.
364 virtual Iterator* CopyIterator(const Field* data,
365 const Iterator* iterator) const = 0;
366 // Move an iterator to point to the next element.
367 virtual Iterator* AdvanceIterator(const Field* data,
368 Iterator* iterator) const = 0;
369 // Compare whether two iterators point to the same element.
370 virtual bool EqualsIterator(const Field* data, const Iterator* a,
371 const Iterator* b) const = 0;
372 // Delete an iterator created by BeginIterator(), EndIterator() and
373 // CopyIterator().
374 virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
375 // Like Get() but for iterators.
376 virtual const Value* GetIteratorValue(const Field* data,
377 const Iterator* iterator,
378 Value* scratch_space) const = 0;
379
380 // Templated methods that make using this interface easier for non-message
381 // types.
382 template<typename T>
383 T Get(const Field* data, int index) const {
384 typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
385 ActualType scratch_space;
386 return static_cast<T>(
387 *reinterpret_cast<const ActualType*>(
388 Get(data, index, static_cast<Value*>(&scratch_space))));
389 }
390
391 template<typename T, typename ValueType>
392 void Set(Field* data, int index, const ValueType& value) const {
393 typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
394 // In this RepeatedFieldAccessor interface we pass/return data using
395 // raw pointers. Type of the data these raw pointers point to should
396 // be ActualType. Here we have a ValueType object and want a ActualType
397 // pointer. We can't cast a ValueType pointer to an ActualType pointer
398 // directly because their type might be different (for enums ValueType
399 // may be a generated enum type while ActualType is int32). To be safe
400 // we make a copy to get a temporary ActualType object and use it.
401 ActualType tmp = static_cast<ActualType>(value);
402 Set(data, index, static_cast<const Value*>(&tmp));
403 }
404
405 template<typename T, typename ValueType>
406 void Add(Field* data, const ValueType& value) const {
407 typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
408 // In this RepeatedFieldAccessor interface we pass/return data using
409 // raw pointers. Type of the data these raw pointers point to should
410 // be ActualType. Here we have a ValueType object and want a ActualType
411 // pointer. We can't cast a ValueType pointer to an ActualType pointer
412 // directly because their type might be different (for enums ValueType
413 // may be a generated enum type while ActualType is int32). To be safe
414 // we make a copy to get a temporary ActualType object and use it.
415 ActualType tmp = static_cast<ActualType>(value);
416 Add(data, static_cast<const Value*>(&tmp));
417 }
418};
419
420// Implement (Mutable)RepeatedFieldRef::iterator
421template<typename T>
422class RepeatedFieldRefIterator
423 : public std::iterator<std::forward_iterator_tag, T> {
424 typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
425 typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
426 typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
427
428 public:
429 // Constructor for non-message fields.
430 RepeatedFieldRefIterator(const void* data,
431 const RepeatedFieldAccessor* accessor,
432 bool begin)
433 : data_(data), accessor_(accessor),
434 iterator_(begin ? accessor->BeginIterator(data) :
435 accessor->EndIterator(data)),
436 scratch_space_(new AccessorValueType) {
437 }
438 // Constructor for message fields.
439 RepeatedFieldRefIterator(const void* data,
440 const RepeatedFieldAccessor* accessor,
441 bool begin,
442 AccessorValueType* scratch_space)
443 : data_(data), accessor_(accessor),
444 iterator_(begin ? accessor->BeginIterator(data) :
445 accessor->EndIterator(data)),
446 scratch_space_(scratch_space) {
447 }
448 ~RepeatedFieldRefIterator() {
449 accessor_->DeleteIterator(data_, iterator_);
450 }
451 RepeatedFieldRefIterator operator++(int) {
452 RepeatedFieldRefIterator tmp(*this);
453 iterator_ = accessor_->AdvanceIterator(data_, iterator_);
454 return tmp;
455 }
456 RepeatedFieldRefIterator& operator++() {
457 iterator_ = accessor_->AdvanceIterator(data_, iterator_);
458 return *this;
459 }
460 IteratorValueType operator*() const {
461 return static_cast<IteratorValueType>(
462 *static_cast<const AccessorValueType*>(
463 accessor_->GetIteratorValue(
464 data_, iterator_, scratch_space_.get())));
465 }
466 IteratorPointerType operator->() const {
467 return static_cast<IteratorPointerType>(
468 accessor_->GetIteratorValue(
469 data_, iterator_, scratch_space_.get()));
470 }
471 bool operator!=(const RepeatedFieldRefIterator& other) const {
472 assert(data_ == other.data_);
473 assert(accessor_ == other.accessor_);
474 return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
475 }
476 bool operator==(const RepeatedFieldRefIterator& other) const {
477 return !this->operator!=(other);
478 }
479
480 RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
481 : data_(other.data_), accessor_(other.accessor_),
482 iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
483 }
484 RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
485 if (this != &other) {
486 accessor_->DeleteIterator(data_, iterator_);
487 data_ = other.data_;
488 accessor_ = other.accessor_;
489 iterator_ = accessor_->CopyIterator(data_, other.iterator_);
490 }
491 return *this;
492 }
493
494 protected:
495 const void* data_;
496 const RepeatedFieldAccessor* accessor_;
497 void* iterator_;
498 google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
499};
500
501// TypeTraits that maps the type parameter T of RepeatedFieldRef or
502// MutableRepeatedFieldRef to corresponding iterator type,
503// RepeatedFieldAccessor type, etc.
504template<typename T>
505struct PrimitiveTraits {
506 static const bool is_primitive = false;
507};
508#define DEFINE_PRIMITIVE(TYPE, type) \
509 template<> struct PrimitiveTraits<type> { \
510 static const bool is_primitive = true; \
511 static const FieldDescriptor::CppType cpp_type = \
512 FieldDescriptor::CPPTYPE_ ## TYPE; \
513 };
514DEFINE_PRIMITIVE(INT32, int32)
515DEFINE_PRIMITIVE(UINT32, uint32)
516DEFINE_PRIMITIVE(INT64, int64)
517DEFINE_PRIMITIVE(UINT64, uint64)
518DEFINE_PRIMITIVE(FLOAT, float)
519DEFINE_PRIMITIVE(DOUBLE, double)
520DEFINE_PRIMITIVE(BOOL, bool)
521#undef DEFINE_PRIMITIVE
522
523template<typename T>
524struct RefTypeTraits<
525 T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
526 typedef RepeatedFieldRefIterator<T> iterator;
527 typedef RepeatedFieldAccessor AccessorType;
528 typedef T AccessorValueType;
529 typedef T IteratorValueType;
530 typedef T* IteratorPointerType;
531 static const FieldDescriptor::CppType cpp_type =
532 PrimitiveTraits<T>::cpp_type;
533 static const Descriptor* GetMessageFieldDescriptor() {
534 return NULL;
535 }
536};
537
538template<typename T>
539struct RefTypeTraits<
540 T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
541 typedef RepeatedFieldRefIterator<T> iterator;
542 typedef RepeatedFieldAccessor AccessorType;
543 // We use int32 for repeated enums in RepeatedFieldAccessor.
544 typedef int32 AccessorValueType;
545 typedef T IteratorValueType;
546 typedef int32* IteratorPointerType;
547 static const FieldDescriptor::CppType cpp_type =
548 FieldDescriptor::CPPTYPE_ENUM;
549 static const Descriptor* GetMessageFieldDescriptor() {
550 return NULL;
551 }
552};
553
554template<typename T>
555struct RefTypeTraits<
556 T, typename internal::enable_if< ::google::protobuf::internal::is_same<string, T>::value>::type> {
557 typedef RepeatedFieldRefIterator<T> iterator;
558 typedef RepeatedFieldAccessor AccessorType;
559 typedef string AccessorValueType;
560 typedef string IteratorValueType;
561 typedef string* IteratorPointerType;
562 static const FieldDescriptor::CppType cpp_type =
563 FieldDescriptor::CPPTYPE_STRING;
564 static const Descriptor* GetMessageFieldDescriptor() {
565 return NULL;
566 }
567};
568
569template<typename T>
570struct MessageDescriptorGetter {
571 static const Descriptor* get() {
572 return T::default_instance().GetDescriptor();
573 }
574};
575template<>
576struct MessageDescriptorGetter<Message> {
577 static const Descriptor* get() {
578 return NULL;
579 }
580};
581
582template<typename T>
583struct RefTypeTraits<
584 T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
585 typedef RepeatedFieldRefIterator<T> iterator;
586 typedef RepeatedFieldAccessor AccessorType;
587 typedef Message AccessorValueType;
588 typedef const T& IteratorValueType;
589 typedef const T* IteratorPointerType;
590 static const FieldDescriptor::CppType cpp_type =
591 FieldDescriptor::CPPTYPE_MESSAGE;
592 static const Descriptor* GetMessageFieldDescriptor() {
593 return MessageDescriptorGetter<T>::get();
594 }
595};
596} // namespace internal
597} // namespace protobuf
598} // namespace google
599
600#endif // GOOGLE_PROTOBUF_REFLECTION_H__