1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 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/common.h> 44 // TODO(jasonh): Remove this once the compiler change to directly include this 45 // is released to components. 46 #include <google/protobuf/generated_enum_reflection.h> 47 #include <google/protobuf/message.h> 48 #include <google/protobuf/unknown_field_set.h> 49 50 51 namespace google { 52 namespace upb { 53 namespace google_opensource { 54 class GMR_Handlers; 55 } // namespace google_opensource 56 } // namespace upb 57 58 namespace protobuf { 59 class DescriptorPool; 60 } 61 62 namespace protobuf { 63 namespace internal { 64 65 // Defined in this file. 66 class GeneratedMessageReflection; 67 68 // Defined in other files. 69 class ExtensionSet; // extension_set.h 70 71 // THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use 72 // by generated code. This class is just a big hack that reduces code 73 // size. 74 // 75 // A GeneratedMessageReflection is an implementation of Reflection 76 // which expects all fields to be backed by simple variables located in 77 // memory. The locations are given using a base pointer and a set of 78 // offsets. 79 // 80 // It is required that the user represents fields of each type in a standard 81 // way, so that GeneratedMessageReflection can cast the void* pointer to 82 // the appropriate type. For primitive fields and string fields, each field 83 // should be represented using the obvious C++ primitive type. Enums and 84 // Messages are different: 85 // - Singular Message fields are stored as a pointer to a Message. These 86 // should start out NULL, except for in the default instance where they 87 // should start out pointing to other default instances. 88 // - Enum fields are stored as an int. This int must always contain 89 // a valid value, such that EnumDescriptor::FindValueByNumber() would 90 // not return NULL. 91 // - Repeated fields are stored as RepeatedFields or RepeatedPtrFields 92 // of whatever type the individual field would be. Strings and 93 // Messages use RepeatedPtrFields while everything else uses 94 // RepeatedFields. 95 class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { 96 public: 97 // Constructs a GeneratedMessageReflection. 98 // Parameters: 99 // descriptor: The descriptor for the message type being implemented. 100 // default_instance: The default instance of the message. This is only 101 // used to obtain pointers to default instances of embedded 102 // messages, which GetMessage() will return if the particular 103 // sub-message has not been initialized yet. (Thus, all 104 // embedded message fields *must* have non-NULL pointers 105 // in the default instance.) 106 // offsets: An array of ints giving the byte offsets, relative to 107 // the start of the message object, of each field. These can 108 // be computed at compile time using the 109 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined 110 // below. 111 // has_bits_offset: Offset in the message of an array of uint32s of size 112 // descriptor->field_count()/32, rounded up. This is a 113 // bitfield where each bit indicates whether or not the 114 // corresponding field of the message has been initialized. 115 // The bit for field index i is obtained by the expression: 116 // has_bits[i / 32] & (1 << (i % 32)) 117 // unknown_fields_offset: Offset in the message of the UnknownFieldSet for 118 // the message. 119 // extensions_offset: Offset in the message of the ExtensionSet for the 120 // message, or -1 if the message type has no extension 121 // ranges. 122 // pool: DescriptorPool to search for extension definitions. Only 123 // used by FindKnownExtensionByName() and 124 // FindKnownExtensionByNumber(). 125 // factory: MessageFactory to use to construct extension messages. 126 // object_size: The size of a message object of this type, as measured 127 // by sizeof(). 128 GeneratedMessageReflection(const Descriptor* descriptor, 129 const Message* default_instance, 130 const int offsets[], 131 int has_bits_offset, 132 int unknown_fields_offset, 133 int extensions_offset, 134 const DescriptorPool* pool, 135 MessageFactory* factory, 136 int object_size); 137 ~GeneratedMessageReflection(); 138 139 // implements Reflection ------------------------------------------- 140 141 const UnknownFieldSet& GetUnknownFields(const Message& message) const; 142 UnknownFieldSet* MutableUnknownFields(Message* message) const; 143 144 int SpaceUsed(const Message& message) const; 145 146 bool HasField(const Message& message, const FieldDescriptor* field) const; 147 int FieldSize(const Message& message, const FieldDescriptor* field) const; 148 void ClearField(Message* message, const FieldDescriptor* field) const; 149 void RemoveLast(Message* message, const FieldDescriptor* field) const; 150 Message* ReleaseLast(Message* message, const FieldDescriptor* field) const; 151 void Swap(Message* message1, Message* message2) const; 152 void SwapElements(Message* message, const FieldDescriptor* field, 153 int index1, int index2) const; 154 void ListFields(const Message& message, 155 vector<const FieldDescriptor*>* output) const; 156 157 int32 GetInt32 (const Message& message, 158 const FieldDescriptor* field) const; 159 int64 GetInt64 (const Message& message, 160 const FieldDescriptor* field) const; 161 uint32 GetUInt32(const Message& message, 162 const FieldDescriptor* field) const; 163 uint64 GetUInt64(const Message& message, 164 const FieldDescriptor* field) const; 165 float GetFloat (const Message& message, 166 const FieldDescriptor* field) const; 167 double GetDouble(const Message& message, 168 const FieldDescriptor* field) const; 169 bool GetBool (const Message& message, 170 const FieldDescriptor* field) const; 171 string GetString(const Message& message, 172 const FieldDescriptor* field) const; 173 const string& GetStringReference(const Message& message, 174 const FieldDescriptor* field, 175 string* scratch) const; 176 const EnumValueDescriptor* GetEnum(const Message& message, 177 const FieldDescriptor* field) const; 178 const Message& GetMessage(const Message& message, 179 const FieldDescriptor* field, 180 MessageFactory* factory = NULL) const; 181 182 void SetInt32 (Message* message, 183 const FieldDescriptor* field, int32 value) const; 184 void SetInt64 (Message* message, 185 const FieldDescriptor* field, int64 value) const; 186 void SetUInt32(Message* message, 187 const FieldDescriptor* field, uint32 value) const; 188 void SetUInt64(Message* message, 189 const FieldDescriptor* field, uint64 value) const; 190 void SetFloat (Message* message, 191 const FieldDescriptor* field, float value) const; 192 void SetDouble(Message* message, 193 const FieldDescriptor* field, double value) const; 194 void SetBool (Message* message, 195 const FieldDescriptor* field, bool value) const; 196 void SetString(Message* message, 197 const FieldDescriptor* field, 198 const string& value) const; 199 void SetEnum (Message* message, const FieldDescriptor* field, 200 const EnumValueDescriptor* value) const; 201 Message* MutableMessage(Message* message, const FieldDescriptor* field, 202 MessageFactory* factory = NULL) const; 203 Message* ReleaseMessage(Message* message, const FieldDescriptor* field, 204 MessageFactory* factory = NULL) const; 205 206 int32 GetRepeatedInt32 (const Message& message, 207 const FieldDescriptor* field, int index) const; 208 int64 GetRepeatedInt64 (const Message& message, 209 const FieldDescriptor* field, int index) const; 210 uint32 GetRepeatedUInt32(const Message& message, 211 const FieldDescriptor* field, int index) const; 212 uint64 GetRepeatedUInt64(const Message& message, 213 const FieldDescriptor* field, int index) const; 214 float GetRepeatedFloat (const Message& message, 215 const FieldDescriptor* field, int index) const; 216 double GetRepeatedDouble(const Message& message, 217 const FieldDescriptor* field, int index) const; 218 bool GetRepeatedBool (const Message& message, 219 const FieldDescriptor* field, int index) const; 220 string GetRepeatedString(const Message& message, 221 const FieldDescriptor* field, int index) const; 222 const string& GetRepeatedStringReference(const Message& message, 223 const FieldDescriptor* field, 224 int index, string* scratch) const; 225 const EnumValueDescriptor* GetRepeatedEnum(const Message& message, 226 const FieldDescriptor* field, 227 int index) const; 228 const Message& GetRepeatedMessage(const Message& message, 229 const FieldDescriptor* field, 230 int index) const; 231 232 // Set the value of a field. 233 void SetRepeatedInt32 (Message* message, 234 const FieldDescriptor* field, int index, int32 value) const; 235 void SetRepeatedInt64 (Message* message, 236 const FieldDescriptor* field, int index, int64 value) const; 237 void SetRepeatedUInt32(Message* message, 238 const FieldDescriptor* field, int index, uint32 value) const; 239 void SetRepeatedUInt64(Message* message, 240 const FieldDescriptor* field, int index, uint64 value) const; 241 void SetRepeatedFloat (Message* message, 242 const FieldDescriptor* field, int index, float value) const; 243 void SetRepeatedDouble(Message* message, 244 const FieldDescriptor* field, int index, double value) const; 245 void SetRepeatedBool (Message* message, 246 const FieldDescriptor* field, int index, bool value) const; 247 void SetRepeatedString(Message* message, 248 const FieldDescriptor* field, int index, 249 const string& value) const; 250 void SetRepeatedEnum(Message* message, const FieldDescriptor* field, 251 int index, const EnumValueDescriptor* value) const; 252 // Get a mutable pointer to a field with a message type. 253 Message* MutableRepeatedMessage(Message* message, 254 const FieldDescriptor* field, 255 int index) const; 256 257 void AddInt32 (Message* message, 258 const FieldDescriptor* field, int32 value) const; 259 void AddInt64 (Message* message, 260 const FieldDescriptor* field, int64 value) const; 261 void AddUInt32(Message* message, 262 const FieldDescriptor* field, uint32 value) const; 263 void AddUInt64(Message* message, 264 const FieldDescriptor* field, uint64 value) const; 265 void AddFloat (Message* message, 266 const FieldDescriptor* field, float value) const; 267 void AddDouble(Message* message, 268 const FieldDescriptor* field, double value) const; 269 void AddBool (Message* message, 270 const FieldDescriptor* field, bool value) const; 271 void AddString(Message* message, 272 const FieldDescriptor* field, const string& value) const; 273 void AddEnum(Message* message, 274 const FieldDescriptor* field, 275 const EnumValueDescriptor* value) const; 276 Message* AddMessage(Message* message, const FieldDescriptor* field, 277 MessageFactory* factory = NULL) const; 278 279 const FieldDescriptor* FindKnownExtensionByName(const string& name) const; 280 const FieldDescriptor* FindKnownExtensionByNumber(int number) const; 281 282 protected: 283 virtual void* MutableRawRepeatedField( 284 Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, 285 int ctype, const Descriptor* desc) const; 286 287 private: 288 friend class GeneratedMessage; 289 290 // To parse directly into a proto2 generated class, the class GMR_Handlers 291 // needs access to member offsets and hasbits. 292 friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers; 293 294 const Descriptor* descriptor_; 295 const Message* default_instance_; 296 const int* offsets_; 297 298 int has_bits_offset_; 299 int unknown_fields_offset_; 300 int extensions_offset_; 301 int object_size_; 302 303 const DescriptorPool* descriptor_pool_; 304 MessageFactory* message_factory_; 305 306 template <typename Type> 307 inline const Type& GetRaw(const Message& message, 308 const FieldDescriptor* field) const; 309 template <typename Type> 310 inline Type* MutableRaw(Message* message, 311 const FieldDescriptor* field) const; 312 template <typename Type> 313 inline const Type& DefaultRaw(const FieldDescriptor* field) const; 314 315 inline const uint32* GetHasBits(const Message& message) const; 316 inline uint32* MutableHasBits(Message* message) const; 317 inline const ExtensionSet& GetExtensionSet(const Message& message) const; 318 inline ExtensionSet* MutableExtensionSet(Message* message) const; 319 320 inline bool HasBit(const Message& message, 321 const FieldDescriptor* field) const; 322 inline void SetBit(Message* message, 323 const FieldDescriptor* field) const; 324 inline void ClearBit(Message* message, 325 const FieldDescriptor* field) const; 326 327 template <typename Type> 328 inline const Type& GetField(const Message& message, 329 const FieldDescriptor* field) const; 330 template <typename Type> 331 inline void SetField(Message* message, 332 const FieldDescriptor* field, const Type& value) const; 333 template <typename Type> 334 inline Type* MutableField(Message* message, 335 const FieldDescriptor* field) const; 336 template <typename Type> 337 inline const Type& GetRepeatedField(const Message& message, 338 const FieldDescriptor* field, 339 int index) const; 340 template <typename Type> 341 inline const Type& GetRepeatedPtrField(const Message& message, 342 const FieldDescriptor* field, 343 int index) const; 344 template <typename Type> 345 inline void SetRepeatedField(Message* message, 346 const FieldDescriptor* field, int index, 347 Type value) const; 348 template <typename Type> 349 inline Type* MutableRepeatedField(Message* message, 350 const FieldDescriptor* field, 351 int index) const; 352 template <typename Type> 353 inline void AddField(Message* message, 354 const FieldDescriptor* field, const Type& value) const; 355 template <typename Type> 356 inline Type* AddField(Message* message, 357 const FieldDescriptor* field) const; 358 359 int GetExtensionNumberOrDie(const Descriptor* type) const; 360 361 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); 362 }; 363 364 // Returns the offset of the given field within the given aggregate type. 365 // This is equivalent to the ANSI C offsetof() macro. However, according 366 // to the C++ standard, offsetof() only works on POD types, and GCC 367 // enforces this requirement with a warning. In practice, this rule is 368 // unnecessarily strict; there is probably no compiler or platform on 369 // which the offsets of the direct fields of a class are non-constant. 370 // Fields inherited from superclasses *can* have non-constant offsets, 371 // but that's not what this macro will be used for. 372 // 373 // Note that we calculate relative to the pointer value 16 here since if we 374 // just use zero, GCC complains about dereferencing a NULL pointer. We 375 // choose 16 rather than some other number just in case the compiler would 376 // be confused by an unaligned pointer. 377 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ 378 static_cast<int>( \ 379 reinterpret_cast<const char*>( \ 380 &reinterpret_cast<const TYPE*>(16)->FIELD) - \ 381 reinterpret_cast<const char*>(16)) 382 383 // There are some places in proto2 where dynamic_cast would be useful as an 384 // optimization. For example, take Message::MergeFrom(const Message& other). 385 // For a given generated message FooMessage, we generate these two methods: 386 // void MergeFrom(const FooMessage& other); 387 // void MergeFrom(const Message& other); 388 // The former method can be implemented directly in terms of FooMessage's 389 // inline accessors, but the latter method must work with the reflection 390 // interface. However, if the parameter to the latter method is actually of 391 // type FooMessage, then we'd like to be able to just call the other method 392 // as an optimization. So, we use dynamic_cast to check this. 393 // 394 // That said, dynamic_cast requires RTTI, which many people like to disable 395 // for performance and code size reasons. When RTTI is not available, we 396 // still need to produce correct results. So, in this case we have to fall 397 // back to using reflection, which is what we would have done anyway if the 398 // objects were not of the exact same class. 399 // 400 // dynamic_cast_if_available() implements this logic. If RTTI is 401 // enabled, it does a dynamic_cast. If RTTI is disabled, it just returns 402 // NULL. 403 // 404 // If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. 405 // On MSVC, this should be detected automatically. 406 template<typename To, typename From> 407 inline To dynamic_cast_if_available(From from) { 408 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) 409 return NULL; 410 #else 411 return dynamic_cast<To>(from); 412 #endif 413 } 414 415 } // namespace internal 416 } // namespace protobuf 417 418 } // namespace google 419 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 420