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 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 // 35 // This header is logically internal, but is made public because it is used 36 // from protocol-compiler-generated code, which may reside in other components. 37 38 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 39 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 40 41 #include <string> 42 #include <vector> 43 #include <google/protobuf/stubs/casts.h> 44 #include <google/protobuf/stubs/common.h> 45 // TODO(jasonh): Remove this once the compiler change to directly include this 46 // is released to components. 47 #include <google/protobuf/generated_enum_reflection.h> 48 #include <google/protobuf/message.h> 49 #include <google/protobuf/metadata.h> 50 #include <google/protobuf/unknown_field_set.h> 51 52 53 namespace google { 54 namespace upb { 55 namespace google_opensource { 56 class GMR_Handlers; 57 } // namespace google_opensource 58 } // namespace upb 59 60 namespace protobuf { 61 class DescriptorPool; 62 class MapKey; 63 class MapValueRef; 64 } 65 66 namespace protobuf { 67 namespace internal { 68 class DefaultEmptyOneof; 69 70 // Defined in this file. 71 class GeneratedMessageReflection; 72 73 // Defined in other files. 74 class ExtensionSet; // extension_set.h 75 76 // THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use 77 // by generated code. This class is just a big hack that reduces code 78 // size. 79 // 80 // A GeneratedMessageReflection is an implementation of Reflection 81 // which expects all fields to be backed by simple variables located in 82 // memory. The locations are given using a base pointer and a set of 83 // offsets. 84 // 85 // It is required that the user represents fields of each type in a standard 86 // way, so that GeneratedMessageReflection can cast the void* pointer to 87 // the appropriate type. For primitive fields and string fields, each field 88 // should be represented using the obvious C++ primitive type. Enums and 89 // Messages are different: 90 // - Singular Message fields are stored as a pointer to a Message. These 91 // should start out NULL, except for in the default instance where they 92 // should start out pointing to other default instances. 93 // - Enum fields are stored as an int. This int must always contain 94 // a valid value, such that EnumDescriptor::FindValueByNumber() would 95 // not return NULL. 96 // - Repeated fields are stored as RepeatedFields or RepeatedPtrFields 97 // of whatever type the individual field would be. Strings and 98 // Messages use RepeatedPtrFields while everything else uses 99 // RepeatedFields. 100 class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { 101 public: 102 // Constructs a GeneratedMessageReflection. 103 // Parameters: 104 // descriptor: The descriptor for the message type being implemented. 105 // default_instance: The default instance of the message. This is only 106 // used to obtain pointers to default instances of embedded 107 // messages, which GetMessage() will return if the particular 108 // sub-message has not been initialized yet. (Thus, all 109 // embedded message fields *must* have non-NULL pointers 110 // in the default instance.) 111 // offsets: An array of ints giving the byte offsets, relative to 112 // the start of the message object, of each field. These can 113 // be computed at compile time using the 114 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined 115 // below. 116 // has_bits_offset: Offset in the message of an array of uint32s of size 117 // descriptor->field_count()/32, rounded up. This is a 118 // bitfield where each bit indicates whether or not the 119 // corresponding field of the message has been initialized. 120 // The bit for field index i is obtained by the expression: 121 // has_bits[i / 32] & (1 << (i % 32)) 122 // unknown_fields_offset: Offset in the message of the UnknownFieldSet for 123 // the message. 124 // extensions_offset: Offset in the message of the ExtensionSet for the 125 // message, or -1 if the message type has no extension 126 // ranges. 127 // pool: DescriptorPool to search for extension definitions. Only 128 // used by FindKnownExtensionByName() and 129 // FindKnownExtensionByNumber(). 130 // factory: MessageFactory to use to construct extension messages. 131 // object_size: The size of a message object of this type, as measured 132 // by sizeof(). 133 GeneratedMessageReflection(const Descriptor* descriptor, 134 const Message* default_instance, 135 const int offsets[], 136 int has_bits_offset, 137 int unknown_fields_offset, 138 int extensions_offset, 139 const DescriptorPool* pool, 140 MessageFactory* factory, 141 int object_size, 142 int arena_offset, 143 int is_default_instance_offset = -1); 144 145 // Similar with the construction above. Call this construction if the 146 // message has oneof definition. 147 // Parameters: 148 // offsets: An array of ints giving the byte offsets. 149 // For each oneof field, the offset is relative to the 150 // default_oneof_instance. These can be computed at compile 151 // time using the 152 // PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro. 153 // For each none oneof field, the offset is related to 154 // the start of the message object. These can be computed 155 // at compile time using the 156 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro. 157 // Besides offsets for all fields, this array also contains 158 // offsets for oneof unions. The offset of the i-th oneof 159 // union is offsets[descriptor->field_count() + i]. 160 // default_oneof_instance: The default instance of the oneofs. It is a 161 // struct holding the default value of all oneof fields 162 // for this message. It is only used to obtain pointers 163 // to default instances of oneof fields, which Get 164 // methods will return if the field is not set. 165 // oneof_case_offset: Offset in the message of an array of uint32s of 166 // size descriptor->oneof_decl_count(). Each uint32 167 // indicates what field is set for each oneof. 168 // other parameters are the same with the construction above. 169 GeneratedMessageReflection(const Descriptor* descriptor, 170 const Message* default_instance, 171 const int offsets[], 172 int has_bits_offset, 173 int unknown_fields_offset, 174 int extensions_offset, 175 const void* default_oneof_instance, 176 int oneof_case_offset, 177 const DescriptorPool* pool, 178 MessageFactory* factory, 179 int object_size, 180 int arena_offset, 181 int is_default_instance_offset = -1); 182 ~GeneratedMessageReflection(); 183 184 // Shorter-to-call helpers for the above two constructions that work if the 185 // pool and factory are the usual, namely, DescriptorPool::generated_pool() 186 // and MessageFactory::generated_factory(). 187 188 static GeneratedMessageReflection* NewGeneratedMessageReflection( 189 const Descriptor* descriptor, 190 const Message* default_instance, 191 const int offsets[], 192 int has_bits_offset, 193 int unknown_fields_offset, 194 int extensions_offset, 195 const void* default_oneof_instance, 196 int oneof_case_offset, 197 int object_size, 198 int arena_offset, 199 int is_default_instance_offset = -1); 200 201 static GeneratedMessageReflection* NewGeneratedMessageReflection( 202 const Descriptor* descriptor, 203 const Message* default_instance, 204 const int offsets[], 205 int has_bits_offset, 206 int unknown_fields_offset, 207 int extensions_offset, 208 int object_size, 209 int arena_offset, 210 int is_default_instance_offset = -1); 211 212 // implements Reflection ------------------------------------------- 213 214 const UnknownFieldSet& GetUnknownFields(const Message& message) const; 215 UnknownFieldSet* MutableUnknownFields(Message* message) const; 216 217 int SpaceUsed(const Message& message) const; 218 219 bool HasField(const Message& message, const FieldDescriptor* field) const; 220 int FieldSize(const Message& message, const FieldDescriptor* field) const; 221 void ClearField(Message* message, const FieldDescriptor* field) const; 222 bool HasOneof(const Message& message, 223 const OneofDescriptor* oneof_descriptor) const; 224 void ClearOneof(Message* message, const OneofDescriptor* field) const; 225 void RemoveLast(Message* message, const FieldDescriptor* field) const; 226 Message* ReleaseLast(Message* message, const FieldDescriptor* field) const; 227 void Swap(Message* message1, Message* message2) const; 228 void SwapFields(Message* message1, Message* message2, 229 const vector<const FieldDescriptor*>& fields) const; 230 void SwapElements(Message* message, const FieldDescriptor* field, 231 int index1, int index2) const; 232 void ListFields(const Message& message, 233 vector<const FieldDescriptor*>* output) const; 234 235 int32 GetInt32 (const Message& message, 236 const FieldDescriptor* field) const; 237 int64 GetInt64 (const Message& message, 238 const FieldDescriptor* field) const; 239 uint32 GetUInt32(const Message& message, 240 const FieldDescriptor* field) const; 241 uint64 GetUInt64(const Message& message, 242 const FieldDescriptor* field) const; 243 float GetFloat (const Message& message, 244 const FieldDescriptor* field) const; 245 double GetDouble(const Message& message, 246 const FieldDescriptor* field) const; 247 bool GetBool (const Message& message, 248 const FieldDescriptor* field) const; 249 string GetString(const Message& message, 250 const FieldDescriptor* field) const; 251 const string& GetStringReference(const Message& message, 252 const FieldDescriptor* field, 253 string* scratch) const; 254 const EnumValueDescriptor* GetEnum(const Message& message, 255 const FieldDescriptor* field) const; 256 int GetEnumValue(const Message& message, 257 const FieldDescriptor* field) const; 258 const Message& GetMessage(const Message& message, 259 const FieldDescriptor* field, 260 MessageFactory* factory = NULL) const; 261 262 const FieldDescriptor* GetOneofFieldDescriptor( 263 const Message& message, 264 const OneofDescriptor* oneof_descriptor) const; 265 266 private: 267 bool ContainsMapKey(const Message& message, 268 const FieldDescriptor* field, 269 const MapKey& key) const; 270 bool InsertOrLookupMapValue(Message* message, 271 const FieldDescriptor* field, 272 const MapKey& key, 273 MapValueRef* val) const; 274 bool DeleteMapValue(Message* message, 275 const FieldDescriptor* field, 276 const MapKey& key) const; 277 MapIterator MapBegin( 278 Message* message, 279 const FieldDescriptor* field) const; 280 MapIterator MapEnd( 281 Message* message, 282 const FieldDescriptor* field) const; 283 int MapSize(const Message& message, const FieldDescriptor* field) const; 284 285 public: 286 void SetInt32 (Message* message, 287 const FieldDescriptor* field, int32 value) const; 288 void SetInt64 (Message* message, 289 const FieldDescriptor* field, int64 value) const; 290 void SetUInt32(Message* message, 291 const FieldDescriptor* field, uint32 value) const; 292 void SetUInt64(Message* message, 293 const FieldDescriptor* field, uint64 value) const; 294 void SetFloat (Message* message, 295 const FieldDescriptor* field, float value) const; 296 void SetDouble(Message* message, 297 const FieldDescriptor* field, double value) const; 298 void SetBool (Message* message, 299 const FieldDescriptor* field, bool value) const; 300 void SetString(Message* message, 301 const FieldDescriptor* field, 302 const string& value) const; 303 void SetEnum (Message* message, const FieldDescriptor* field, 304 const EnumValueDescriptor* value) const; 305 void SetEnumValue(Message* message, const FieldDescriptor* field, 306 int value) const; 307 Message* MutableMessage(Message* message, const FieldDescriptor* field, 308 MessageFactory* factory = NULL) const; 309 void SetAllocatedMessage(Message* message, 310 Message* sub_message, 311 const FieldDescriptor* field) const; 312 Message* ReleaseMessage(Message* message, const FieldDescriptor* field, 313 MessageFactory* factory = NULL) const; 314 315 int32 GetRepeatedInt32 (const Message& message, 316 const FieldDescriptor* field, int index) const; 317 int64 GetRepeatedInt64 (const Message& message, 318 const FieldDescriptor* field, int index) const; 319 uint32 GetRepeatedUInt32(const Message& message, 320 const FieldDescriptor* field, int index) const; 321 uint64 GetRepeatedUInt64(const Message& message, 322 const FieldDescriptor* field, int index) const; 323 float GetRepeatedFloat (const Message& message, 324 const FieldDescriptor* field, int index) const; 325 double GetRepeatedDouble(const Message& message, 326 const FieldDescriptor* field, int index) const; 327 bool GetRepeatedBool (const Message& message, 328 const FieldDescriptor* field, int index) const; 329 string GetRepeatedString(const Message& message, 330 const FieldDescriptor* field, int index) const; 331 const string& GetRepeatedStringReference(const Message& message, 332 const FieldDescriptor* field, 333 int index, string* scratch) const; 334 const EnumValueDescriptor* GetRepeatedEnum(const Message& message, 335 const FieldDescriptor* field, 336 int index) const; 337 int GetRepeatedEnumValue(const Message& message, 338 const FieldDescriptor* field, 339 int index) const; 340 const Message& GetRepeatedMessage(const Message& message, 341 const FieldDescriptor* field, 342 int index) const; 343 344 // Set the value of a field. 345 void SetRepeatedInt32 (Message* message, 346 const FieldDescriptor* field, int index, int32 value) const; 347 void SetRepeatedInt64 (Message* message, 348 const FieldDescriptor* field, int index, int64 value) const; 349 void SetRepeatedUInt32(Message* message, 350 const FieldDescriptor* field, int index, uint32 value) const; 351 void SetRepeatedUInt64(Message* message, 352 const FieldDescriptor* field, int index, uint64 value) const; 353 void SetRepeatedFloat (Message* message, 354 const FieldDescriptor* field, int index, float value) const; 355 void SetRepeatedDouble(Message* message, 356 const FieldDescriptor* field, int index, double value) const; 357 void SetRepeatedBool (Message* message, 358 const FieldDescriptor* field, int index, bool value) const; 359 void SetRepeatedString(Message* message, 360 const FieldDescriptor* field, int index, 361 const string& value) const; 362 void SetRepeatedEnum(Message* message, const FieldDescriptor* field, 363 int index, const EnumValueDescriptor* value) const; 364 void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field, 365 int index, int value) const; 366 // Get a mutable pointer to a field with a message type. 367 Message* MutableRepeatedMessage(Message* message, 368 const FieldDescriptor* field, 369 int index) const; 370 371 void AddInt32 (Message* message, 372 const FieldDescriptor* field, int32 value) const; 373 void AddInt64 (Message* message, 374 const FieldDescriptor* field, int64 value) const; 375 void AddUInt32(Message* message, 376 const FieldDescriptor* field, uint32 value) const; 377 void AddUInt64(Message* message, 378 const FieldDescriptor* field, uint64 value) const; 379 void AddFloat (Message* message, 380 const FieldDescriptor* field, float value) const; 381 void AddDouble(Message* message, 382 const FieldDescriptor* field, double value) const; 383 void AddBool (Message* message, 384 const FieldDescriptor* field, bool value) const; 385 void AddString(Message* message, 386 const FieldDescriptor* field, const string& value) const; 387 void AddEnum(Message* message, 388 const FieldDescriptor* field, 389 const EnumValueDescriptor* value) const; 390 void AddEnumValue(Message* message, 391 const FieldDescriptor* field, 392 int value) const; 393 Message* AddMessage(Message* message, const FieldDescriptor* field, 394 MessageFactory* factory = NULL) const; 395 void AddAllocatedMessage( 396 Message* message, const FieldDescriptor* field, 397 Message* new_entry) const; 398 399 const FieldDescriptor* FindKnownExtensionByName(const string& name) const; 400 const FieldDescriptor* FindKnownExtensionByNumber(int number) const; 401 402 bool SupportsUnknownEnumValues() const; 403 404 // This value for arena_offset_ indicates that there is no arena pointer in 405 // this message (e.g., old generated code). 406 static const int kNoArenaPointer = -1; 407 408 // This value for unknown_field_offset_ indicates that there is no 409 // UnknownFieldSet in this message, and that instead, we are using the 410 // Zero-Overhead Arena Pointer trick. When this is the case, arena_offset_ 411 // actually indexes to an InternalMetadataWithArena instance, which can return 412 // either an arena pointer or an UnknownFieldSet or both. It is never the case 413 // that unknown_field_offset_ == kUnknownFieldSetInMetadata && arena_offset_ 414 // == kNoArenaPointer. 415 static const int kUnknownFieldSetInMetadata = -1; 416 417 protected: 418 void* MutableRawRepeatedField( 419 Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, 420 int ctype, const Descriptor* desc) const; 421 422 const void* GetRawRepeatedField( 423 const Message& message, const FieldDescriptor* field, 424 FieldDescriptor::CppType, int ctype, 425 const Descriptor* desc) const; 426 427 virtual MessageFactory* GetMessageFactory() const; 428 429 virtual void* RepeatedFieldData( 430 Message* message, const FieldDescriptor* field, 431 FieldDescriptor::CppType cpp_type, 432 const Descriptor* message_type) const; 433 434 private: 435 friend class GeneratedMessage; 436 437 // To parse directly into a proto2 generated class, the class GMR_Handlers 438 // needs access to member offsets and hasbits. 439 friend class upb::google_opensource::GMR_Handlers; 440 441 const Descriptor* descriptor_; 442 const Message* default_instance_; 443 const void* default_oneof_instance_; 444 const int* offsets_; 445 446 int has_bits_offset_; 447 int oneof_case_offset_; 448 int unknown_fields_offset_; 449 int extensions_offset_; 450 int arena_offset_; 451 int is_default_instance_offset_; 452 int object_size_; 453 454 static const int kHasNoDefaultInstanceField = -1; 455 456 const DescriptorPool* descriptor_pool_; 457 MessageFactory* message_factory_; 458 459 template <typename Type> 460 inline const Type& GetRaw(const Message& message, 461 const FieldDescriptor* field) const; 462 template <typename Type> 463 inline Type* MutableRaw(Message* message, 464 const FieldDescriptor* field) const; 465 template <typename Type> 466 inline const Type& DefaultRaw(const FieldDescriptor* field) const; 467 template <typename Type> 468 inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const; 469 470 inline const uint32* GetHasBits(const Message& message) const; 471 inline uint32* MutableHasBits(Message* message) const; 472 inline uint32 GetOneofCase( 473 const Message& message, 474 const OneofDescriptor* oneof_descriptor) const; 475 inline uint32* MutableOneofCase( 476 Message* message, 477 const OneofDescriptor* oneof_descriptor) const; 478 inline const ExtensionSet& GetExtensionSet(const Message& message) const; 479 inline ExtensionSet* MutableExtensionSet(Message* message) const; 480 inline Arena* GetArena(Message* message) const; 481 inline const internal::InternalMetadataWithArena& 482 GetInternalMetadataWithArena(const Message& message) const; 483 inline internal::InternalMetadataWithArena* 484 MutableInternalMetadataWithArena(Message* message) const; 485 486 inline bool GetIsDefaultInstance(const Message& message) const; 487 488 inline bool HasBit(const Message& message, 489 const FieldDescriptor* field) const; 490 inline void SetBit(Message* message, 491 const FieldDescriptor* field) const; 492 inline void ClearBit(Message* message, 493 const FieldDescriptor* field) const; 494 inline void SwapBit(Message* message1, 495 Message* message2, 496 const FieldDescriptor* field) const; 497 498 // This function only swaps the field. Should swap corresponding has_bit 499 // before or after using this function. 500 void SwapField(Message* message1, 501 Message* message2, 502 const FieldDescriptor* field) const; 503 504 void SwapOneofField(Message* message1, 505 Message* message2, 506 const OneofDescriptor* oneof_descriptor) const; 507 508 inline bool HasOneofField(const Message& message, 509 const FieldDescriptor* field) const; 510 inline void SetOneofCase(Message* message, 511 const FieldDescriptor* field) const; 512 inline void ClearOneofField(Message* message, 513 const FieldDescriptor* field) const; 514 515 template <typename Type> 516 inline const Type& GetField(const Message& message, 517 const FieldDescriptor* field) const; 518 template <typename Type> 519 inline void SetField(Message* message, 520 const FieldDescriptor* field, const Type& value) const; 521 template <typename Type> 522 inline Type* MutableField(Message* message, 523 const FieldDescriptor* field) const; 524 template <typename Type> 525 inline const Type& GetRepeatedField(const Message& message, 526 const FieldDescriptor* field, 527 int index) const; 528 template <typename Type> 529 inline const Type& GetRepeatedPtrField(const Message& message, 530 const FieldDescriptor* field, 531 int index) const; 532 template <typename Type> 533 inline void SetRepeatedField(Message* message, 534 const FieldDescriptor* field, int index, 535 Type value) const; 536 template <typename Type> 537 inline Type* MutableRepeatedField(Message* message, 538 const FieldDescriptor* field, 539 int index) const; 540 template <typename Type> 541 inline void AddField(Message* message, 542 const FieldDescriptor* field, const Type& value) const; 543 template <typename Type> 544 inline Type* AddField(Message* message, 545 const FieldDescriptor* field) const; 546 547 int GetExtensionNumberOrDie(const Descriptor* type) const; 548 549 // Internal versions of EnumValue API perform no checking. Called after checks 550 // by public methods. 551 void SetEnumValueInternal(Message* message, 552 const FieldDescriptor* field, 553 int value) const; 554 void SetRepeatedEnumValueInternal(Message* message, 555 const FieldDescriptor* field, 556 int index, 557 int value) const; 558 void AddEnumValueInternal(Message* message, 559 const FieldDescriptor* field, 560 int value) const; 561 562 563 Message* UnsafeArenaReleaseMessage(Message* message, 564 const FieldDescriptor* field, 565 MessageFactory* factory = NULL) const; 566 567 void UnsafeArenaSetAllocatedMessage(Message* message, 568 Message* sub_message, 569 const FieldDescriptor* field) const; 570 571 internal::MapFieldBase* MapData( 572 Message* message, const FieldDescriptor* field) const; 573 574 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); 575 }; 576 577 // Returns the offset of the given field within the given aggregate type. 578 // This is equivalent to the ANSI C offsetof() macro. However, according 579 // to the C++ standard, offsetof() only works on POD types, and GCC 580 // enforces this requirement with a warning. In practice, this rule is 581 // unnecessarily strict; there is probably no compiler or platform on 582 // which the offsets of the direct fields of a class are non-constant. 583 // Fields inherited from superclasses *can* have non-constant offsets, 584 // but that's not what this macro will be used for. 585 #if defined(__clang__) 586 // For Clang we use __builtin_offsetof() and suppress the warning, 587 // to avoid Control Flow Integrity and UBSan vptr sanitizers from 588 // crashing while trying to validate the invalid reinterpet_casts. 589 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ 590 _Pragma("clang diagnostic push") \ 591 _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ 592 __builtin_offsetof(TYPE, FIELD) \ 593 _Pragma("clang diagnostic pop") 594 #else 595 // Note that we calculate relative to the pointer value 16 here since if we 596 // just use zero, GCC complains about dereferencing a NULL pointer. We 597 // choose 16 rather than some other number just in case the compiler would 598 // be confused by an unaligned pointer. 599 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ 600 static_cast<int>( \ 601 reinterpret_cast<const char*>( \ 602 &reinterpret_cast<const TYPE*>(16)->FIELD) - \ 603 reinterpret_cast<const char*>(16)) 604 #endif 605 606 #define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \ 607 static_cast<int>( \ 608 reinterpret_cast<const char*>(&(ONEOF->FIELD)) \ 609 - reinterpret_cast<const char*>(ONEOF)) 610 611 // There are some places in proto2 where dynamic_cast would be useful as an 612 // optimization. For example, take Message::MergeFrom(const Message& other). 613 // For a given generated message FooMessage, we generate these two methods: 614 // void MergeFrom(const FooMessage& other); 615 // void MergeFrom(const Message& other); 616 // The former method can be implemented directly in terms of FooMessage's 617 // inline accessors, but the latter method must work with the reflection 618 // interface. However, if the parameter to the latter method is actually of 619 // type FooMessage, then we'd like to be able to just call the other method 620 // as an optimization. So, we use dynamic_cast to check this. 621 // 622 // That said, dynamic_cast requires RTTI, which many people like to disable 623 // for performance and code size reasons. When RTTI is not available, we 624 // still need to produce correct results. So, in this case we have to fall 625 // back to using reflection, which is what we would have done anyway if the 626 // objects were not of the exact same class. 627 // 628 // dynamic_cast_if_available() implements this logic. If RTTI is 629 // enabled, it does a dynamic_cast. If RTTI is disabled, it just returns 630 // NULL. 631 // 632 // If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. 633 // On MSVC, this should be detected automatically. 634 template<typename To, typename From> 635 inline To dynamic_cast_if_available(From from) { 636 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || defined(__GXX_RTTI) || \ 637 (defined(_MSC_VER)&&!defined(_CPPRTTI)) 638 // Avoid the compiler warning about unused variables. 639 (void)from; 640 return NULL; 641 #else 642 return dynamic_cast<To>(from); 643 #endif 644 } 645 646 // Tries to downcast this message to a generated message type. 647 // Returns NULL if this class is not an instance of T. 648 // 649 // This is like dynamic_cast_if_available, except it works even when 650 // dynamic_cast is not available by using Reflection. However it only works 651 // with Message objects. 652 // 653 // TODO(haberman): can we remove dynamic_cast_if_available in favor of this? 654 template <typename T> 655 T* DynamicCastToGenerated(const Message* from) { 656 // Compile-time assert that T is a generated type that has a 657 // default_instance() accessor, but avoid actually calling it. 658 const T&(*get_default_instance)() = &T::default_instance; 659 (void)get_default_instance; 660 661 // Compile-time assert that T is a subclass of google::protobuf::Message. 662 const Message* unused = static_cast<T*>(NULL); 663 (void)unused; 664 665 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || defined(__GXX_RTTI) || \ 666 (defined(_MSC_VER)&&!defined(_CPPRTTI)) 667 bool ok = &T::default_instance() == 668 from->GetReflection()->GetMessageFactory()->GetPrototype( 669 from->GetDescriptor()); 670 return ok ? down_cast<T*>(from) : NULL; 671 #else 672 return dynamic_cast<T*>(from); 673 #endif 674 } 675 676 template <typename T> 677 T* DynamicCastToGenerated(Message* from) { 678 const Message* message_const = from; 679 return const_cast<T*>(DynamicCastToGenerated<const T>(message_const)); 680 } 681 682 } // namespace internal 683 } // namespace protobuf 684 685 } // namespace google 686 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 687