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