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