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