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