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@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>
dynamic_cast_if_available(From from)635 inline To dynamic_cast_if_available(From from) {
636 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
637 return NULL;
638 #else
639 return dynamic_cast<To>(from);
640 #endif
641 }
642
643 // Tries to downcast this message to a generated message type.
644 // Returns NULL if this class is not an instance of T.
645 //
646 // This is like dynamic_cast_if_available, except it works even when
647 // dynamic_cast is not available by using Reflection. However it only works
648 // with Message objects.
649 //
650 // TODO(haberman): can we remove dynamic_cast_if_available in favor of this?
651 template <typename T>
DynamicCastToGenerated(const Message * from)652 T* DynamicCastToGenerated(const Message* from) {
653 // Compile-time assert that T is a generated type that has a
654 // default_instance() accessor, but avoid actually calling it.
655 const T&(*get_default_instance)() = &T::default_instance;
656 (void)get_default_instance;
657
658 // Compile-time assert that T is a subclass of google::protobuf::Message.
659 const Message* unused = static_cast<T*>(NULL);
660 (void)unused;
661
662 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || \
663 (defined(_MSC_VER) && !defined(_CPPRTTI))
664 bool ok = &T::default_instance() ==
665 from->GetReflection()->GetMessageFactory()->GetPrototype(
666 from->GetDescriptor());
667 return ok ? down_cast<T*>(from) : NULL;
668 #else
669 return dynamic_cast<T*>(from);
670 #endif
671 }
672
673 template <typename T>
DynamicCastToGenerated(Message * from)674 T* DynamicCastToGenerated(Message* from) {
675 const Message* message_const = from;
676 return const_cast<T*>(DynamicCastToGenerated<const T>(message_const));
677 }
678
679 } // namespace internal
680 } // namespace protobuf
681
682 } // namespace google
683 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
684