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 <map>
     43 #include <utility>
     44 #include <string>
     45 
     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_param, bool isrepeated, bool ispacked)
     93       : type(type_param), is_repeated(isrepeated), is_packed(ispacked),
     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   int NumExtensions() const;  // The number of extensions
    218   FieldType ExtensionType(int number) const;
    219   void ClearExtension(int number);
    220 
    221   // singular fields -------------------------------------------------
    222 
    223   int32  GetInt32 (int number, int32  default_value) const;
    224   int64  GetInt64 (int number, int64  default_value) const;
    225   uint32 GetUInt32(int number, uint32 default_value) const;
    226   uint64 GetUInt64(int number, uint64 default_value) const;
    227   float  GetFloat (int number, float  default_value) const;
    228   double GetDouble(int number, double default_value) const;
    229   bool   GetBool  (int number, bool   default_value) const;
    230   int    GetEnum  (int number, int    default_value) const;
    231   const string & GetString (int number, const string&  default_value) const;
    232   const MessageLite& GetMessage(int number,
    233                                 const MessageLite& default_value) const;
    234   const MessageLite& GetMessage(int number, const Descriptor* message_type,
    235                                 MessageFactory* factory) const;
    236 
    237   // |descriptor| may be NULL so long as it is known that the descriptor for
    238   // the extension lives in the same pool as the descriptor for the containing
    239   // type.
    240 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
    241   void SetInt32 (int number, FieldType type, int32  value, desc);
    242   void SetInt64 (int number, FieldType type, int64  value, desc);
    243   void SetUInt32(int number, FieldType type, uint32 value, desc);
    244   void SetUInt64(int number, FieldType type, uint64 value, desc);
    245   void SetFloat (int number, FieldType type, float  value, desc);
    246   void SetDouble(int number, FieldType type, double value, desc);
    247   void SetBool  (int number, FieldType type, bool   value, desc);
    248   void SetEnum  (int number, FieldType type, int    value, desc);
    249   void SetString(int number, FieldType type, const string& value, desc);
    250   string * MutableString (int number, FieldType type, desc);
    251   MessageLite* MutableMessage(int number, FieldType type,
    252                               const MessageLite& prototype, desc);
    253   MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
    254                               MessageFactory* factory);
    255   // Adds the given message to the ExtensionSet, taking ownership of the
    256   // message object. Existing message with the same number will be deleted.
    257   // If "message" is NULL, this is equivalent to "ClearExtension(number)".
    258   void SetAllocatedMessage(int number, FieldType type,
    259                            const FieldDescriptor* descriptor,
    260                            MessageLite* message);
    261   MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
    262   MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
    263                               MessageFactory* factory);
    264 #undef desc
    265 
    266   // repeated fields -------------------------------------------------
    267 
    268   void* MutableRawRepeatedField(int number);
    269 
    270   int32  GetRepeatedInt32 (int number, int index) const;
    271   int64  GetRepeatedInt64 (int number, int index) const;
    272   uint32 GetRepeatedUInt32(int number, int index) const;
    273   uint64 GetRepeatedUInt64(int number, int index) const;
    274   float  GetRepeatedFloat (int number, int index) const;
    275   double GetRepeatedDouble(int number, int index) const;
    276   bool   GetRepeatedBool  (int number, int index) const;
    277   int    GetRepeatedEnum  (int number, int index) const;
    278   const string & GetRepeatedString (int number, int index) const;
    279   const MessageLite& GetRepeatedMessage(int number, int index) const;
    280 
    281   void SetRepeatedInt32 (int number, int index, int32  value);
    282   void SetRepeatedInt64 (int number, int index, int64  value);
    283   void SetRepeatedUInt32(int number, int index, uint32 value);
    284   void SetRepeatedUInt64(int number, int index, uint64 value);
    285   void SetRepeatedFloat (int number, int index, float  value);
    286   void SetRepeatedDouble(int number, int index, double value);
    287   void SetRepeatedBool  (int number, int index, bool   value);
    288   void SetRepeatedEnum  (int number, int index, int    value);
    289   void SetRepeatedString(int number, int index, const string& value);
    290   string * MutableRepeatedString (int number, int index);
    291   MessageLite* MutableRepeatedMessage(int number, int index);
    292 
    293 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
    294   void AddInt32 (int number, FieldType type, bool packed, int32  value, desc);
    295   void AddInt64 (int number, FieldType type, bool packed, int64  value, desc);
    296   void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
    297   void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
    298   void AddFloat (int number, FieldType type, bool packed, float  value, desc);
    299   void AddDouble(int number, FieldType type, bool packed, double value, desc);
    300   void AddBool  (int number, FieldType type, bool packed, bool   value, desc);
    301   void AddEnum  (int number, FieldType type, bool packed, int    value, desc);
    302   void AddString(int number, FieldType type, const string& value, desc);
    303   string * AddString (int number, FieldType type, desc);
    304   MessageLite* AddMessage(int number, FieldType type,
    305                           const MessageLite& prototype, desc);
    306   MessageLite* AddMessage(const FieldDescriptor* descriptor,
    307                           MessageFactory* factory);
    308 #undef desc
    309 
    310   void RemoveLast(int number);
    311   MessageLite* ReleaseLast(int number);
    312   void SwapElements(int number, int index1, int index2);
    313 
    314   // -----------------------------------------------------------------
    315   // TODO(kenton):  Hardcore memory management accessors
    316 
    317   // =================================================================
    318   // convenience methods for implementing methods of Message
    319   //
    320   // These could all be implemented in terms of the other methods of this
    321   // class, but providing them here helps keep the generated code size down.
    322 
    323   void Clear();
    324   void MergeFrom(const ExtensionSet& other);
    325   void Swap(ExtensionSet* other);
    326   bool IsInitialized() const;
    327 
    328   // Parses a single extension from the input. The input should start out
    329   // positioned immediately after the tag.
    330   bool ParseField(uint32 tag, io::CodedInputStream* input,
    331                   ExtensionFinder* extension_finder,
    332                   FieldSkipper* field_skipper);
    333 
    334   // Specific versions for lite or full messages (constructs the appropriate
    335   // FieldSkipper automatically).  |containing_type| is the default
    336   // instance for the containing message; it is used only to look up the
    337   // extension by number.  See RegisterExtension(), above.  Unlike the other
    338   // methods of ExtensionSet, this only works for generated message types --
    339   // it looks up extensions registered using RegisterExtension().
    340   bool ParseField(uint32 tag, io::CodedInputStream* input,
    341                   const MessageLite* containing_type,
    342                   UnknownFieldSet* unknown_fields);
    343   bool ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
    344                        const Message* containing_type,
    345                        UnknownFieldSet* unknown_fields);
    346 
    347   // Parse an entire message in MessageSet format.  Such messages have no
    348   // fields, only extensions.
    349   bool ParseMessageSet(io::CodedInputStream* input,
    350                        ExtensionFinder* extension_finder,
    351                        FieldSkipper* field_skipper);
    352 
    353   // Specific versions for lite or full messages (constructs the appropriate
    354   // FieldSkipper automatically).
    355   bool ParseMessageSet(io::CodedInputStream* input,
    356                        const MessageLite* containing_type,
    357                        UnknownFieldSet* unknown_fields);
    358   bool ParseMessageSetHeavy(io::CodedInputStream* input,
    359                             const Message* containing_type,
    360                             UnknownFieldSet* unknown_fields);
    361 
    362   // Write all extension fields with field numbers in the range
    363   //   [start_field_number, end_field_number)
    364   // to the output stream, using the cached sizes computed when ByteSize() was
    365   // last called.  Note that the range bounds are inclusive-exclusive.
    366   void SerializeWithCachedSizes(int start_field_number,
    367                                 int end_field_number,
    368                                 io::CodedOutputStream* output) const;
    369 
    370   // Same as SerializeWithCachedSizes, but without any bounds checking.
    371   // The caller must ensure that target has sufficient capacity for the
    372   // serialized extensions.
    373   //
    374   // Returns a pointer past the last written byte.
    375   uint8* SerializeWithCachedSizesToArray(int start_field_number,
    376                                          int end_field_number,
    377                                          uint8* target) const;
    378 
    379   // Like above but serializes in MessageSet format.
    380   void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
    381   uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
    382 
    383   // Returns the total serialized size of all the extensions.
    384   int ByteSize() const;
    385 
    386   // Like ByteSize() but uses MessageSet format.
    387   int MessageSetByteSize() const;
    388 
    389   // Returns (an estimate of) the total number of bytes used for storing the
    390   // extensions in memory, excluding sizeof(*this).  If the ExtensionSet is
    391   // for a lite message (and thus possibly contains lite messages), the results
    392   // are undefined (might work, might crash, might corrupt data, might not even
    393   // be linked in).  It's up to the protocol compiler to avoid calling this on
    394   // such ExtensionSets (easy enough since lite messages don't implement
    395   // SpaceUsed()).
    396   int SpaceUsedExcludingSelf() const;
    397 
    398  private:
    399 
    400   // Interface of a lazily parsed singular message extension.
    401   class LIBPROTOBUF_EXPORT LazyMessageExtension {
    402    public:
    403     LazyMessageExtension() {}
    404     virtual ~LazyMessageExtension() {}
    405 
    406     virtual LazyMessageExtension* New() const = 0;
    407     virtual const MessageLite& GetMessage(
    408         const MessageLite& prototype) const = 0;
    409     virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
    410     virtual void SetAllocatedMessage(MessageLite *message) = 0;
    411     virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0;
    412 
    413     virtual bool IsInitialized() const = 0;
    414     virtual int ByteSize() const = 0;
    415     virtual int SpaceUsed() const = 0;
    416 
    417     virtual void MergeFrom(const LazyMessageExtension& other) = 0;
    418     virtual void Clear() = 0;
    419 
    420     virtual bool ReadMessage(const MessageLite& prototype,
    421                              io::CodedInputStream* input) = 0;
    422     virtual void WriteMessage(int number,
    423                               io::CodedOutputStream* output) const = 0;
    424     virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
    425    private:
    426     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
    427   };
    428   struct Extension {
    429     // The order of these fields packs Extension into 24 bytes when using 8
    430     // byte alignment. Consider this when adding or removing fields here.
    431     union {
    432       int32                 int32_value;
    433       int64                 int64_value;
    434       uint32                uint32_value;
    435       uint64                uint64_value;
    436       float                 float_value;
    437       double                double_value;
    438       bool                  bool_value;
    439       int                   enum_value;
    440       string*               string_value;
    441       MessageLite*          message_value;
    442       LazyMessageExtension* lazymessage_value;
    443 
    444       RepeatedField   <int32      >* repeated_int32_value;
    445       RepeatedField   <int64      >* repeated_int64_value;
    446       RepeatedField   <uint32     >* repeated_uint32_value;
    447       RepeatedField   <uint64     >* repeated_uint64_value;
    448       RepeatedField   <float      >* repeated_float_value;
    449       RepeatedField   <double     >* repeated_double_value;
    450       RepeatedField   <bool       >* repeated_bool_value;
    451       RepeatedField   <int        >* repeated_enum_value;
    452       RepeatedPtrField<string     >* repeated_string_value;
    453       RepeatedPtrField<MessageLite>* repeated_message_value;
    454     };
    455 
    456     FieldType type;
    457     bool is_repeated;
    458 
    459     // For singular types, indicates if the extension is "cleared".  This
    460     // happens when an extension is set and then later cleared by the caller.
    461     // We want to keep the Extension object around for reuse, so instead of
    462     // removing it from the map, we just set is_cleared = true.  This has no
    463     // meaning for repeated types; for those, the size of the RepeatedField
    464     // simply becomes zero when cleared.
    465     bool is_cleared : 4;
    466 
    467     // For singular message types, indicates whether lazy parsing is enabled
    468     // for this extension. This field is only valid when type == TYPE_MESSAGE
    469     // and !is_repeated because we only support lazy parsing for singular
    470     // message types currently. If is_lazy = true, the extension is stored in
    471     // lazymessage_value. Otherwise, the extension will be message_value.
    472     bool is_lazy : 4;
    473 
    474     // For repeated types, this indicates if the [packed=true] option is set.
    475     bool is_packed;
    476 
    477     // For packed fields, the size of the packed data is recorded here when
    478     // ByteSize() is called then used during serialization.
    479     // TODO(kenton):  Use atomic<int> when C++ supports it.
    480     mutable int cached_size;
    481 
    482     // The descriptor for this extension, if one exists and is known.  May be
    483     // NULL.  Must not be NULL if the descriptor for the extension does not
    484     // live in the same pool as the descriptor for the containing type.
    485     const FieldDescriptor* descriptor;
    486 
    487     // Some helper methods for operations on a single Extension.
    488     void SerializeFieldWithCachedSizes(
    489         int number,
    490         io::CodedOutputStream* output) const;
    491     uint8* SerializeFieldWithCachedSizesToArray(
    492         int number,
    493         uint8* target) const;
    494     void SerializeMessageSetItemWithCachedSizes(
    495         int number,
    496         io::CodedOutputStream* output) const;
    497     uint8* SerializeMessageSetItemWithCachedSizesToArray(
    498         int number,
    499         uint8* target) const;
    500     int ByteSize(int number) const;
    501     int MessageSetItemByteSize(int number) const;
    502     void Clear();
    503     int GetSize() const;
    504     void Free();
    505     int SpaceUsedExcludingSelf() const;
    506   };
    507 
    508 
    509   // Returns true and fills field_number and extension if extension is found.
    510   bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder,
    511                                 int* field_number, ExtensionInfo* extension);
    512 
    513   // Parses a single extension from the input. The input should start out
    514   // positioned immediately after the wire tag. This method is called in
    515   // ParseField() after field number is extracted from the wire tag and
    516   // ExtensionInfo is found by the field number.
    517   bool ParseFieldWithExtensionInfo(int field_number,
    518                                    const ExtensionInfo& extension,
    519                                    io::CodedInputStream* input,
    520                                    FieldSkipper* field_skipper);
    521 
    522   // Like ParseField(), but this method may parse singular message extensions
    523   // lazily depending on the value of FLAGS_eagerly_parse_message_sets.
    524   bool ParseFieldMaybeLazily(uint32 tag, io::CodedInputStream* input,
    525                              ExtensionFinder* extension_finder,
    526                              FieldSkipper* field_skipper);
    527 
    528   // Gets the extension with the given number, creating it if it does not
    529   // already exist.  Returns true if the extension did not already exist.
    530   bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
    531                          Extension** result);
    532 
    533   // Parse a single MessageSet item -- called just after the item group start
    534   // tag has been read.
    535   bool ParseMessageSetItem(io::CodedInputStream* input,
    536                            ExtensionFinder* extension_finder,
    537                            FieldSkipper* field_skipper);
    538 
    539 
    540   // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
    541   //   friendship should automatically extend to ExtensionSet::Extension, but
    542   //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
    543   //   correctly.  So, we must provide helpers for calling methods of that
    544   //   class.
    545 
    546   // Defined in extension_set_heavy.cc.
    547   static inline int RepeatedMessage_SpaceUsedExcludingSelf(
    548       RepeatedPtrFieldBase* field);
    549 
    550   // The Extension struct is small enough to be passed by value, so we use it
    551   // directly as the value type in the map rather than use pointers.  We use
    552   // a map rather than hash_map here because we expect most ExtensionSets will
    553   // only contain a small number of extensions whereas hash_map is optimized
    554   // for 100 elements or more.  Also, we want AppendToList() to order fields
    555   // by field number.
    556   std::map<int, Extension> extensions_;
    557 
    558   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
    559 };
    560 
    561 // These are just for convenience...
    562 inline void ExtensionSet::SetString(int number, FieldType type,
    563                                     const string& value,
    564                                     const FieldDescriptor* descriptor) {
    565   MutableString(number, type, descriptor)->assign(value);
    566 }
    567 inline void ExtensionSet::SetRepeatedString(int number, int index,
    568                                             const string& value) {
    569   MutableRepeatedString(number, index)->assign(value);
    570 }
    571 inline void ExtensionSet::AddString(int number, FieldType type,
    572                                     const string& value,
    573                                     const FieldDescriptor* descriptor) {
    574   AddString(number, type, descriptor)->assign(value);
    575 }
    576 
    577 // ===================================================================
    578 // Glue for generated extension accessors
    579 
    580 // -------------------------------------------------------------------
    581 // Template magic
    582 
    583 // First we have a set of classes representing "type traits" for different
    584 // field types.  A type traits class knows how to implement basic accessors
    585 // for extensions of a particular type given an ExtensionSet.  The signature
    586 // for a type traits class looks like this:
    587 //
    588 //   class TypeTraits {
    589 //    public:
    590 //     typedef ? ConstType;
    591 //     typedef ? MutableType;
    592 //
    593 //     static inline ConstType Get(int number, const ExtensionSet& set);
    594 //     static inline void Set(int number, ConstType value, ExtensionSet* set);
    595 //     static inline MutableType Mutable(int number, ExtensionSet* set);
    596 //
    597 //     // Variants for repeated fields.
    598 //     static inline ConstType Get(int number, const ExtensionSet& set,
    599 //                                 int index);
    600 //     static inline void Set(int number, int index,
    601 //                            ConstType value, ExtensionSet* set);
    602 //     static inline MutableType Mutable(int number, int index,
    603 //                                       ExtensionSet* set);
    604 //     static inline void Add(int number, ConstType value, ExtensionSet* set);
    605 //     static inline MutableType Add(int number, ExtensionSet* set);
    606 //   };
    607 //
    608 // Not all of these methods make sense for all field types.  For example, the
    609 // "Mutable" methods only make sense for strings and messages, and the
    610 // repeated methods only make sense for repeated types.  So, each type
    611 // traits class implements only the set of methods from this signature that it
    612 // actually supports.  This will cause a compiler error if the user tries to
    613 // access an extension using a method that doesn't make sense for its type.
    614 // For example, if "foo" is an extension of type "optional int32", then if you
    615 // try to write code like:
    616 //   my_message.MutableExtension(foo)
    617 // you will get a compile error because PrimitiveTypeTraits<int32> does not
    618 // have a "Mutable()" method.
    619 
    620 // -------------------------------------------------------------------
    621 // PrimitiveTypeTraits
    622 
    623 // Since the ExtensionSet has different methods for each primitive type,
    624 // we must explicitly define the methods of the type traits class for each
    625 // known type.
    626 template <typename Type>
    627 class PrimitiveTypeTraits {
    628  public:
    629   typedef Type ConstType;
    630 
    631   static inline ConstType Get(int number, const ExtensionSet& set,
    632                               ConstType default_value);
    633   static inline void Set(int number, FieldType field_type,
    634                          ConstType value, ExtensionSet* set);
    635 };
    636 
    637 template <typename Type>
    638 class RepeatedPrimitiveTypeTraits {
    639  public:
    640   typedef Type ConstType;
    641 
    642   static inline Type Get(int number, const ExtensionSet& set, int index);
    643   static inline void Set(int number, int index, Type value, ExtensionSet* set);
    644   static inline void Add(int number, FieldType field_type,
    645                          bool is_packed, Type value, ExtensionSet* set);
    646 };
    647 
    648 #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
    649 template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get(                     \
    650     int number, const ExtensionSet& set, TYPE default_value) {             \
    651   return set.Get##METHOD(number, default_value);                           \
    652 }                                                                          \
    653 template<> inline void PrimitiveTypeTraits<TYPE>::Set(                     \
    654     int number, FieldType field_type, TYPE value, ExtensionSet* set) {     \
    655   set->Set##METHOD(number, field_type, value, NULL);                       \
    656 }                                                                          \
    657                                                                            \
    658 template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(             \
    659     int number, const ExtensionSet& set, int index) {                      \
    660   return set.GetRepeated##METHOD(number, index);                           \
    661 }                                                                          \
    662 template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(             \
    663     int number, int index, TYPE value, ExtensionSet* set) {                \
    664   set->SetRepeated##METHOD(number, index, value);                          \
    665 }                                                                          \
    666 template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(             \
    667     int number, FieldType field_type, bool is_packed,                      \
    668     TYPE value, ExtensionSet* set) {                                       \
    669   set->Add##METHOD(number, field_type, is_packed, value, NULL);            \
    670 }
    671 
    672 PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32,  Int32)
    673 PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64,  Int64)
    674 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
    675 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
    676 PROTOBUF_DEFINE_PRIMITIVE_TYPE( float,  Float)
    677 PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
    678 PROTOBUF_DEFINE_PRIMITIVE_TYPE(  bool,   Bool)
    679 
    680 #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
    681 
    682 // -------------------------------------------------------------------
    683 // StringTypeTraits
    684 
    685 // Strings support both Set() and Mutable().
    686 class LIBPROTOBUF_EXPORT StringTypeTraits {
    687  public:
    688   typedef const string& ConstType;
    689   typedef string* MutableType;
    690 
    691   static inline const string& Get(int number, const ExtensionSet& set,
    692                                   ConstType default_value) {
    693     return set.GetString(number, default_value);
    694   }
    695   static inline void Set(int number, FieldType field_type,
    696                          const string& value, ExtensionSet* set) {
    697     set->SetString(number, field_type, value, NULL);
    698   }
    699   static inline string* Mutable(int number, FieldType field_type,
    700                                 ExtensionSet* set) {
    701     return set->MutableString(number, field_type, NULL);
    702   }
    703 };
    704 
    705 class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
    706  public:
    707   typedef const string& ConstType;
    708   typedef string* MutableType;
    709 
    710   static inline const string& Get(int number, const ExtensionSet& set,
    711                                   int index) {
    712     return set.GetRepeatedString(number, index);
    713   }
    714   static inline void Set(int number, int index,
    715                          const string& value, ExtensionSet* set) {
    716     set->SetRepeatedString(number, index, value);
    717   }
    718   static inline string* Mutable(int number, int index, ExtensionSet* set) {
    719     return set->MutableRepeatedString(number, index);
    720   }
    721   static inline void Add(int number, FieldType field_type,
    722                          bool /*is_packed*/, const string& value,
    723                          ExtensionSet* set) {
    724     set->AddString(number, field_type, value, NULL);
    725   }
    726   static inline string* Add(int number, FieldType field_type,
    727                             ExtensionSet* set) {
    728     return set->AddString(number, field_type, NULL);
    729   }
    730 };
    731 
    732 // -------------------------------------------------------------------
    733 // EnumTypeTraits
    734 
    735 // ExtensionSet represents enums using integers internally, so we have to
    736 // static_cast around.
    737 template <typename Type, bool IsValid(int)>
    738 class EnumTypeTraits {
    739  public:
    740   typedef Type ConstType;
    741 
    742   static inline ConstType Get(int number, const ExtensionSet& set,
    743                               ConstType default_value) {
    744     return static_cast<Type>(set.GetEnum(number, default_value));
    745   }
    746   static inline void Set(int number, FieldType field_type,
    747                          ConstType value, ExtensionSet* set) {
    748     GOOGLE_DCHECK(IsValid(value));
    749     set->SetEnum(number, field_type, value, NULL);
    750   }
    751 };
    752 
    753 template <typename Type, bool IsValid(int)>
    754 class RepeatedEnumTypeTraits {
    755  public:
    756   typedef Type ConstType;
    757 
    758   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
    759     return static_cast<Type>(set.GetRepeatedEnum(number, index));
    760   }
    761   static inline void Set(int number, int index,
    762                          ConstType value, ExtensionSet* set) {
    763     GOOGLE_DCHECK(IsValid(value));
    764     set->SetRepeatedEnum(number, index, value);
    765   }
    766   static inline void Add(int number, FieldType field_type,
    767                          bool is_packed, ConstType value, ExtensionSet* set) {
    768     GOOGLE_DCHECK(IsValid(value));
    769     set->AddEnum(number, field_type, is_packed, value, NULL);
    770   }
    771 };
    772 
    773 // -------------------------------------------------------------------
    774 // MessageTypeTraits
    775 
    776 // ExtensionSet guarantees that when manipulating extensions with message
    777 // types, the implementation used will be the compiled-in class representing
    778 // that type.  So, we can static_cast down to the exact type we expect.
    779 template <typename Type>
    780 class MessageTypeTraits {
    781  public:
    782   typedef const Type& ConstType;
    783   typedef Type* MutableType;
    784 
    785   static inline ConstType Get(int number, const ExtensionSet& set,
    786                               ConstType default_value) {
    787     return static_cast<const Type&>(
    788         set.GetMessage(number, default_value));
    789   }
    790   static inline MutableType Mutable(int number, FieldType field_type,
    791                                     ExtensionSet* set) {
    792     return static_cast<Type*>(
    793       set->MutableMessage(number, field_type, Type::default_instance(), NULL));
    794   }
    795   static inline void SetAllocated(int number, FieldType field_type,
    796                                   MutableType message, ExtensionSet* set) {
    797     set->SetAllocatedMessage(number, field_type, NULL, message);
    798   }
    799   static inline MutableType Release(int number, FieldType field_type,
    800                                     ExtensionSet* set) {
    801     return static_cast<Type*>(set->ReleaseMessage(
    802         number, Type::default_instance()));
    803   }
    804 };
    805 
    806 template <typename Type>
    807 class RepeatedMessageTypeTraits {
    808  public:
    809   typedef const Type& ConstType;
    810   typedef Type* MutableType;
    811 
    812   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
    813     return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
    814   }
    815   static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
    816     return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
    817   }
    818   static inline MutableType Add(int number, FieldType field_type,
    819                                 ExtensionSet* set) {
    820     return static_cast<Type*>(
    821         set->AddMessage(number, field_type, Type::default_instance(), NULL));
    822   }
    823 };
    824 
    825 // -------------------------------------------------------------------
    826 // ExtensionIdentifier
    827 
    828 // This is the type of actual extension objects.  E.g. if you have:
    829 //   extends Foo with optional int32 bar = 1234;
    830 // then "bar" will be defined in C++ as:
    831 //   ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 1, false> bar(1234);
    832 //
    833 // Note that we could, in theory, supply the field number as a template
    834 // parameter, and thus make an instance of ExtensionIdentifier have no
    835 // actual contents.  However, if we did that, then using at extension
    836 // identifier would not necessarily cause the compiler to output any sort
    837 // of reference to any simple defined in the extension's .pb.o file.  Some
    838 // linkers will actually drop object files that are not explicitly referenced,
    839 // but that would be bad because it would cause this extension to not be
    840 // registered at static initialization, and therefore using it would crash.
    841 
    842 template <typename ExtendeeType, typename TypeTraitsType,
    843           FieldType field_type, bool is_packed>
    844 class ExtensionIdentifier {
    845  public:
    846   typedef TypeTraitsType TypeTraits;
    847   typedef ExtendeeType Extendee;
    848 
    849   ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
    850       : number_(number), default_value_(default_value) {}
    851   inline int number() const { return number_; }
    852   typename TypeTraits::ConstType default_value() const {
    853     return default_value_;
    854   }
    855 
    856  private:
    857   const int number_;
    858   typename TypeTraits::ConstType default_value_;
    859 };
    860 
    861 // -------------------------------------------------------------------
    862 // Generated accessors
    863 
    864 // This macro should be expanded in the context of a generated type which
    865 // has extensions.
    866 //
    867 // We use "_proto_TypeTraits" as a type name below because "TypeTraits"
    868 // causes problems if the class has a nested message or enum type with that
    869 // name and "_TypeTraits" is technically reserved for the C++ library since
    870 // it starts with an underscore followed by a capital letter.
    871 //
    872 // For similar reason, we use "_field_type" and "_is_packed" as parameter names
    873 // below, so that "field_type" and "is_packed" can be used as field names.
    874 #define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME)                        \
    875   /* Has, Size, Clear */                                                      \
    876   template <typename _proto_TypeTraits,                                       \
    877             ::google::protobuf::internal::FieldType _field_type,                        \
    878             bool _is_packed>                                                  \
    879   inline bool HasExtension(                                                   \
    880       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    881         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
    882     return _extensions_.Has(id.number());                                     \
    883   }                                                                           \
    884                                                                               \
    885   template <typename _proto_TypeTraits,                                       \
    886             ::google::protobuf::internal::FieldType _field_type,                        \
    887             bool _is_packed>                                                  \
    888   inline void ClearExtension(                                                 \
    889       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    890         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    891     _extensions_.ClearExtension(id.number());                                 \
    892   }                                                                           \
    893                                                                               \
    894   template <typename _proto_TypeTraits,                                       \
    895             ::google::protobuf::internal::FieldType _field_type,                        \
    896             bool _is_packed>                                                  \
    897   inline int ExtensionSize(                                                   \
    898       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    899         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
    900     return _extensions_.ExtensionSize(id.number());                           \
    901   }                                                                           \
    902                                                                               \
    903   /* Singular accessors */                                                    \
    904   template <typename _proto_TypeTraits,                                       \
    905             ::google::protobuf::internal::FieldType _field_type,                        \
    906             bool _is_packed>                                                  \
    907   inline typename _proto_TypeTraits::ConstType GetExtension(                  \
    908       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    909         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
    910     return _proto_TypeTraits::Get(id.number(), _extensions_,                  \
    911                                   id.default_value());                        \
    912   }                                                                           \
    913                                                                               \
    914   template <typename _proto_TypeTraits,                                       \
    915             ::google::protobuf::internal::FieldType _field_type,                        \
    916             bool _is_packed>                                                  \
    917   inline typename _proto_TypeTraits::MutableType MutableExtension(            \
    918       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    919         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    920     return _proto_TypeTraits::Mutable(id.number(), _field_type,               \
    921                                       &_extensions_);                         \
    922   }                                                                           \
    923                                                                               \
    924   template <typename _proto_TypeTraits,                                       \
    925             ::google::protobuf::internal::FieldType _field_type,                        \
    926             bool _is_packed>                                                  \
    927   inline void SetExtension(                                                   \
    928       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    929         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    930       typename _proto_TypeTraits::ConstType value) {                          \
    931     _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);   \
    932   }                                                                           \
    933                                                                               \
    934   template <typename _proto_TypeTraits,                                       \
    935             ::google::protobuf::internal::FieldType _field_type,                        \
    936             bool _is_packed>                                                  \
    937   inline void SetAllocatedExtension(                                          \
    938       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    939         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    940       typename _proto_TypeTraits::MutableType value) {                        \
    941     _proto_TypeTraits::SetAllocated(id.number(), _field_type,                 \
    942                                     value, &_extensions_);                    \
    943   }                                                                           \
    944   template <typename _proto_TypeTraits,                                       \
    945             ::google::protobuf::internal::FieldType _field_type,                        \
    946             bool _is_packed>                                                  \
    947   inline typename _proto_TypeTraits::MutableType ReleaseExtension(            \
    948       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    949         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    950     return _proto_TypeTraits::Release(id.number(), _field_type,               \
    951                                       &_extensions_);                         \
    952   }                                                                           \
    953                                                                               \
    954   /* Repeated accessors */                                                    \
    955   template <typename _proto_TypeTraits,                                       \
    956             ::google::protobuf::internal::FieldType _field_type,                        \
    957             bool _is_packed>                                                  \
    958   inline typename _proto_TypeTraits::ConstType GetExtension(                  \
    959       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    960         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    961       int index) const {                                                      \
    962     return _proto_TypeTraits::Get(id.number(), _extensions_, index);          \
    963   }                                                                           \
    964                                                                               \
    965   template <typename _proto_TypeTraits,                                       \
    966             ::google::protobuf::internal::FieldType _field_type,                        \
    967             bool _is_packed>                                                  \
    968   inline typename _proto_TypeTraits::MutableType MutableExtension(            \
    969       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    970         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    971       int index) {                                                            \
    972     return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);     \
    973   }                                                                           \
    974                                                                               \
    975   template <typename _proto_TypeTraits,                                       \
    976             ::google::protobuf::internal::FieldType _field_type,                        \
    977             bool _is_packed>                                                  \
    978   inline void SetExtension(                                                   \
    979       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    980         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    981       int index, typename _proto_TypeTraits::ConstType value) {               \
    982     _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);         \
    983   }                                                                           \
    984                                                                               \
    985   template <typename _proto_TypeTraits,                                       \
    986             ::google::protobuf::internal::FieldType _field_type,                        \
    987             bool _is_packed>                                                  \
    988   inline typename _proto_TypeTraits::MutableType AddExtension(                \
    989       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    990         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    991     return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);   \
    992   }                                                                           \
    993                                                                               \
    994   template <typename _proto_TypeTraits,                                       \
    995             ::google::protobuf::internal::FieldType _field_type,                        \
    996             bool _is_packed>                                                  \
    997   inline void AddExtension(                                                   \
    998       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    999         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
   1000       typename _proto_TypeTraits::ConstType value) {                          \
   1001     _proto_TypeTraits::Add(id.number(), _field_type, _is_packed,              \
   1002                            value, &_extensions_);                             \
   1003   }
   1004 
   1005 }  // namespace internal
   1006 }  // namespace protobuf
   1007 
   1008 }  // namespace google
   1009 #endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__
   1010