LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf - generated_message_reflection.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 2 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 26 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13