• 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 #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 
44 namespace google {
45 namespace protobuf {
46 namespace internal {
47 template<typename T, typename Enable = void>
48 struct RefTypeTraits;
49 }  // namespace internal
50 
51 template<typename T>
GetRepeatedFieldRef(const Message & message,const FieldDescriptor * field)52 RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
53     const Message& message, const FieldDescriptor* field) const {
54   return RepeatedFieldRef<T>(message, field);
55 }
56 
57 template<typename T>
GetMutableRepeatedFieldRef(Message * message,const FieldDescriptor * field)58 MutableRepeatedFieldRef<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.
64 template<typename T>
65 class 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:
empty()71   bool empty() const {
72     return accessor_->IsEmpty(data_);
73   }
size()74   int size() const {
75     return accessor_->Size(data_);
76   }
Get(int index)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;
begin()83   iterator begin() const {
84     return iterator(data_, accessor_, true);
85   }
end()86   iterator end() const {
87     return iterator(data_, accessor_, false);
88   }
89 
90  private:
91   friend class Reflection;
RepeatedFieldRef(const Message & message,const FieldDescriptor * field)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.
107 template<typename T>
108 class 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:
empty()113   bool empty() const {
114     return accessor_->IsEmpty(data_);
115   }
size()116   int size() const {
117     return accessor_->Size(data_);
118   }
Get(int index)119   T Get(int index) const {
120     return accessor_->template Get<T>(data_, index);
121   }
122 
Set(int index,const T & value)123   void Set(int index, const T& value) const {
124     accessor_->template Set<T>(data_, index, value);
125   }
Add(const T & value)126   void Add(const T& value) const {
127     accessor_->template Add<T>(data_, value);
128   }
RemoveLast()129   void RemoveLast() const {
130     accessor_->RemoveLast(data_);
131   }
SwapElements(int index1,int index2)132   void SwapElements(int index1, int index2) const {
133     accessor_->SwapElements(data_, index1, index2);
134   }
Clear()135   void Clear() const {
136     accessor_->Clear(data_);
137   }
138 
Swap(const MutableRepeatedFieldRef & other)139   void Swap(const MutableRepeatedFieldRef& other) const {
140     accessor_->Swap(data_, other.accessor_, other.data_);
141   }
142 
143   template<typename Container>
MergeFrom(const Container & 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>
CopyFrom(const Container & container)151   void CopyFrom(const Container& container) const {
152     Clear();
153     MergeFrom(container);
154   }
155 
156  private:
157   friend class Reflection;
MutableRepeatedFieldRef(Message * message,const FieldDescriptor * field)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.
172 template<typename T>
173 class 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:
empty()179   bool empty() const {
180     return accessor_->IsEmpty(data_);
181   }
size()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());
Get(int index,T * scratch_space)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.
NewMessage()199   T* NewMessage() const {
200     return static_cast<T*>(default_instance_->New());
201   }
202 
203   typedef IteratorType iterator;
204   typedef IteratorType const_iterator;
begin()205   iterator begin() const {
206     return iterator(data_, accessor_, true, NewMessage());
207   }
end()208   iterator end() const {
209     return iterator(data_, accessor_, false, NewMessage());
210   }
211 
212  private:
213   friend class Reflection;
RepeatedFieldRef(const Message & message,const FieldDescriptor * field)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.
233 template<typename T>
234 class 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:
empty()239   bool empty() const {
240     return accessor_->IsEmpty(data_);
241   }
size()242   int size() const {
243     return accessor_->Size(data_);
244   }
245   // See comments for RepeatedFieldRef<Message>::Get()
Get(int index,T * scratch_space)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.
NewMessage()251   T* NewMessage() const {
252     return static_cast<T*>(default_instance_->New());
253   }
254 
Set(int index,const T & value)255   void Set(int index, const T& value) const {
256     accessor_->Set(data_, index, &value);
257   }
Add(const T & value)258   void Add(const T& value) const {
259     accessor_->Add(data_, &value);
260   }
RemoveLast()261   void RemoveLast() const {
262     accessor_->RemoveLast(data_);
263   }
SwapElements(int index1,int index2)264   void SwapElements(int index1, int index2) const {
265     accessor_->SwapElements(data_, index1, index2);
266   }
Clear()267   void Clear() const {
268     accessor_->Clear(data_);
269   }
270 
Swap(const MutableRepeatedFieldRef & other)271   void Swap(const MutableRepeatedFieldRef& other) const {
272     accessor_->Swap(data_, other.accessor_, other.data_);
273   }
274 
275   template<typename Container>
MergeFrom(const Container & 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>
CopyFrom(const Container & container)283   void CopyFrom(const Container& container) const {
284     Clear();
285     MergeFrom(container);
286   }
287 
288  private:
289   friend class Reflection;
MutableRepeatedFieldRef(Message * message,const FieldDescriptor * field)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 
307 namespace 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;
333 class 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>
Get(const Field * data,int index)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>
Set(Field * data,int index,const ValueType & value)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>
Add(Field * data,const ValueType & value)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
421 template<typename T>
422 class 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.
RepeatedFieldRefIterator(const void * data,const RepeatedFieldAccessor * accessor,bool begin)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.
RepeatedFieldRefIterator(const void * data,const RepeatedFieldAccessor * accessor,bool begin,AccessorValueType * scratch_space)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   }
~RepeatedFieldRefIterator()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 
RepeatedFieldRefIterator(const RepeatedFieldRefIterator & other)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.
504 template<typename T>
505 struct 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     };
514 DEFINE_PRIMITIVE(INT32, int32)
515 DEFINE_PRIMITIVE(UINT32, uint32)
516 DEFINE_PRIMITIVE(INT64, int64)
517 DEFINE_PRIMITIVE(UINT64, uint64)
518 DEFINE_PRIMITIVE(FLOAT, float)
519 DEFINE_PRIMITIVE(DOUBLE, double)
520 DEFINE_PRIMITIVE(BOOL, bool)
521 #undef DEFINE_PRIMITIVE
522 
523 template<typename T>
524 struct 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 
538 template<typename T>
539 struct 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 
554 template<typename T>
555 struct 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 
569 template<typename T>
570 struct MessageDescriptorGetter {
571   static const Descriptor* get() {
572     return T::default_instance().GetDescriptor();
573   }
574 };
575 template<>
576 struct MessageDescriptorGetter<Message> {
577   static const Descriptor* get() {
578     return NULL;
579   }
580 };
581 
582 template<typename T>
583 struct 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__
601