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