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_EXTENSION_SET_H__
     39 #define GOOGLE_PROTOBUF_EXTENSION_SET_H__
     40 
     41 #include <vector>
     42 #include <stack>
     43 #include <map>
     44 #include <utility>
     45 #include <string>
     46 
     47 #include <google/protobuf/stubs/common.h>
     48 
     49 namespace google {
     50 
     51 namespace protobuf {
     52   class Descriptor;                                    // descriptor.h
     53   class FieldDescriptor;                               // descriptor.h
     54   class DescriptorPool;                                // descriptor.h
     55   class MessageLite;                                   // message_lite.h
     56   class Message;                                       // message.h
     57   class MessageFactory;                                // message.h
     58   class UnknownFieldSet;                               // unknown_field_set.h
     59   namespace io {
     60     class CodedInputStream;                              // coded_stream.h
     61     class CodedOutputStream;                             // coded_stream.h
     62   }
     63   namespace internal {
     64     class FieldSkipper;                                  // wire_format_lite.h
     65     class RepeatedPtrFieldBase;                          // repeated_field.h
     66   }
     67   template <typename Element> class RepeatedField;     // repeated_field.h
     68   template <typename Element> class RepeatedPtrField;  // repeated_field.h
     69 }
     70 
     71 namespace protobuf {
     72 namespace internal {
     73 
     74 // Used to store values of type WireFormatLite::FieldType without having to
     75 // #include wire_format_lite.h.  Also, ensures that we use only one byte to
     76 // store these values, which is important to keep the layout of
     77 // ExtensionSet::Extension small.
     78 typedef uint8 FieldType;
     79 
     80 // A function which, given an integer value, returns true if the number
     81 // matches one of the defined values for the corresponding enum type.  This
     82 // is used with RegisterEnumExtension, below.
     83 typedef bool EnumValidityFunc(int number);
     84 
     85 // Version of the above which takes an argument.  This is needed to deal with
     86 // extensions that are not compiled in.
     87 typedef bool EnumValidityFuncWithArg(const void* arg, int number);
     88 
     89 // Information about a registered extension.
     90 struct ExtensionInfo {
     91   inline ExtensionInfo() {}
     92   inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
     93       : type(type), is_repeated(is_repeated), is_packed(is_packed),
     94         descriptor(NULL) {}
     95 
     96   FieldType type;
     97   bool is_repeated;
     98   bool is_packed;
     99 
    100   struct EnumValidityCheck {
    101     EnumValidityFuncWithArg* func;
    102     const void* arg;
    103   };
    104 
    105   union {
    106     EnumValidityCheck enum_validity_check;
    107     const MessageLite* message_prototype;
    108   };
    109 
    110   // The descriptor for this extension, if one exists and is known.  May be
    111   // NULL.  Must not be NULL if the descriptor for the extension does not
    112   // live in the same pool as the descriptor for the containing type.
    113   const FieldDescriptor* descriptor;
    114 };
    115 
    116 // Abstract interface for an object which looks up extension definitions.  Used
    117 // when parsing.
    118 class LIBPROTOBUF_EXPORT ExtensionFinder {
    119  public:
    120   virtual ~ExtensionFinder();
    121 
    122   // Find the extension with the given containing type and number.
    123   virtual bool Find(int number, ExtensionInfo* output) = 0;
    124 };
    125 
    126 // Implementation of ExtensionFinder which finds extensions defined in .proto
    127 // files which have been compiled into the binary.
    128 class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
    129  public:
    130   GeneratedExtensionFinder(const MessageLite* containing_type)
    131       : containing_type_(containing_type) {}
    132   virtual ~GeneratedExtensionFinder() {}
    133 
    134   // Returns true and fills in *output if found, otherwise returns false.
    135   virtual bool Find(int number, ExtensionInfo* output);
    136 
    137  private:
    138   const MessageLite* containing_type_;
    139 };
    140 
    141 // Note:  extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
    142 // finding extensions from a DescriptorPool.
    143 
    144 // This is an internal helper class intended for use within the protocol buffer
    145 // library and generated classes.  Clients should not use it directly.  Instead,
    146 // use the generated accessors such as GetExtension() of the class being
    147 // extended.
    148 //
    149 // This class manages extensions for a protocol message object.  The
    150 // message's HasExtension(), GetExtension(), MutableExtension(), and
    151 // ClearExtension() methods are just thin wrappers around the embedded
    152 // ExtensionSet.  When parsing, if a tag number is encountered which is
    153 // inside one of the message type's extension ranges, the tag is passed
    154 // off to the ExtensionSet for parsing.  Etc.
    155 class LIBPROTOBUF_EXPORT ExtensionSet {
    156  public:
    157   ExtensionSet();
    158   ~ExtensionSet();
    159 
    160   // These are called at startup by protocol-compiler-generated code to
    161   // register known extensions.  The registrations are used by ParseField()
    162   // to look up extensions for parsed field numbers.  Note that dynamic parsing
    163   // does not use ParseField(); only protocol-compiler-generated parsing
    164   // methods do.
    165   static void RegisterExtension(const MessageLite* containing_type,
    166                                 int number, FieldType type,
    167                                 bool is_repeated, bool is_packed);
    168   static void RegisterEnumExtension(const MessageLite* containing_type,
    169                                     int number, FieldType type,
    170                                     bool is_repeated, bool is_packed,
    171                                     EnumValidityFunc* is_valid);
    172   static void RegisterMessageExtension(const MessageLite* containing_type,
    173                                        int number, FieldType type,
    174                                        bool is_repeated, bool is_packed,
    175                                        const MessageLite* prototype);
    176 
    177   // =================================================================
    178 
    179   // Add all fields which are currently present to the given vector.  This
    180   // is useful to implement Reflection::ListFields().
    181   void AppendToList(const Descriptor* containing_type,
    182                     const DescriptorPool* pool,
    183                     vector<const FieldDescriptor*>* output) const;
    184 
    185   // =================================================================
    186   // Accessors
    187   //
    188   // Generated message classes include type-safe templated wrappers around
    189   // these methods.  Generally you should use those rather than call these
    190   // directly, unless you are doing low-level memory management.
    191   //
    192   // When calling any of these accessors, the extension number requested
    193   // MUST exist in the DescriptorPool provided to the constructor.  Otheriwse,
    194   // the method will fail an assert.  Normally, though, you would not call
    195   // these directly; you would either call the generated accessors of your
    196   // message class (e.g. GetExtension()) or you would call the accessors
    197   // of the reflection interface.  In both cases, it is impossible to
    198   // trigger this assert failure:  the generated accessors only accept
    199   // linked-in extension types as parameters, while the Reflection interface
    200   // requires you to provide the FieldDescriptor describing the extension.
    201   //
    202   // When calling any of these accessors, a protocol-compiler-generated
    203   // implementation of the extension corresponding to the number MUST
    204   // be linked in, and the FieldDescriptor used to refer to it MUST be
    205   // the one generated by that linked-in code.  Otherwise, the method will
    206   // die on an assert failure.  The message objects returned by the message
    207   // accessors are guaranteed to be of the correct linked-in type.
    208   //
    209   // These methods pretty much match Reflection except that:
    210   // - They're not virtual.
    211   // - They identify fields by number rather than FieldDescriptors.
    212   // - They identify enum values using integers rather than descriptors.
    213   // - Strings provide Mutable() in addition to Set() accessors.
    214 
    215   bool Has(int number) const;
    216   int ExtensionSize(int number) const;   // Size of a repeated extension.
    217   void ClearExtension(int number);
    218 
    219   // singular fields -------------------------------------------------
    220 
    221   int32  GetInt32 (int number, int32  default_value) const;
    222   int64  GetInt64 (int number, int64  default_value) const;
    223   uint32 GetUInt32(int number, uint32 default_value) const;
    224   uint64 GetUInt64(int number, uint64 default_value) const;
    225   float  GetFloat (int number, float  default_value) const;
    226   double GetDouble(int number, double default_value) const;
    227   bool   GetBool  (int number, bool   default_value) const;
    228   int    GetEnum  (int number, int    default_value) const;
    229   const string & GetString (int number, const string&  default_value) const;
    230   const MessageLite& GetMessage(int number,
    231                                 const MessageLite& default_value) const;
    232   const MessageLite& GetMessage(int number, const Descriptor* message_type,
    233                                 MessageFactory* factory) const;
    234 
    235   // |descriptor| may be NULL so long as it is known that the descriptor for
    236   // the extension lives in the same pool as the descriptor for the containing
    237   // type.
    238 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
    239   void SetInt32 (int number, FieldType type, int32  value, desc);
    240   void SetInt64 (int number, FieldType type, int64  value, desc);
    241   void SetUInt32(int number, FieldType type, uint32 value, desc);
    242   void SetUInt64(int number, FieldType type, uint64 value, desc);
    243   void SetFloat (int number, FieldType type, float  value, desc);
    244   void SetDouble(int number, FieldType type, double value, desc);
    245   void SetBool  (int number, FieldType type, bool   value, desc);
    246   void SetEnum  (int number, FieldType type, int    value, desc);
    247   void SetString(int number, FieldType type, const string& value, desc);
    248   string * MutableString (int number, FieldType type, desc);
    249   MessageLite* MutableMessage(int number, FieldType type,
    250                               const MessageLite& prototype, desc);
    251   MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
    252                               MessageFactory* factory);
    253 #undef desc
    254 
    255   // repeated fields -------------------------------------------------
    256 
    257   int32  GetRepeatedInt32 (int number, int index) const;
    258   int64  GetRepeatedInt64 (int number, int index) const;
    259   uint32 GetRepeatedUInt32(int number, int index) const;
    260   uint64 GetRepeatedUInt64(int number, int index) const;
    261   float  GetRepeatedFloat (int number, int index) const;
    262   double GetRepeatedDouble(int number, int index) const;
    263   bool   GetRepeatedBool  (int number, int index) const;
    264   int    GetRepeatedEnum  (int number, int index) const;
    265   const string & GetRepeatedString (int number, int index) const;
    266   const MessageLite& GetRepeatedMessage(int number, int index) const;
    267 
    268   void SetRepeatedInt32 (int number, int index, int32  value);
    269   void SetRepeatedInt64 (int number, int index, int64  value);
    270   void SetRepeatedUInt32(int number, int index, uint32 value);
    271   void SetRepeatedUInt64(int number, int index, uint64 value);
    272   void SetRepeatedFloat (int number, int index, float  value);
    273   void SetRepeatedDouble(int number, int index, double value);
    274   void SetRepeatedBool  (int number, int index, bool   value);
    275   void SetRepeatedEnum  (int number, int index, int    value);
    276   void SetRepeatedString(int number, int index, const string& value);
    277   string * MutableRepeatedString (int number, int index);
    278   MessageLite* MutableRepeatedMessage(int number, int index);
    279 
    280 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
    281   void AddInt32 (int number, FieldType type, bool packed, int32  value, desc);
    282   void AddInt64 (int number, FieldType type, bool packed, int64  value, desc);
    283   void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
    284   void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
    285   void AddFloat (int number, FieldType type, bool packed, float  value, desc);
    286   void AddDouble(int number, FieldType type, bool packed, double value, desc);
    287   void AddBool  (int number, FieldType type, bool packed, bool   value, desc);
    288   void AddEnum  (int number, FieldType type, bool packed, int    value, desc);
    289   void AddString(int number, FieldType type, const string& value, desc);
    290   string * AddString (int number, FieldType type, desc);
    291   MessageLite* AddMessage(int number, FieldType type,
    292                           const MessageLite& prototype, desc);
    293   MessageLite* AddMessage(const FieldDescriptor* descriptor,
    294                           MessageFactory* factory);
    295 #undef desc
    296 
    297   void RemoveLast(int number);
    298   void SwapElements(int number, int index1, int index2);
    299 
    300   // -----------------------------------------------------------------
    301   // TODO(kenton):  Hardcore memory management accessors
    302 
    303   // =================================================================
    304   // convenience methods for implementing methods of Message
    305   //
    306   // These could all be implemented in terms of the other methods of this
    307   // class, but providing them here helps keep the generated code size down.
    308 
    309   void Clear();
    310   void MergeFrom(const ExtensionSet& other);
    311   void Swap(ExtensionSet* other);
    312   bool IsInitialized() const;
    313 
    314   // Parses a single extension from the input.  The input should start out
    315   // positioned immediately after the tag.  |containing_type| is the default
    316   // instance for the containing message; it is used only to look up the
    317   // extension by number.  See RegisterExtension(), above.  Unlike the other
    318   // methods of ExtensionSet, this only works for generated message types --
    319   // it looks up extensions registered using RegisterExtension().
    320   bool ParseField(uint32 tag, io::CodedInputStream* input,
    321                   ExtensionFinder* extension_finder,
    322                   FieldSkipper* field_skipper);
    323 
    324   // Specific versions for lite or full messages (constructs the appropriate
    325   // FieldSkipper automatically).
    326   bool ParseField(uint32 tag, io::CodedInputStream* input,
    327                   const MessageLite* containing_type);
    328   bool ParseField(uint32 tag, io::CodedInputStream* input,
    329                   const Message* containing_type,
    330                   UnknownFieldSet* unknown_fields);
    331 
    332   // Parse an entire message in MessageSet format.  Such messages have no
    333   // fields, only extensions.
    334   bool ParseMessageSet(io::CodedInputStream* input,
    335                        ExtensionFinder* extension_finder,
    336                        FieldSkipper* field_skipper);
    337 
    338   // Specific versions for lite or full messages (constructs the appropriate
    339   // FieldSkipper automatically).
    340   bool ParseMessageSet(io::CodedInputStream* input,
    341                        const MessageLite* containing_type);
    342   bool ParseMessageSet(io::CodedInputStream* input,
    343                        const Message* containing_type,
    344                        UnknownFieldSet* unknown_fields);
    345 
    346   // Write all extension fields with field numbers in the range
    347   //   [start_field_number, end_field_number)
    348   // to the output stream, using the cached sizes computed when ByteSize() was
    349   // last called.  Note that the range bounds are inclusive-exclusive.
    350   void SerializeWithCachedSizes(int start_field_number,
    351                                 int end_field_number,
    352                                 io::CodedOutputStream* output) const;
    353 
    354   // Same as SerializeWithCachedSizes, but without any bounds checking.
    355   // The caller must ensure that target has sufficient capacity for the
    356   // serialized extensions.
    357   //
    358   // Returns a pointer past the last written byte.
    359   uint8* SerializeWithCachedSizesToArray(int start_field_number,
    360                                          int end_field_number,
    361                                          uint8* target) const;
    362 
    363   // Like above but serializes in MessageSet format.
    364   void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
    365   uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
    366 
    367   // Returns the total serialized size of all the extensions.
    368   int ByteSize() const;
    369 
    370   // Like ByteSize() but uses MessageSet format.
    371   int MessageSetByteSize() const;
    372 
    373   // Returns (an estimate of) the total number of bytes used for storing the
    374   // extensions in memory, excluding sizeof(*this).  If the ExtensionSet is
    375   // for a lite message (and thus possibly contains lite messages), the results
    376   // are undefined (might work, might crash, might corrupt data, might not even
    377   // be linked in).  It's up to the protocol compiler to avoid calling this on
    378   // such ExtensionSets (easy enough since lite messages don't implement
    379   // SpaceUsed()).
    380   int SpaceUsedExcludingSelf() const;
    381 
    382  private:
    383 
    384   struct Extension {
    385     union {
    386       int32        int32_value;
    387       int64        int64_value;
    388       uint32       uint32_value;
    389       uint64       uint64_value;
    390       float        float_value;
    391       double       double_value;
    392       bool         bool_value;
    393       int          enum_value;
    394       string*      string_value;
    395       MessageLite* message_value;
    396 
    397       RepeatedField   <int32      >* repeated_int32_value;
    398       RepeatedField   <int64      >* repeated_int64_value;
    399       RepeatedField   <uint32     >* repeated_uint32_value;
    400       RepeatedField   <uint64     >* repeated_uint64_value;
    401       RepeatedField   <float      >* repeated_float_value;
    402       RepeatedField   <double     >* repeated_double_value;
    403       RepeatedField   <bool       >* repeated_bool_value;
    404       RepeatedField   <int        >* repeated_enum_value;
    405       RepeatedPtrField<string     >* repeated_string_value;
    406       RepeatedPtrField<MessageLite>* repeated_message_value;
    407     };
    408 
    409     FieldType type;
    410     bool is_repeated;
    411 
    412     // For singular types, indicates if the extension is "cleared".  This
    413     // happens when an extension is set and then later cleared by the caller.
    414     // We want to keep the Extension object around for reuse, so instead of
    415     // removing it from the map, we just set is_cleared = true.  This has no
    416     // meaning for repeated types; for those, the size of the RepeatedField
    417     // simply becomes zero when cleared.
    418     bool is_cleared;
    419 
    420     // For repeated types, this indicates if the [packed=true] option is set.
    421     bool is_packed;
    422 
    423     // The descriptor for this extension, if one exists and is known.  May be
    424     // NULL.  Must not be NULL if the descriptor for the extension does not
    425     // live in the same pool as the descriptor for the containing type.
    426     const FieldDescriptor* descriptor;
    427 
    428     // For packed fields, the size of the packed data is recorded here when
    429     // ByteSize() is called then used during serialization.
    430     // TODO(kenton):  Use atomic<int> when C++ supports it.
    431     mutable int cached_size;
    432 
    433     // Some helper methods for operations on a single Extension.
    434     void SerializeFieldWithCachedSizes(
    435         int number,
    436         io::CodedOutputStream* output) const;
    437     uint8* SerializeFieldWithCachedSizesToArray(
    438         int number,
    439         uint8* target) const;
    440     void SerializeMessageSetItemWithCachedSizes(
    441         int number,
    442         io::CodedOutputStream* output) const;
    443     uint8* SerializeMessageSetItemWithCachedSizesToArray(
    444         int number,
    445         uint8* target) const;
    446     int ByteSize(int number) const;
    447     int MessageSetItemByteSize(int number) const;
    448     void Clear();
    449     int GetSize() const;
    450     void Free();
    451     int SpaceUsedExcludingSelf() const;
    452   };
    453 
    454   // Gets the extension with the given number, creating it if it does not
    455   // already exist.  Returns true if the extension did not already exist.
    456   bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
    457                          Extension** result);
    458 
    459   // Parse a single MessageSet item -- called just after the item group start
    460   // tag has been read.
    461   bool ParseMessageSetItem(io::CodedInputStream* input,
    462                            ExtensionFinder* extension_finder,
    463                            FieldSkipper* field_skipper);
    464 
    465 
    466   // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
    467   //   friendship should automatically extend to ExtensionSet::Extension, but
    468   //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
    469   //   correctly.  So, we must provide helpers for calling methods of that
    470   //   class.
    471 
    472   // Defined in extension_set_heavy.cc.
    473   static inline int RepeatedMessage_SpaceUsedExcludingSelf(
    474       RepeatedPtrFieldBase* field);
    475 
    476   // The Extension struct is small enough to be passed by value, so we use it
    477   // directly as the value type in the map rather than use pointers.  We use
    478   // a map rather than hash_map here because we expect most ExtensionSets will
    479   // only contain a small number of extensions whereas hash_map is optimized
    480   // for 100 elements or more.  Also, we want AppendToList() to order fields
    481   // by field number.
    482   map<int, Extension> extensions_;
    483 
    484   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
    485 };
    486 
    487 // These are just for convenience...
    488 inline void ExtensionSet::SetString(int number, FieldType type,
    489                                     const string& value,
    490                                     const FieldDescriptor* descriptor) {
    491   MutableString(number, type, descriptor)->assign(value);
    492 }
    493 inline void ExtensionSet::SetRepeatedString(int number, int index,
    494                                             const string& value) {
    495   MutableRepeatedString(number, index)->assign(value);
    496 }
    497 inline void ExtensionSet::AddString(int number, FieldType type,
    498                                     const string& value,
    499                                     const FieldDescriptor* descriptor) {
    500   AddString(number, type, descriptor)->assign(value);
    501 }
    502 
    503 // ===================================================================
    504 // Glue for generated extension accessors
    505 
    506 // -------------------------------------------------------------------
    507 // Template magic
    508 
    509 // First we have a set of classes representing "type traits" for different
    510 // field types.  A type traits class knows how to implement basic accessors
    511 // for extensions of a particular type given an ExtensionSet.  The signature
    512 // for a type traits class looks like this:
    513 //
    514 //   class TypeTraits {
    515 //    public:
    516 //     typedef ? ConstType;
    517 //     typedef ? MutableType;
    518 //
    519 //     static inline ConstType Get(int number, const ExtensionSet& set);
    520 //     static inline void Set(int number, ConstType value, ExtensionSet* set);
    521 //     static inline MutableType Mutable(int number, ExtensionSet* set);
    522 //
    523 //     // Variants for repeated fields.
    524 //     static inline ConstType Get(int number, const ExtensionSet& set,
    525 //                                 int index);
    526 //     static inline void Set(int number, int index,
    527 //                            ConstType value, ExtensionSet* set);
    528 //     static inline MutableType Mutable(int number, int index,
    529 //                                       ExtensionSet* set);
    530 //     static inline void Add(int number, ConstType value, ExtensionSet* set);
    531 //     static inline MutableType Add(int number, ExtensionSet* set);
    532 //   };
    533 //
    534 // Not all of these methods make sense for all field types.  For example, the
    535 // "Mutable" methods only make sense for strings and messages, and the
    536 // repeated methods only make sense for repeated types.  So, each type
    537 // traits class implements only the set of methods from this signature that it
    538 // actually supports.  This will cause a compiler error if the user tries to
    539 // access an extension using a method that doesn't make sense for its type.
    540 // For example, if "foo" is an extension of type "optional int32", then if you
    541 // try to write code like:
    542 //   my_message.MutableExtension(foo)
    543 // you will get a compile error because PrimitiveTypeTraits<int32> does not
    544 // have a "Mutable()" method.
    545 
    546 // -------------------------------------------------------------------
    547 // PrimitiveTypeTraits
    548 
    549 // Since the ExtensionSet has different methods for each primitive type,
    550 // we must explicitly define the methods of the type traits class for each
    551 // known type.
    552 template <typename Type>
    553 class PrimitiveTypeTraits {
    554  public:
    555   typedef Type ConstType;
    556 
    557   static inline ConstType Get(int number, const ExtensionSet& set,
    558                               ConstType default_value);
    559   static inline void Set(int number, FieldType field_type,
    560                          ConstType value, ExtensionSet* set);
    561 };
    562 
    563 template <typename Type>
    564 class RepeatedPrimitiveTypeTraits {
    565  public:
    566   typedef Type ConstType;
    567 
    568   static inline Type Get(int number, const ExtensionSet& set, int index);
    569   static inline void Set(int number, int index, Type value, ExtensionSet* set);
    570   static inline void Add(int number, FieldType field_type,
    571                          bool is_packed, Type value, ExtensionSet* set);
    572 };
    573 
    574 #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
    575 template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get(                     \
    576     int number, const ExtensionSet& set, TYPE default_value) {             \
    577   return set.Get##METHOD(number, default_value);                           \
    578 }                                                                          \
    579 template<> inline void PrimitiveTypeTraits<TYPE>::Set(                     \
    580     int number, FieldType field_type, TYPE value, ExtensionSet* set) {     \
    581   set->Set##METHOD(number, field_type, value, NULL);                       \
    582 }                                                                          \
    583                                                                            \
    584 template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(             \
    585     int number, const ExtensionSet& set, int index) {                      \
    586   return set.GetRepeated##METHOD(number, index);                           \
    587 }                                                                          \
    588 template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(             \
    589     int number, int index, TYPE value, ExtensionSet* set) {                \
    590   set->SetRepeated##METHOD(number, index, value);                          \
    591 }                                                                          \
    592 template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(             \
    593     int number, FieldType field_type, bool is_packed,                      \
    594     TYPE value, ExtensionSet* set) {                                       \
    595   set->Add##METHOD(number, field_type, is_packed, value, NULL);            \
    596 }
    597 
    598 PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32,  Int32)
    599 PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64,  Int64)
    600 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
    601 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
    602 PROTOBUF_DEFINE_PRIMITIVE_TYPE( float,  Float)
    603 PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
    604 PROTOBUF_DEFINE_PRIMITIVE_TYPE(  bool,   Bool)
    605 
    606 #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
    607 
    608 // -------------------------------------------------------------------
    609 // StringTypeTraits
    610 
    611 // Strings support both Set() and Mutable().
    612 class LIBPROTOBUF_EXPORT StringTypeTraits {
    613  public:
    614   typedef const string& ConstType;
    615   typedef string* MutableType;
    616 
    617   static inline const string& Get(int number, const ExtensionSet& set,
    618                                   ConstType default_value) {
    619     return set.GetString(number, default_value);
    620   }
    621   static inline void Set(int number, FieldType field_type,
    622                          const string& value, ExtensionSet* set) {
    623     set->SetString(number, field_type, value, NULL);
    624   }
    625   static inline string* Mutable(int number, FieldType field_type,
    626                                 ExtensionSet* set) {
    627     return set->MutableString(number, field_type, NULL);
    628   }
    629 };
    630 
    631 class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
    632  public:
    633   typedef const string& ConstType;
    634   typedef string* MutableType;
    635 
    636   static inline const string& Get(int number, const ExtensionSet& set,
    637                                   int index) {
    638     return set.GetRepeatedString(number, index);
    639   }
    640   static inline void Set(int number, int index,
    641                          const string& value, ExtensionSet* set) {
    642     set->SetRepeatedString(number, index, value);
    643   }
    644   static inline string* Mutable(int number, int index, ExtensionSet* set) {
    645     return set->MutableRepeatedString(number, index);
    646   }
    647   static inline void Add(int number, FieldType field_type,
    648                          bool /*is_packed*/, const string& value,
    649                          ExtensionSet* set) {
    650     set->AddString(number, field_type, value, NULL);
    651   }
    652   static inline string* Add(int number, FieldType field_type,
    653                             ExtensionSet* set) {
    654     return set->AddString(number, field_type, NULL);
    655   }
    656 };
    657 
    658 // -------------------------------------------------------------------
    659 // EnumTypeTraits
    660 
    661 // ExtensionSet represents enums using integers internally, so we have to
    662 // static_cast around.
    663 template <typename Type, bool IsValid(int)>
    664 class EnumTypeTraits {
    665  public:
    666   typedef Type ConstType;
    667 
    668   static inline ConstType Get(int number, const ExtensionSet& set,
    669                               ConstType default_value) {
    670     return static_cast<Type>(set.GetEnum(number, default_value));
    671   }
    672   static inline void Set(int number, FieldType field_type,
    673                          ConstType value, ExtensionSet* set) {
    674     GOOGLE_DCHECK(IsValid(value));
    675     set->SetEnum(number, field_type, value, NULL);
    676   }
    677 };
    678 
    679 template <typename Type, bool IsValid(int)>
    680 class RepeatedEnumTypeTraits {
    681  public:
    682   typedef Type ConstType;
    683 
    684   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
    685     return static_cast<Type>(set.GetRepeatedEnum(number, index));
    686   }
    687   static inline void Set(int number, int index,
    688                          ConstType value, ExtensionSet* set) {
    689     GOOGLE_DCHECK(IsValid(value));
    690     set->SetRepeatedEnum(number, index, value);
    691   }
    692   static inline void Add(int number, FieldType field_type,
    693                          bool is_packed, ConstType value, ExtensionSet* set) {
    694     GOOGLE_DCHECK(IsValid(value));
    695     set->AddEnum(number, field_type, is_packed, value, NULL);
    696   }
    697 };
    698 
    699 // -------------------------------------------------------------------
    700 // MessageTypeTraits
    701 
    702 // ExtensionSet guarantees that when manipulating extensions with message
    703 // types, the implementation used will be the compiled-in class representing
    704 // that type.  So, we can static_cast down to the exact type we expect.
    705 template <typename Type>
    706 class MessageTypeTraits {
    707  public:
    708   typedef const Type& ConstType;
    709   typedef Type* MutableType;
    710 
    711   static inline ConstType Get(int number, const ExtensionSet& set,
    712                               ConstType default_value) {
    713     return static_cast<const Type&>(
    714         set.GetMessage(number, default_value));
    715   }
    716   static inline MutableType Mutable(int number, FieldType field_type,
    717                                     ExtensionSet* set) {
    718     return static_cast<Type*>(
    719       set->MutableMessage(number, field_type, Type::default_instance(), NULL));
    720   }
    721 };
    722 
    723 template <typename Type>
    724 class RepeatedMessageTypeTraits {
    725  public:
    726   typedef const Type& ConstType;
    727   typedef Type* MutableType;
    728 
    729   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
    730     return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
    731   }
    732   static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
    733     return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
    734   }
    735   static inline MutableType Add(int number, FieldType field_type,
    736                                 ExtensionSet* set) {
    737     return static_cast<Type*>(
    738         set->AddMessage(number, field_type, Type::default_instance(), NULL));
    739   }
    740 };
    741 
    742 // -------------------------------------------------------------------
    743 // ExtensionIdentifier
    744 
    745 // This is the type of actual extension objects.  E.g. if you have:
    746 //   extends Foo with optional int32 bar = 1234;
    747 // then "bar" will be defined in C++ as:
    748 //   ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 1, false> bar(1234);
    749 //
    750 // Note that we could, in theory, supply the field number as a template
    751 // parameter, and thus make an instance of ExtensionIdentifier have no
    752 // actual contents.  However, if we did that, then using at extension
    753 // identifier would not necessarily cause the compiler to output any sort
    754 // of reference to any simple defined in the extension's .pb.o file.  Some
    755 // linkers will actually drop object files that are not explicitly referenced,
    756 // but that would be bad because it would cause this extension to not be
    757 // registered at static initialization, and therefore using it would crash.
    758 
    759 template <typename ExtendeeType, typename TypeTraitsType,
    760           FieldType field_type, bool is_packed>
    761 class ExtensionIdentifier {
    762  public:
    763   typedef TypeTraitsType TypeTraits;
    764   typedef ExtendeeType Extendee;
    765 
    766   ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
    767       : number_(number), default_value_(default_value) {}
    768   inline int number() const { return number_; }
    769   typename TypeTraits::ConstType default_value() const {
    770     return default_value_;
    771   }
    772 
    773  private:
    774   const int number_;
    775   typename TypeTraits::ConstType default_value_;
    776 };
    777 
    778 // -------------------------------------------------------------------
    779 // Generated accessors
    780 
    781 // This macro should be expanded in the context of a generated type which
    782 // has extensions.
    783 //
    784 // We use "_proto_TypeTraits" as a type name below because "TypeTraits"
    785 // causes problems if the class has a nested message or enum type with that
    786 // name and "_TypeTraits" is technically reserved for the C++ library since
    787 // it starts with an underscore followed by a capital letter.
    788 #define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME)                        \
    789   /* Has, Size, Clear */                                                      \
    790   template <typename _proto_TypeTraits,                                       \
    791             ::google::protobuf::internal::FieldType field_type,                         \
    792             bool is_packed>                                                   \
    793   inline bool HasExtension(                                                   \
    794       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    795         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const {     \
    796     return _extensions_.Has(id.number());                                     \
    797   }                                                                           \
    798                                                                               \
    799   template <typename _proto_TypeTraits,                                       \
    800             ::google::protobuf::internal::FieldType field_type,                         \
    801             bool is_packed>                                                   \
    802   inline void ClearExtension(                                                 \
    803       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    804         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) {           \
    805     _extensions_.ClearExtension(id.number());                                 \
    806   }                                                                           \
    807                                                                               \
    808   template <typename _proto_TypeTraits,                                       \
    809             ::google::protobuf::internal::FieldType field_type,                         \
    810             bool is_packed>                                                   \
    811   inline int ExtensionSize(                                                   \
    812       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    813         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const {     \
    814     return _extensions_.ExtensionSize(id.number());                           \
    815   }                                                                           \
    816                                                                               \
    817   /* Singular accessors */                                                    \
    818   template <typename _proto_TypeTraits,                                       \
    819             ::google::protobuf::internal::FieldType field_type,                         \
    820             bool is_packed>                                                   \
    821   inline typename _proto_TypeTraits::ConstType GetExtension(                  \
    822       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    823         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const {     \
    824     return _proto_TypeTraits::Get(id.number(), _extensions_,                  \
    825                                   id.default_value());                        \
    826   }                                                                           \
    827                                                                               \
    828   template <typename _proto_TypeTraits,                                       \
    829             ::google::protobuf::internal::FieldType field_type,                         \
    830             bool is_packed>                                                   \
    831   inline typename _proto_TypeTraits::MutableType MutableExtension(            \
    832       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    833         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) {           \
    834     return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\
    835   }                                                                           \
    836                                                                               \
    837   template <typename _proto_TypeTraits,                                       \
    838             ::google::protobuf::internal::FieldType field_type,                         \
    839             bool is_packed>                                                   \
    840   inline void SetExtension(                                                   \
    841       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    842         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    843       typename _proto_TypeTraits::ConstType value) {                          \
    844     _proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_);    \
    845   }                                                                           \
    846                                                                               \
    847   /* Repeated accessors */                                                    \
    848   template <typename _proto_TypeTraits,                                       \
    849             ::google::protobuf::internal::FieldType field_type,                         \
    850             bool is_packed>                                                   \
    851   inline typename _proto_TypeTraits::ConstType GetExtension(                  \
    852       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    853         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    854       int index) const {                                                      \
    855     return _proto_TypeTraits::Get(id.number(), _extensions_, index);          \
    856   }                                                                           \
    857                                                                               \
    858   template <typename _proto_TypeTraits,                                       \
    859             ::google::protobuf::internal::FieldType field_type,                         \
    860             bool is_packed>                                                   \
    861   inline typename _proto_TypeTraits::MutableType MutableExtension(            \
    862       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    863         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    864       int index) {                                                            \
    865     return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);     \
    866   }                                                                           \
    867                                                                               \
    868   template <typename _proto_TypeTraits,                                       \
    869             ::google::protobuf::internal::FieldType field_type,                         \
    870             bool is_packed>                                                   \
    871   inline void SetExtension(                                                   \
    872       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    873         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    874       int index, typename _proto_TypeTraits::ConstType value) {               \
    875     _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);         \
    876   }                                                                           \
    877                                                                               \
    878   template <typename _proto_TypeTraits,                                       \
    879             ::google::protobuf::internal::FieldType field_type,                         \
    880             bool is_packed>                                                   \
    881   inline typename _proto_TypeTraits::MutableType AddExtension(                \
    882       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    883         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) {           \
    884     return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_);    \
    885   }                                                                           \
    886                                                                               \
    887   template <typename _proto_TypeTraits,                                       \
    888             ::google::protobuf::internal::FieldType field_type,                         \
    889             bool is_packed>                                                   \
    890   inline void AddExtension(                                                   \
    891       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    892         CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id,             \
    893       typename _proto_TypeTraits::ConstType value) {                          \
    894     _proto_TypeTraits::Add(id.number(), field_type, is_packed,                \
    895                            value, &_extensions_);                             \
    896   }
    897 
    898 }  // namespace internal
    899 }  // namespace protobuf
    900 
    901 }  // namespace google
    902 #endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__
    903