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 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__ 601