webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
generated_message_reflection.h
Go to the documentation of this file.
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>
45 // TODO(jasonh): Remove this once the compiler change to directly include this
46 // is released to components.
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.
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().
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,
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);
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;
482  GetInternalMetadataWithArena(const Message& message) const;
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 
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(_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>
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() ==
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>
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__
Definition: message.h:179
EnumValueDescriptorProto * AddEnumValue(EnumDescriptorProto *enum_proto, const string &name, int number)
Definition: descriptor_unittest.cc:157
const FieldDescriptor * field
Definition: parser_unittest.cc:2279
virtual const Message * GetPrototype(const Descriptor *type)=0
Definition: map_field.h:60
Definition: message.h:401
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: macros.h:40
ClearField
Definition: python_message.py:887
const Descriptor * descriptor_
Definition: field_comparator_test.cc:58
Definition: extension_set.h:160
const Descriptor * descriptor
Definition: descriptor.cc:271
const OneofDescriptor * oneof_descriptor
Definition: descriptor.cc:273
Definition: descriptor.h:172
virtual const Reflection * GetReflection() const
Definition: message.h:331
EGLImageKHR int EGLint EGLint * offsets
Definition: eglext.h:861
Definition: AirOpcode.h:13
#define desc
Definition: extension_set.h:320
#define output
Definition: wire_format_lite.h:418
Definition: descriptor.h:439
void
Definition: AVFoundationCFSoftLinking.h:81
Definition: generated_message_reflection.h:100
int32_t int32
Definition: port.h:130
TestSubObjConstructor T
Definition: TestTypedefs.idl:84
ListFields
Definition: python_message.py:805
rtc::scoped_refptr< PeerConnectionFactoryInterface > factory(webrtc::CreatePeerConnectionFactory(network_thread.get(), worker_thread.get(), signaling_thread.get(), nullptr, encoder_factory, decoder_factory))
Definition: peerconnection_jni.cc:1838
Definition: map.h:97
GLuint index
Definition: gl2.h:383
EGLAttrib * value
Definition: eglext.h:120
T * DynamicCastToGenerated(Message *from)
Definition: generated_message_reflection.h:674
Definition: map.h:297
Definition: protobuf.h:64
uint32_t uint32
Definition: port.h:135
EGLImageKHR EGLint * name
Definition: eglext.h:851
const AtomicString & number()
Definition: InputTypeNames.cpp:100
Definition: __init__.py:1
uint64_t uint64
Definition: port.h:136
To dynamic_cast_if_available(From from)
Definition: generated_message_reflection.h:635
Definition: type.pb.h:133
Definition: arena.h:218
virtual MessageFactory * GetMessageFactory() const
Definition: message.cc:410
Definition: unknown_field_set.h:75
EGLenum type
Definition: eglext.h:63
Definition: document.h:393
Definition: descriptor.h:1355
int64_t int64
Definition: port.h:131
Definition: AirOpcode.h:12
FieldDescriptor::CppType cpp_type(FieldType type)
Definition: extension_set_heavy.cc:128
#define NULL
Definition: common_types.h:41
#define LIBPROTOBUF_EXPORT
Definition: port.h:97
Definition: gflags_completions.h:115
Definition: descriptor.h:919
FieldDescriptorProto * AddField(DescriptorProto *parent, const string &name, int number, FieldDescriptorProto::Label label, FieldDescriptorProto::Type type)
Definition: descriptor_unittest.cc:101
To down_cast(From *f)
Definition: casts.h:81
Definition: message.h:1006
EnumDescriptorProto * AddEnum(FileDescriptorProto *file, const string &name)
Definition: descriptor_unittest.cc:81
DescriptorProto * AddMessage(FileDescriptorProto *file, const string &name)
Definition: descriptor_unittest.cc:69
CFArrayRef CFTypeRef key
Definition: AVFoundationCFSoftLinking.h:129
GLuint GLsizei const GLchar * message
Definition: gl2ext.h:137
Definition: descriptor.h:736
const Descriptor * GetDescriptor() const
Definition: message.h:322
Definition: map_field.h:327
GLuint GLsizei GLsizei GLfloat * val
Definition: gl2ext.h:3301
HasField
Definition: python_message.py:849
message_type
Definition: descriptor_pb2.py:1556
Message * ReleaseMessage(CMessage *self, const Descriptor *descriptor, const FieldDescriptor *field_descriptor)
Definition: message.cc:1556
ANGLE_EXPORT const GLubyte *GL_APIENTRY GetString(GLenum name)
Definition: entry_points_gles_2_0.cpp:1660