LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - extension_set.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 3 8 37.5 %
Date: 2015-10-10 Functions: 0 4 0.0 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       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@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             : #include <google/protobuf/stubs/logging.h>
      49             : 
      50             : #include <google/protobuf/repeated_field.h>
      51             : 
      52             : namespace google {
      53             : 
      54             : namespace protobuf {
      55             :   class Arena;
      56             :   class Descriptor;                                    // descriptor.h
      57             :   class FieldDescriptor;                               // descriptor.h
      58             :   class DescriptorPool;                                // descriptor.h
      59             :   class MessageLite;                                   // message_lite.h
      60             :   class Message;                                       // message.h
      61             :   class MessageFactory;                                // message.h
      62             :   class UnknownFieldSet;                               // unknown_field_set.h
      63             :   namespace io {
      64             :     class CodedInputStream;                              // coded_stream.h
      65             :     class CodedOutputStream;                             // coded_stream.h
      66             :   }
      67             :   namespace internal {
      68             :     class FieldSkipper;                                  // wire_format_lite.h
      69             :   }
      70             : }
      71             : 
      72             : namespace protobuf {
      73             : namespace internal {
      74             : 
      75             : // Used to store values of type WireFormatLite::FieldType without having to
      76             : // #include wire_format_lite.h.  Also, ensures that we use only one byte to
      77             : // store these values, which is important to keep the layout of
      78             : // ExtensionSet::Extension small.
      79             : typedef uint8 FieldType;
      80             : 
      81             : // A function which, given an integer value, returns true if the number
      82             : // matches one of the defined values for the corresponding enum type.  This
      83             : // is used with RegisterEnumExtension, below.
      84             : typedef bool EnumValidityFunc(int number);
      85             : 
      86             : // Version of the above which takes an argument.  This is needed to deal with
      87             : // extensions that are not compiled in.
      88             : typedef bool EnumValidityFuncWithArg(const void* arg, int number);
      89             : 
      90             : // Information about a registered extension.
      91             : struct ExtensionInfo {
      92             :   inline ExtensionInfo() {}
      93             :   inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked)
      94             :       : type(type_param), is_repeated(isrepeated), is_packed(ispacked),
      95           0 :         descriptor(NULL) {}
      96             : 
      97             :   FieldType type;
      98             :   bool is_repeated;
      99             :   bool is_packed;
     100             : 
     101             :   struct EnumValidityCheck {
     102             :     EnumValidityFuncWithArg* func;
     103             :     const void* arg;
     104             :   };
     105             : 
     106             :   union {
     107             :     EnumValidityCheck enum_validity_check;
     108             :     const MessageLite* message_prototype;
     109             :   };
     110             : 
     111             :   // The descriptor for this extension, if one exists and is known.  May be
     112             :   // NULL.  Must not be NULL if the descriptor for the extension does not
     113             :   // live in the same pool as the descriptor for the containing type.
     114             :   const FieldDescriptor* descriptor;
     115             : };
     116             : 
     117             : // Abstract interface for an object which looks up extension definitions.  Used
     118             : // when parsing.
     119          71 : class LIBPROTOBUF_EXPORT ExtensionFinder {
     120             :  public:
     121             :   virtual ~ExtensionFinder();
     122             : 
     123             :   // Find the extension with the given containing type and number.
     124             :   virtual bool Find(int number, ExtensionInfo* output) = 0;
     125             : };
     126             : 
     127             : // Implementation of ExtensionFinder which finds extensions defined in .proto
     128             : // files which have been compiled into the binary.
     129             : class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
     130             :  public:
     131             :   GeneratedExtensionFinder(const MessageLite* containing_type)
     132         142 :       : containing_type_(containing_type) {}
     133          71 :   virtual ~GeneratedExtensionFinder() {}
     134             : 
     135             :   // Returns true and fills in *output if found, otherwise returns false.
     136             :   virtual bool Find(int number, ExtensionInfo* output);
     137             : 
     138             :  private:
     139             :   const MessageLite* containing_type_;
     140             : };
     141             : 
     142             : // A FieldSkipper used for parsing MessageSet.
     143             : class MessageSetFieldSkipper;
     144             : 
     145             : // Note:  extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
     146             : // finding extensions from a DescriptorPool.
     147             : 
     148             : // This is an internal helper class intended for use within the protocol buffer
     149             : // library and generated classes.  Clients should not use it directly.  Instead,
     150             : // use the generated accessors such as GetExtension() of the class being
     151             : // extended.
     152             : //
     153             : // This class manages extensions for a protocol message object.  The
     154             : // message's HasExtension(), GetExtension(), MutableExtension(), and
     155             : // ClearExtension() methods are just thin wrappers around the embedded
     156             : // ExtensionSet.  When parsing, if a tag number is encountered which is
     157             : // inside one of the message type's extension ranges, the tag is passed
     158             : // off to the ExtensionSet for parsing.  Etc.
     159             : class LIBPROTOBUF_EXPORT ExtensionSet {
     160             :  public:
     161             :   ExtensionSet();
     162             :   explicit ExtensionSet(::google::protobuf::Arena* arena);
     163             :   ~ExtensionSet();
     164             : 
     165             :   // These are called at startup by protocol-compiler-generated code to
     166             :   // register known extensions.  The registrations are used by ParseField()
     167             :   // to look up extensions for parsed field numbers.  Note that dynamic parsing
     168             :   // does not use ParseField(); only protocol-compiler-generated parsing
     169             :   // methods do.
     170             :   static void RegisterExtension(const MessageLite* containing_type,
     171             :                                 int number, FieldType type,
     172             :                                 bool is_repeated, bool is_packed);
     173             :   static void RegisterEnumExtension(const MessageLite* containing_type,
     174             :                                     int number, FieldType type,
     175             :                                     bool is_repeated, bool is_packed,
     176             :                                     EnumValidityFunc* is_valid);
     177             :   static void RegisterMessageExtension(const MessageLite* containing_type,
     178             :                                        int number, FieldType type,
     179             :                                        bool is_repeated, bool is_packed,
     180             :                                        const MessageLite* prototype);
     181             : 
     182             :   // =================================================================
     183             : 
     184             :   // Add all fields which are currently present to the given vector.  This
     185             :   // is useful to implement Reflection::ListFields().
     186             :   void AppendToList(const Descriptor* containing_type,
     187             :                     const DescriptorPool* pool,
     188             :                     std::vector<const FieldDescriptor*>* output) const;
     189             : 
     190             :   // =================================================================
     191             :   // Accessors
     192             :   //
     193             :   // Generated message classes include type-safe templated wrappers around
     194             :   // these methods.  Generally you should use those rather than call these
     195             :   // directly, unless you are doing low-level memory management.
     196             :   //
     197             :   // When calling any of these accessors, the extension number requested
     198             :   // MUST exist in the DescriptorPool provided to the constructor.  Otherwise,
     199             :   // the method will fail an assert.  Normally, though, you would not call
     200             :   // these directly; you would either call the generated accessors of your
     201             :   // message class (e.g. GetExtension()) or you would call the accessors
     202             :   // of the reflection interface.  In both cases, it is impossible to
     203             :   // trigger this assert failure:  the generated accessors only accept
     204             :   // linked-in extension types as parameters, while the Reflection interface
     205             :   // requires you to provide the FieldDescriptor describing the extension.
     206             :   //
     207             :   // When calling any of these accessors, a protocol-compiler-generated
     208             :   // implementation of the extension corresponding to the number MUST
     209             :   // be linked in, and the FieldDescriptor used to refer to it MUST be
     210             :   // the one generated by that linked-in code.  Otherwise, the method will
     211             :   // die on an assert failure.  The message objects returned by the message
     212             :   // accessors are guaranteed to be of the correct linked-in type.
     213             :   //
     214             :   // These methods pretty much match Reflection except that:
     215             :   // - They're not virtual.
     216             :   // - They identify fields by number rather than FieldDescriptors.
     217             :   // - They identify enum values using integers rather than descriptors.
     218             :   // - Strings provide Mutable() in addition to Set() accessors.
     219             : 
     220             :   bool Has(int number) const;
     221             :   int ExtensionSize(int number) const;   // Size of a repeated extension.
     222             :   int NumExtensions() const;  // The number of extensions
     223             :   FieldType ExtensionType(int number) const;
     224             :   void ClearExtension(int number);
     225             : 
     226             :   // singular fields -------------------------------------------------
     227             : 
     228             :   int32  GetInt32 (int number, int32  default_value) const;
     229             :   int64  GetInt64 (int number, int64  default_value) const;
     230             :   uint32 GetUInt32(int number, uint32 default_value) const;
     231             :   uint64 GetUInt64(int number, uint64 default_value) const;
     232             :   float  GetFloat (int number, float  default_value) const;
     233             :   double GetDouble(int number, double default_value) const;
     234             :   bool   GetBool  (int number, bool   default_value) const;
     235             :   int    GetEnum  (int number, int    default_value) const;
     236             :   const string & GetString (int number, const string&  default_value) const;
     237             :   const MessageLite& GetMessage(int number,
     238             :                                 const MessageLite& default_value) const;
     239             :   const MessageLite& GetMessage(int number, const Descriptor* message_type,
     240             :                                 MessageFactory* factory) const;
     241             : 
     242             :   // |descriptor| may be NULL so long as it is known that the descriptor for
     243             :   // the extension lives in the same pool as the descriptor for the containing
     244             :   // type.
     245             : #define desc const FieldDescriptor* descriptor  // avoid line wrapping
     246             :   void SetInt32 (int number, FieldType type, int32  value, desc);
     247             :   void SetInt64 (int number, FieldType type, int64  value, desc);
     248             :   void SetUInt32(int number, FieldType type, uint32 value, desc);
     249             :   void SetUInt64(int number, FieldType type, uint64 value, desc);
     250             :   void SetFloat (int number, FieldType type, float  value, desc);
     251             :   void SetDouble(int number, FieldType type, double value, desc);
     252             :   void SetBool  (int number, FieldType type, bool   value, desc);
     253             :   void SetEnum  (int number, FieldType type, int    value, desc);
     254             :   void SetString(int number, FieldType type, const string& value, desc);
     255             :   string * MutableString (int number, FieldType type, desc);
     256             :   MessageLite* MutableMessage(int number, FieldType type,
     257             :                               const MessageLite& prototype, desc);
     258             :   MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
     259             :                               MessageFactory* factory);
     260             :   // Adds the given message to the ExtensionSet, taking ownership of the
     261             :   // message object. Existing message with the same number will be deleted.
     262             :   // If "message" is NULL, this is equivalent to "ClearExtension(number)".
     263             :   void SetAllocatedMessage(int number, FieldType type,
     264             :                            const FieldDescriptor* descriptor,
     265             :                            MessageLite* message);
     266             :   void UnsafeArenaSetAllocatedMessage(int number, FieldType type,
     267             :                                       const FieldDescriptor* descriptor,
     268             :                                       MessageLite* message);
     269             :   MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
     270             :   MessageLite* UnsafeArenaReleaseMessage(
     271             :       int number, const MessageLite& prototype);
     272             : 
     273             :   MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
     274             :                               MessageFactory* factory);
     275             : #undef desc
     276             :   ::google::protobuf::Arena* GetArenaNoVirtual() const { return arena_; }
     277             : 
     278             :   // repeated fields -------------------------------------------------
     279             : 
     280             :   // Fetches a RepeatedField extension by number; returns |default_value|
     281             :   // if no such extension exists. User should not touch this directly; it is
     282             :   // used by the GetRepeatedExtension() method.
     283             :   const void* GetRawRepeatedField(int number, const void* default_value) const;
     284             :   // Fetches a mutable version of a RepeatedField extension by number,
     285             :   // instantiating one if none exists. Similar to above, user should not use
     286             :   // this directly; it underlies MutableRepeatedExtension().
     287             :   void* MutableRawRepeatedField(int number, FieldType field_type,
     288             :                                 bool packed, const FieldDescriptor* desc);
     289             : 
     290             :   // This is an overload of MutableRawRepeatedField to maintain compatibility
     291             :   // with old code using a previous API. This version of
     292             :   // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension.
     293             :   // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
     294             :   void* MutableRawRepeatedField(int number);
     295             : 
     296             :   int32  GetRepeatedInt32 (int number, int index) const;
     297             :   int64  GetRepeatedInt64 (int number, int index) const;
     298             :   uint32 GetRepeatedUInt32(int number, int index) const;
     299             :   uint64 GetRepeatedUInt64(int number, int index) const;
     300             :   float  GetRepeatedFloat (int number, int index) const;
     301             :   double GetRepeatedDouble(int number, int index) const;
     302             :   bool   GetRepeatedBool  (int number, int index) const;
     303             :   int    GetRepeatedEnum  (int number, int index) const;
     304             :   const string & GetRepeatedString (int number, int index) const;
     305             :   const MessageLite& GetRepeatedMessage(int number, int index) const;
     306             : 
     307             :   void SetRepeatedInt32 (int number, int index, int32  value);
     308             :   void SetRepeatedInt64 (int number, int index, int64  value);
     309             :   void SetRepeatedUInt32(int number, int index, uint32 value);
     310             :   void SetRepeatedUInt64(int number, int index, uint64 value);
     311             :   void SetRepeatedFloat (int number, int index, float  value);
     312             :   void SetRepeatedDouble(int number, int index, double value);
     313             :   void SetRepeatedBool  (int number, int index, bool   value);
     314             :   void SetRepeatedEnum  (int number, int index, int    value);
     315             :   void SetRepeatedString(int number, int index, const string& value);
     316             :   string * MutableRepeatedString (int number, int index);
     317             :   MessageLite* MutableRepeatedMessage(int number, int index);
     318             : 
     319             : #define desc const FieldDescriptor* descriptor  // avoid line wrapping
     320             :   void AddInt32 (int number, FieldType type, bool packed, int32  value, desc);
     321             :   void AddInt64 (int number, FieldType type, bool packed, int64  value, desc);
     322             :   void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
     323             :   void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
     324             :   void AddFloat (int number, FieldType type, bool packed, float  value, desc);
     325             :   void AddDouble(int number, FieldType type, bool packed, double value, desc);
     326             :   void AddBool  (int number, FieldType type, bool packed, bool   value, desc);
     327             :   void AddEnum  (int number, FieldType type, bool packed, int    value, desc);
     328             :   void AddString(int number, FieldType type, const string& value, desc);
     329             :   string * AddString (int number, FieldType type, desc);
     330             :   MessageLite* AddMessage(int number, FieldType type,
     331             :                           const MessageLite& prototype, desc);
     332             :   MessageLite* AddMessage(const FieldDescriptor* descriptor,
     333             :                           MessageFactory* factory);
     334             :   void AddAllocatedMessage(const FieldDescriptor* descriptor,
     335             :                            MessageLite* new_entry);
     336             : #undef desc
     337             : 
     338             :   void RemoveLast(int number);
     339             :   MessageLite* ReleaseLast(int number);
     340             :   void SwapElements(int number, int index1, int index2);
     341             : 
     342             :   // -----------------------------------------------------------------
     343             :   // TODO(kenton):  Hardcore memory management accessors
     344             : 
     345             :   // =================================================================
     346             :   // convenience methods for implementing methods of Message
     347             :   //
     348             :   // These could all be implemented in terms of the other methods of this
     349             :   // class, but providing them here helps keep the generated code size down.
     350             : 
     351             :   void Clear();
     352             :   void MergeFrom(const ExtensionSet& other);
     353             :   void Swap(ExtensionSet* other);
     354             :   void SwapExtension(ExtensionSet* other, int number);
     355             :   bool IsInitialized() const;
     356             : 
     357             :   // Parses a single extension from the input. The input should start out
     358             :   // positioned immediately after the tag.
     359             :   bool ParseField(uint32 tag, io::CodedInputStream* input,
     360             :                   ExtensionFinder* extension_finder,
     361             :                   FieldSkipper* field_skipper);
     362             : 
     363             :   // Specific versions for lite or full messages (constructs the appropriate
     364             :   // FieldSkipper automatically).  |containing_type| is the default
     365             :   // instance for the containing message; it is used only to look up the
     366             :   // extension by number.  See RegisterExtension(), above.  Unlike the other
     367             :   // methods of ExtensionSet, this only works for generated message types --
     368             :   // it looks up extensions registered using RegisterExtension().
     369             :   bool ParseField(uint32 tag, io::CodedInputStream* input,
     370             :                   const MessageLite* containing_type);
     371             :   bool ParseField(uint32 tag, io::CodedInputStream* input,
     372             :                   const Message* containing_type,
     373             :                   UnknownFieldSet* unknown_fields);
     374             :   bool ParseField(uint32 tag, io::CodedInputStream* input,
     375             :                   const MessageLite* containing_type,
     376             :                   io::CodedOutputStream* unknown_fields);
     377             : 
     378             :   // Parse an entire message in MessageSet format.  Such messages have no
     379             :   // fields, only extensions.
     380             :   bool ParseMessageSet(io::CodedInputStream* input,
     381             :                        ExtensionFinder* extension_finder,
     382             :                        MessageSetFieldSkipper* field_skipper);
     383             : 
     384             :   // Specific versions for lite or full messages (constructs the appropriate
     385             :   // FieldSkipper automatically).
     386             :   bool ParseMessageSet(io::CodedInputStream* input,
     387             :                        const MessageLite* containing_type);
     388             :   bool ParseMessageSet(io::CodedInputStream* input,
     389             :                        const Message* containing_type,
     390             :                        UnknownFieldSet* unknown_fields);
     391             : 
     392             :   // Write all extension fields with field numbers in the range
     393             :   //   [start_field_number, end_field_number)
     394             :   // to the output stream, using the cached sizes computed when ByteSize() was
     395             :   // last called.  Note that the range bounds are inclusive-exclusive.
     396             :   void SerializeWithCachedSizes(int start_field_number,
     397             :                                 int end_field_number,
     398             :                                 io::CodedOutputStream* output) const;
     399             : 
     400             :   // Same as SerializeWithCachedSizes, but without any bounds checking.
     401             :   // The caller must ensure that target has sufficient capacity for the
     402             :   // serialized extensions.
     403             :   //
     404             :   // Returns a pointer past the last written byte.
     405             :   uint8* SerializeWithCachedSizesToArray(int start_field_number,
     406             :                                          int end_field_number,
     407             :                                          uint8* target) const;
     408             : 
     409             :   // Like above but serializes in MessageSet format.
     410             :   void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
     411             :   uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
     412             : 
     413             :   // Returns the total serialized size of all the extensions.
     414             :   int ByteSize() const;
     415             : 
     416             :   // Like ByteSize() but uses MessageSet format.
     417             :   int MessageSetByteSize() const;
     418             : 
     419             :   // Returns (an estimate of) the total number of bytes used for storing the
     420             :   // extensions in memory, excluding sizeof(*this).  If the ExtensionSet is
     421             :   // for a lite message (and thus possibly contains lite messages), the results
     422             :   // are undefined (might work, might crash, might corrupt data, might not even
     423             :   // be linked in).  It's up to the protocol compiler to avoid calling this on
     424             :   // such ExtensionSets (easy enough since lite messages don't implement
     425             :   // SpaceUsed()).
     426             :   int SpaceUsedExcludingSelf() const;
     427             : 
     428             :  private:
     429             : 
     430             :   // Interface of a lazily parsed singular message extension.
     431             :   class LIBPROTOBUF_EXPORT LazyMessageExtension {
     432             :    public:
     433             :     LazyMessageExtension() {}
     434           0 :     virtual ~LazyMessageExtension() {}
     435             : 
     436             :     virtual LazyMessageExtension* New(::google::protobuf::Arena* arena) const = 0;
     437             :     virtual const MessageLite& GetMessage(
     438             :         const MessageLite& prototype) const = 0;
     439             :     virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
     440             :     virtual void SetAllocatedMessage(MessageLite *message) = 0;
     441             :     virtual void UnsafeArenaSetAllocatedMessage(MessageLite *message) = 0;
     442             :     virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0;
     443             :     virtual MessageLite* UnsafeArenaReleaseMessage(
     444             :         const MessageLite& prototype) = 0;
     445             : 
     446             :     virtual bool IsInitialized() const = 0;
     447             :     virtual int ByteSize() const = 0;
     448             :     virtual int SpaceUsed() const = 0;
     449             : 
     450             :     virtual void MergeFrom(const LazyMessageExtension& other) = 0;
     451             :     virtual void Clear() = 0;
     452             : 
     453             :     virtual bool ReadMessage(const MessageLite& prototype,
     454             :                              io::CodedInputStream* input) = 0;
     455             :     virtual void WriteMessage(int number,
     456             :                               io::CodedOutputStream* output) const = 0;
     457             :     virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
     458             :    private:
     459             :     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
     460             :   };
     461             :   struct Extension {
     462             :     // The order of these fields packs Extension into 24 bytes when using 8
     463             :     // byte alignment. Consider this when adding or removing fields here.
     464             :     union {
     465             :       int32                 int32_value;
     466             :       int64                 int64_value;
     467             :       uint32                uint32_value;
     468             :       uint64                uint64_value;
     469             :       float                 float_value;
     470             :       double                double_value;
     471             :       bool                  bool_value;
     472             :       int                   enum_value;
     473             :       string*               string_value;
     474             :       MessageLite*          message_value;
     475             :       LazyMessageExtension* lazymessage_value;
     476             : 
     477             :       RepeatedField   <int32      >* repeated_int32_value;
     478             :       RepeatedField   <int64      >* repeated_int64_value;
     479             :       RepeatedField   <uint32     >* repeated_uint32_value;
     480             :       RepeatedField   <uint64     >* repeated_uint64_value;
     481             :       RepeatedField   <float      >* repeated_float_value;
     482             :       RepeatedField   <double     >* repeated_double_value;
     483             :       RepeatedField   <bool       >* repeated_bool_value;
     484             :       RepeatedField   <int        >* repeated_enum_value;
     485             :       RepeatedPtrField<string     >* repeated_string_value;
     486             :       RepeatedPtrField<MessageLite>* repeated_message_value;
     487             :     };
     488             : 
     489             :     FieldType type;
     490             :     bool is_repeated;
     491             : 
     492             :     // For singular types, indicates if the extension is "cleared".  This
     493             :     // happens when an extension is set and then later cleared by the caller.
     494             :     // We want to keep the Extension object around for reuse, so instead of
     495             :     // removing it from the map, we just set is_cleared = true.  This has no
     496             :     // meaning for repeated types; for those, the size of the RepeatedField
     497             :     // simply becomes zero when cleared.
     498             :     bool is_cleared : 4;
     499             : 
     500             :     // For singular message types, indicates whether lazy parsing is enabled
     501             :     // for this extension. This field is only valid when type == TYPE_MESSAGE
     502             :     // and !is_repeated because we only support lazy parsing for singular
     503             :     // message types currently. If is_lazy = true, the extension is stored in
     504             :     // lazymessage_value. Otherwise, the extension will be message_value.
     505             :     bool is_lazy : 4;
     506             : 
     507             :     // For repeated types, this indicates if the [packed=true] option is set.
     508             :     bool is_packed;
     509             : 
     510             :     // For packed fields, the size of the packed data is recorded here when
     511             :     // ByteSize() is called then used during serialization.
     512             :     // TODO(kenton):  Use atomic<int> when C++ supports it.
     513             :     mutable int cached_size;
     514             : 
     515             :     // The descriptor for this extension, if one exists and is known.  May be
     516             :     // NULL.  Must not be NULL if the descriptor for the extension does not
     517             :     // live in the same pool as the descriptor for the containing type.
     518             :     const FieldDescriptor* descriptor;
     519             : 
     520             :     // Some helper methods for operations on a single Extension.
     521             :     void SerializeFieldWithCachedSizes(
     522             :         int number,
     523             :         io::CodedOutputStream* output) const;
     524             :     uint8* SerializeFieldWithCachedSizesToArray(
     525             :         int number,
     526             :         uint8* target) const;
     527             :     void SerializeMessageSetItemWithCachedSizes(
     528             :         int number,
     529             :         io::CodedOutputStream* output) const;
     530             :     uint8* SerializeMessageSetItemWithCachedSizesToArray(
     531             :         int number,
     532             :         uint8* target) const;
     533             :     int ByteSize(int number) const;
     534             :     int MessageSetItemByteSize(int number) const;
     535             :     void Clear();
     536             :     int GetSize() const;
     537             :     void Free();
     538             :     int SpaceUsedExcludingSelf() const;
     539             :   };
     540             : 
     541             : 
     542             :   // Merges existing Extension from other_extension
     543             :   void InternalExtensionMergeFrom(int number, const Extension& other_extension);
     544             : 
     545             :   // Returns true and fills field_number and extension if extension is found.
     546             :   // Note to support packed repeated field compatibility, it also fills whether
     547             :   // the tag on wire is packed, which can be different from
     548             :   // extension->is_packed (whether packed=true is specified).
     549             :   bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder,
     550             :                                 int* field_number, ExtensionInfo* extension,
     551             :                                 bool* was_packed_on_wire);
     552             : 
     553             :   // Returns true and fills extension if extension is found.
     554             :   // Note to support packed repeated field compatibility, it also fills whether
     555             :   // the tag on wire is packed, which can be different from
     556             :   // extension->is_packed (whether packed=true is specified).
     557             :   bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number,
     558             :                                         ExtensionFinder* extension_finder,
     559             :                                         ExtensionInfo* extension,
     560             :                                         bool* was_packed_on_wire);
     561             : 
     562             :   // Parses a single extension from the input. The input should start out
     563             :   // positioned immediately after the wire tag. This method is called in
     564             :   // ParseField() after field number and was_packed_on_wire is extracted from
     565             :   // the wire tag and ExtensionInfo is found by the field number.
     566             :   bool ParseFieldWithExtensionInfo(int field_number,
     567             :                                    bool was_packed_on_wire,
     568             :                                    const ExtensionInfo& extension,
     569             :                                    io::CodedInputStream* input,
     570             :                                    FieldSkipper* field_skipper);
     571             : 
     572             :   // Like ParseField(), but this method may parse singular message extensions
     573             :   // lazily depending on the value of FLAGS_eagerly_parse_message_sets.
     574             :   bool ParseFieldMaybeLazily(int wire_type, int field_number,
     575             :                              io::CodedInputStream* input,
     576             :                              ExtensionFinder* extension_finder,
     577             :                              MessageSetFieldSkipper* field_skipper);
     578             : 
     579             :   // Gets the extension with the given number, creating it if it does not
     580             :   // already exist.  Returns true if the extension did not already exist.
     581             :   bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
     582             :                          Extension** result);
     583             : 
     584             :   // Gets the repeated extension for the given descriptor, creating it if
     585             :   // it does not exist.
     586             :   Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor);
     587             : 
     588             :   // Parse a single MessageSet item -- called just after the item group start
     589             :   // tag has been read.
     590             :   bool ParseMessageSetItem(io::CodedInputStream* input,
     591             :                            ExtensionFinder* extension_finder,
     592             :                            MessageSetFieldSkipper* field_skipper);
     593             : 
     594             :   // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
     595             :   //   friendship should automatically extend to ExtensionSet::Extension, but
     596             :   //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
     597             :   //   correctly.  So, we must provide helpers for calling methods of that
     598             :   //   class.
     599             : 
     600             :   // Defined in extension_set_heavy.cc.
     601             :   static inline int RepeatedMessage_SpaceUsedExcludingSelf(
     602             :       RepeatedPtrFieldBase* field);
     603             : 
     604             :   // The Extension struct is small enough to be passed by value, so we use it
     605             :   // directly as the value type in the map rather than use pointers.  We use
     606             :   // a map rather than hash_map here because we expect most ExtensionSets will
     607             :   // only contain a small number of extensions whereas hash_map is optimized
     608             :   // for 100 elements or more.  Also, we want AppendToList() to order fields
     609             :   // by field number.
     610             :   std::map<int, Extension> extensions_;
     611             :   ::google::protobuf::Arena* arena_;
     612             :   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
     613             : };
     614             : 
     615             : // These are just for convenience...
     616             : inline void ExtensionSet::SetString(int number, FieldType type,
     617             :                                     const string& value,
     618             :                                     const FieldDescriptor* descriptor) {
     619           0 :   MutableString(number, type, descriptor)->assign(value);
     620             : }
     621             : inline void ExtensionSet::SetRepeatedString(int number, int index,
     622             :                                             const string& value) {
     623           0 :   MutableRepeatedString(number, index)->assign(value);
     624             : }
     625             : inline void ExtensionSet::AddString(int number, FieldType type,
     626             :                                     const string& value,
     627             :                                     const FieldDescriptor* descriptor) {
     628           0 :   AddString(number, type, descriptor)->assign(value);
     629             : }
     630             : 
     631             : // ===================================================================
     632             : // Glue for generated extension accessors
     633             : 
     634             : // -------------------------------------------------------------------
     635             : // Template magic
     636             : 
     637             : // First we have a set of classes representing "type traits" for different
     638             : // field types.  A type traits class knows how to implement basic accessors
     639             : // for extensions of a particular type given an ExtensionSet.  The signature
     640             : // for a type traits class looks like this:
     641             : //
     642             : //   class TypeTraits {
     643             : //    public:
     644             : //     typedef ? ConstType;
     645             : //     typedef ? MutableType;
     646             : //     // TypeTraits for singular fields and repeated fields will define the
     647             : //     // symbol "Singular" or "Repeated" respectively. These two symbols will
     648             : //     // be used in extension accessors to distinguish between singular
     649             : //     // extensions and repeated extensions. If the TypeTraits for the passed
     650             : //     // in extension doesn't have the expected symbol defined, it means the
     651             : //     // user is passing a repeated extension to a singular accessor, or the
     652             : //     // opposite. In that case the C++ compiler will generate an error
     653             : //     // message "no matching member function" to inform the user.
     654             : //     typedef ? Singular
     655             : //     typedef ? Repeated
     656             : //
     657             : //     static inline ConstType Get(int number, const ExtensionSet& set);
     658             : //     static inline void Set(int number, ConstType value, ExtensionSet* set);
     659             : //     static inline MutableType Mutable(int number, ExtensionSet* set);
     660             : //
     661             : //     // Variants for repeated fields.
     662             : //     static inline ConstType Get(int number, const ExtensionSet& set,
     663             : //                                 int index);
     664             : //     static inline void Set(int number, int index,
     665             : //                            ConstType value, ExtensionSet* set);
     666             : //     static inline MutableType Mutable(int number, int index,
     667             : //                                       ExtensionSet* set);
     668             : //     static inline void Add(int number, ConstType value, ExtensionSet* set);
     669             : //     static inline MutableType Add(int number, ExtensionSet* set);
     670             : //   };
     671             : //
     672             : // Not all of these methods make sense for all field types.  For example, the
     673             : // "Mutable" methods only make sense for strings and messages, and the
     674             : // repeated methods only make sense for repeated types.  So, each type
     675             : // traits class implements only the set of methods from this signature that it
     676             : // actually supports.  This will cause a compiler error if the user tries to
     677             : // access an extension using a method that doesn't make sense for its type.
     678             : // For example, if "foo" is an extension of type "optional int32", then if you
     679             : // try to write code like:
     680             : //   my_message.MutableExtension(foo)
     681             : // you will get a compile error because PrimitiveTypeTraits<int32> does not
     682             : // have a "Mutable()" method.
     683             : 
     684             : // -------------------------------------------------------------------
     685             : // PrimitiveTypeTraits
     686             : 
     687             : // Since the ExtensionSet has different methods for each primitive type,
     688             : // we must explicitly define the methods of the type traits class for each
     689             : // known type.
     690             : template <typename Type>
     691             : class PrimitiveTypeTraits {
     692             :  public:
     693             :   typedef Type ConstType;
     694             :   typedef Type MutableType;
     695             :   typedef PrimitiveTypeTraits<Type> Singular;
     696             : 
     697             :   static inline ConstType Get(int number, const ExtensionSet& set,
     698             :                               ConstType default_value);
     699             :   static inline void Set(int number, FieldType field_type,
     700             :                          ConstType value, ExtensionSet* set);
     701             : };
     702             : 
     703             : template <typename Type>
     704             : class RepeatedPrimitiveTypeTraits {
     705             :  public:
     706             :   typedef Type ConstType;
     707             :   typedef Type MutableType;
     708             :   typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
     709             : 
     710             :   typedef RepeatedField<Type> RepeatedFieldType;
     711             : 
     712             :   static inline Type Get(int number, const ExtensionSet& set, int index);
     713             :   static inline void Set(int number, int index, Type value, ExtensionSet* set);
     714             :   static inline void Add(int number, FieldType field_type,
     715             :                          bool is_packed, Type value, ExtensionSet* set);
     716             : 
     717             :   static inline const RepeatedField<ConstType>&
     718             :       GetRepeated(int number, const ExtensionSet& set);
     719             :   static inline RepeatedField<Type>*
     720             :       MutableRepeated(int number, FieldType field_type,
     721             :                       bool is_packed, ExtensionSet* set);
     722             : 
     723             :   static const RepeatedFieldType* GetDefaultRepeatedField();
     724             : };
     725             : 
     726             : // Declared here so that this can be friended below.
     727             : void InitializeDefaultRepeatedFields();
     728             : void DestroyDefaultRepeatedFields();
     729             : 
     730             : class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits {
     731             :  private:
     732             :   template<typename Type> friend class RepeatedPrimitiveTypeTraits;
     733             :   friend void InitializeDefaultRepeatedFields();
     734             :   friend void DestroyDefaultRepeatedFields();
     735             :   static const RepeatedField<int32>* default_repeated_field_int32_;
     736             :   static const RepeatedField<int64>* default_repeated_field_int64_;
     737             :   static const RepeatedField<uint32>* default_repeated_field_uint32_;
     738             :   static const RepeatedField<uint64>* default_repeated_field_uint64_;
     739             :   static const RepeatedField<double>* default_repeated_field_double_;
     740             :   static const RepeatedField<float>* default_repeated_field_float_;
     741             :   static const RepeatedField<bool>* default_repeated_field_bool_;
     742             : };
     743             : 
     744             : #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
     745             : template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get(                     \
     746             :     int number, const ExtensionSet& set, TYPE default_value) {             \
     747             :   return set.Get##METHOD(number, default_value);                           \
     748             : }                                                                          \
     749             : template<> inline void PrimitiveTypeTraits<TYPE>::Set(                     \
     750             :     int number, FieldType field_type, TYPE value, ExtensionSet* set) {     \
     751             :   set->Set##METHOD(number, field_type, value, NULL);                       \
     752             : }                                                                          \
     753             :                                                                            \
     754             : template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(             \
     755             :     int number, const ExtensionSet& set, int index) {                      \
     756             :   return set.GetRepeated##METHOD(number, index);                           \
     757             : }                                                                          \
     758             : template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(             \
     759             :     int number, int index, TYPE value, ExtensionSet* set) {                \
     760             :   set->SetRepeated##METHOD(number, index, value);                          \
     761             : }                                                                          \
     762             : template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(             \
     763             :     int number, FieldType field_type, bool is_packed,                      \
     764             :     TYPE value, ExtensionSet* set) {                                       \
     765             :   set->Add##METHOD(number, field_type, is_packed, value, NULL);            \
     766             : }                                                                          \
     767             : template<> inline const RepeatedField<TYPE>*                               \
     768             :     RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() {         \
     769             :   return RepeatedPrimitiveGenericTypeTraits::                              \
     770             :       default_repeated_field_##TYPE##_;                                    \
     771             : }                                                                          \
     772             : template<> inline const RepeatedField<TYPE>&                               \
     773             :     RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number,             \
     774             :                                                const ExtensionSet& set) {  \
     775             :   return *reinterpret_cast<const RepeatedField<TYPE>*>(                    \
     776             :                             set.GetRawRepeatedField(                       \
     777             :                                 number, GetDefaultRepeatedField()));       \
     778             : }                                                                          \
     779             : template<> inline RepeatedField<TYPE>*                                     \
     780             :     RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(int number,         \
     781             :                                                    FieldType field_type,   \
     782             :                                                    bool is_packed,         \
     783             :                                                    ExtensionSet* set) {    \
     784             :   return reinterpret_cast<RepeatedField<TYPE>*>(                           \
     785             :       set->MutableRawRepeatedField(number, field_type, is_packed, NULL));  \
     786             : }
     787             : 
     788             : PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32,  Int32)
     789             : PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64,  Int64)
     790             : PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
     791             : PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
     792             : PROTOBUF_DEFINE_PRIMITIVE_TYPE( float,  Float)
     793             : PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
     794             : PROTOBUF_DEFINE_PRIMITIVE_TYPE(  bool,   Bool)
     795             : 
     796             : #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
     797             : 
     798             : // -------------------------------------------------------------------
     799             : // StringTypeTraits
     800             : 
     801             : // Strings support both Set() and Mutable().
     802             : class LIBPROTOBUF_EXPORT StringTypeTraits {
     803             :  public:
     804             :   typedef const string& ConstType;
     805             :   typedef string* MutableType;
     806             :   typedef StringTypeTraits Singular;
     807             : 
     808             :   static inline const string& Get(int number, const ExtensionSet& set,
     809             :                                   ConstType default_value) {
     810             :     return set.GetString(number, default_value);
     811             :   }
     812             :   static inline void Set(int number, FieldType field_type,
     813             :                          const string& value, ExtensionSet* set) {
     814             :     set->SetString(number, field_type, value, NULL);
     815             :   }
     816             :   static inline string* Mutable(int number, FieldType field_type,
     817             :                                 ExtensionSet* set) {
     818             :     return set->MutableString(number, field_type, NULL);
     819             :   }
     820             : };
     821             : 
     822             : class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
     823             :  public:
     824             :   typedef const string& ConstType;
     825             :   typedef string* MutableType;
     826             :   typedef RepeatedStringTypeTraits Repeated;
     827             : 
     828             :   typedef RepeatedPtrField<string> RepeatedFieldType;
     829             : 
     830             :   static inline const string& Get(int number, const ExtensionSet& set,
     831             :                                   int index) {
     832             :     return set.GetRepeatedString(number, index);
     833             :   }
     834             :   static inline void Set(int number, int index,
     835             :                          const string& value, ExtensionSet* set) {
     836             :     set->SetRepeatedString(number, index, value);
     837             :   }
     838             :   static inline string* Mutable(int number, int index, ExtensionSet* set) {
     839             :     return set->MutableRepeatedString(number, index);
     840             :   }
     841             :   static inline void Add(int number, FieldType field_type,
     842             :                          bool /*is_packed*/, const string& value,
     843             :                          ExtensionSet* set) {
     844             :     set->AddString(number, field_type, value, NULL);
     845             :   }
     846             :   static inline string* Add(int number, FieldType field_type,
     847             :                             ExtensionSet* set) {
     848             :     return set->AddString(number, field_type, NULL);
     849             :   }
     850             :   static inline const RepeatedPtrField<string>&
     851             :       GetRepeated(int number, const ExtensionSet& set) {
     852             :     return *reinterpret_cast<const RepeatedPtrField<string>*>(
     853             :         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
     854             :   }
     855             : 
     856             :   static inline RepeatedPtrField<string>*
     857             :       MutableRepeated(int number, FieldType field_type,
     858             :                       bool is_packed, ExtensionSet* set) {
     859             :     return reinterpret_cast<RepeatedPtrField<string>*>(
     860             :         set->MutableRawRepeatedField(number, field_type,
     861             :                                      is_packed, NULL));
     862             :   }
     863             : 
     864             :   static const RepeatedFieldType* GetDefaultRepeatedField() {
     865             :     return default_repeated_field_;
     866             :   }
     867             : 
     868             :  private:
     869             :   friend void InitializeDefaultRepeatedFields();
     870             :   friend void DestroyDefaultRepeatedFields();
     871             :   static const RepeatedFieldType *default_repeated_field_;
     872             : };
     873             : 
     874             : // -------------------------------------------------------------------
     875             : // EnumTypeTraits
     876             : 
     877             : // ExtensionSet represents enums using integers internally, so we have to
     878             : // static_cast around.
     879             : template <typename Type, bool IsValid(int)>
     880             : class EnumTypeTraits {
     881             :  public:
     882             :   typedef Type ConstType;
     883             :   typedef Type MutableType;
     884             :   typedef EnumTypeTraits<Type, IsValid> Singular;
     885             : 
     886             :   static inline ConstType Get(int number, const ExtensionSet& set,
     887             :                               ConstType default_value) {
     888             :     return static_cast<Type>(set.GetEnum(number, default_value));
     889             :   }
     890             :   static inline void Set(int number, FieldType field_type,
     891             :                          ConstType value, ExtensionSet* set) {
     892             :     GOOGLE_DCHECK(IsValid(value));
     893             :     set->SetEnum(number, field_type, value, NULL);
     894             :   }
     895             : };
     896             : 
     897             : template <typename Type, bool IsValid(int)>
     898             : class RepeatedEnumTypeTraits {
     899             :  public:
     900             :   typedef Type ConstType;
     901             :   typedef Type MutableType;
     902             :   typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
     903             : 
     904             :   typedef RepeatedField<Type> RepeatedFieldType;
     905             : 
     906             :   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
     907             :     return static_cast<Type>(set.GetRepeatedEnum(number, index));
     908             :   }
     909             :   static inline void Set(int number, int index,
     910             :                          ConstType value, ExtensionSet* set) {
     911             :     GOOGLE_DCHECK(IsValid(value));
     912             :     set->SetRepeatedEnum(number, index, value);
     913             :   }
     914             :   static inline void Add(int number, FieldType field_type,
     915             :                          bool is_packed, ConstType value, ExtensionSet* set) {
     916             :     GOOGLE_DCHECK(IsValid(value));
     917             :     set->AddEnum(number, field_type, is_packed, value, NULL);
     918             :   }
     919             :   static inline const RepeatedField<Type>& GetRepeated(int number,
     920             :                                                        const ExtensionSet&
     921             :                                                        set) {
     922             :     // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
     923             :     // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
     924             :     // so we need to do some casting magic. See message.h for similar
     925             :     // contortions for non-extension fields.
     926             :     return *reinterpret_cast<const RepeatedField<Type>*>(
     927             :         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
     928             :   }
     929             : 
     930             :   static inline RepeatedField<Type>* MutableRepeated(int number,
     931             :                                                      FieldType field_type,
     932             :                                                      bool is_packed,
     933             :                                                      ExtensionSet* set) {
     934             :     return reinterpret_cast<RepeatedField<Type>*>(
     935             :         set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
     936             :   }
     937             : 
     938             :   static const RepeatedFieldType* GetDefaultRepeatedField() {
     939             :     // Hack: as noted above, repeated enum fields are internally stored as a
     940             :     // RepeatedField<int>. We need to be able to instantiate global static
     941             :     // objects to return as default (empty) repeated fields on non-existent
     942             :     // extensions. We would not be able to know a-priori all of the enum types
     943             :     // (values of |Type|) to instantiate all of these, so we just re-use int32's
     944             :     // default repeated field object.
     945             :     return reinterpret_cast<const RepeatedField<Type>*>(
     946             :         RepeatedPrimitiveTypeTraits<int32>::GetDefaultRepeatedField());
     947             :   }
     948             : };
     949             : 
     950             : // -------------------------------------------------------------------
     951             : // MessageTypeTraits
     952             : 
     953             : // ExtensionSet guarantees that when manipulating extensions with message
     954             : // types, the implementation used will be the compiled-in class representing
     955             : // that type.  So, we can static_cast down to the exact type we expect.
     956             : template <typename Type>
     957             : class MessageTypeTraits {
     958             :  public:
     959             :   typedef const Type& ConstType;
     960             :   typedef Type* MutableType;
     961             :   typedef MessageTypeTraits<Type> Singular;
     962             : 
     963             :   static inline ConstType Get(int number, const ExtensionSet& set,
     964             :                               ConstType default_value) {
     965             :     return static_cast<const Type&>(
     966             :         set.GetMessage(number, default_value));
     967             :   }
     968             :   static inline MutableType Mutable(int number, FieldType field_type,
     969             :                                     ExtensionSet* set) {
     970             :     return static_cast<Type*>(
     971             :       set->MutableMessage(number, field_type, Type::default_instance(), NULL));
     972             :   }
     973             :   static inline void SetAllocated(int number, FieldType field_type,
     974             :                                   MutableType message, ExtensionSet* set) {
     975             :     set->SetAllocatedMessage(number, field_type, NULL, message);
     976             :   }
     977             :   static inline MutableType Release(int number, FieldType /* field_type */,
     978             :                                     ExtensionSet* set) {
     979             :     return static_cast<Type*>(set->ReleaseMessage(
     980             :         number, Type::default_instance()));
     981             :   }
     982             : };
     983             : 
     984             : // forward declaration
     985             : class RepeatedMessageGenericTypeTraits;
     986             : 
     987             : template <typename Type>
     988             : class RepeatedMessageTypeTraits {
     989             :  public:
     990             :   typedef const Type& ConstType;
     991             :   typedef Type* MutableType;
     992             :   typedef RepeatedMessageTypeTraits<Type> Repeated;
     993             : 
     994             :   typedef RepeatedPtrField<Type> RepeatedFieldType;
     995             : 
     996             :   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
     997             :     return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
     998             :   }
     999             :   static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
    1000             :     return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
    1001             :   }
    1002             :   static inline MutableType Add(int number, FieldType field_type,
    1003             :                                 ExtensionSet* set) {
    1004             :     return static_cast<Type*>(
    1005             :         set->AddMessage(number, field_type, Type::default_instance(), NULL));
    1006             :   }
    1007             :   static inline const RepeatedPtrField<Type>& GetRepeated(int number,
    1008             :                                                           const ExtensionSet&
    1009             :                                                           set) {
    1010             :     // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
    1011             :     // casting hack applies here, because a RepeatedPtrField<MessageLite>
    1012             :     // cannot naturally become a RepeatedPtrType<Type> even though Type is
    1013             :     // presumably a message. google::protobuf::Message goes through similar contortions
    1014             :     // with a reinterpret_cast<>.
    1015             :     return *reinterpret_cast<const RepeatedPtrField<Type>*>(
    1016             :         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
    1017             :   }
    1018             :   static inline RepeatedPtrField<Type>* MutableRepeated(int number,
    1019             :                                                         FieldType field_type,
    1020             :                                                         bool is_packed,
    1021             :                                                         ExtensionSet* set) {
    1022             :     return reinterpret_cast<RepeatedPtrField<Type>*>(
    1023             :         set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
    1024             :   }
    1025             : 
    1026             :   static const RepeatedFieldType* GetDefaultRepeatedField();
    1027             : };
    1028             : 
    1029             : // This class exists only to hold a generic default empty repeated field for all
    1030             : // message-type repeated field extensions.
    1031             : class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
    1032             :  public:
    1033             :   typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType;
    1034             :  private:
    1035             :   template<typename Type> friend class RepeatedMessageTypeTraits;
    1036             :   friend void InitializeDefaultRepeatedFields();
    1037             :   friend void DestroyDefaultRepeatedFields();
    1038             :   static const RepeatedFieldType* default_repeated_field_;
    1039             : };
    1040             : 
    1041             : template<typename Type> inline
    1042             :     const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
    1043             :     RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
    1044             :   return reinterpret_cast<const RepeatedFieldType*>(
    1045             :       RepeatedMessageGenericTypeTraits::default_repeated_field_);
    1046             : }
    1047             : 
    1048             : // -------------------------------------------------------------------
    1049             : // ExtensionIdentifier
    1050             : 
    1051             : // This is the type of actual extension objects.  E.g. if you have:
    1052             : //   extends Foo with optional int32 bar = 1234;
    1053             : // then "bar" will be defined in C++ as:
    1054             : //   ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 1, false> bar(1234);
    1055             : //
    1056             : // Note that we could, in theory, supply the field number as a template
    1057             : // parameter, and thus make an instance of ExtensionIdentifier have no
    1058             : // actual contents.  However, if we did that, then using at extension
    1059             : // identifier would not necessarily cause the compiler to output any sort
    1060             : // of reference to any simple defined in the extension's .pb.o file.  Some
    1061             : // linkers will actually drop object files that are not explicitly referenced,
    1062             : // but that would be bad because it would cause this extension to not be
    1063             : // registered at static initialization, and therefore using it would crash.
    1064             : 
    1065             : template <typename ExtendeeType, typename TypeTraitsType,
    1066             :           FieldType field_type, bool is_packed>
    1067             : class ExtensionIdentifier {
    1068             :  public:
    1069             :   typedef TypeTraitsType TypeTraits;
    1070             :   typedef ExtendeeType Extendee;
    1071             : 
    1072             :   ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
    1073             :       : number_(number), default_value_(default_value) {}
    1074             :   inline int number() const { return number_; }
    1075             :   typename TypeTraits::ConstType default_value() const {
    1076             :     return default_value_;
    1077             :   }
    1078             : 
    1079             :  private:
    1080             :   const int number_;
    1081             :   typename TypeTraits::ConstType default_value_;
    1082             : };
    1083             : 
    1084             : // -------------------------------------------------------------------
    1085             : // Generated accessors
    1086             : 
    1087             : // This macro should be expanded in the context of a generated type which
    1088             : // has extensions.
    1089             : //
    1090             : // We use "_proto_TypeTraits" as a type name below because "TypeTraits"
    1091             : // causes problems if the class has a nested message or enum type with that
    1092             : // name and "_TypeTraits" is technically reserved for the C++ library since
    1093             : // it starts with an underscore followed by a capital letter.
    1094             : //
    1095             : // For similar reason, we use "_field_type" and "_is_packed" as parameter names
    1096             : // below, so that "field_type" and "is_packed" can be used as field names.
    1097             : #define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME)                        \
    1098             :   /* Has, Size, Clear */                                                      \
    1099             :   template <typename _proto_TypeTraits,                                       \
    1100             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1101             :             bool _is_packed>                                                  \
    1102             :   inline bool HasExtension(                                                   \
    1103             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1104             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
    1105             :     return _extensions_.Has(id.number());                                     \
    1106             :   }                                                                           \
    1107             :                                                                               \
    1108             :   template <typename _proto_TypeTraits,                                       \
    1109             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1110             :             bool _is_packed>                                                  \
    1111             :   inline void ClearExtension(                                                 \
    1112             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1113             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    1114             :     _extensions_.ClearExtension(id.number());                                 \
    1115             :   }                                                                           \
    1116             :                                                                               \
    1117             :   template <typename _proto_TypeTraits,                                       \
    1118             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1119             :             bool _is_packed>                                                  \
    1120             :   inline int ExtensionSize(                                                   \
    1121             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1122             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
    1123             :     return _extensions_.ExtensionSize(id.number());                           \
    1124             :   }                                                                           \
    1125             :                                                                               \
    1126             :   /* Singular accessors */                                                    \
    1127             :   template <typename _proto_TypeTraits,                                       \
    1128             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1129             :             bool _is_packed>                                                  \
    1130             :   inline typename _proto_TypeTraits::Singular::ConstType GetExtension(        \
    1131             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1132             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
    1133             :     return _proto_TypeTraits::Get(id.number(), _extensions_,                  \
    1134             :                                   id.default_value());                        \
    1135             :   }                                                                           \
    1136             :                                                                               \
    1137             :   template <typename _proto_TypeTraits,                                       \
    1138             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1139             :             bool _is_packed>                                                  \
    1140             :   inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(  \
    1141             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1142             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    1143             :     return _proto_TypeTraits::Mutable(id.number(), _field_type,               \
    1144             :                                       &_extensions_);                         \
    1145             :   }                                                                           \
    1146             :                                                                               \
    1147             :   template <typename _proto_TypeTraits,                                       \
    1148             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1149             :             bool _is_packed>                                                  \
    1150             :   inline void SetExtension(                                                   \
    1151             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1152             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    1153             :       typename _proto_TypeTraits::Singular::ConstType value) {                \
    1154             :     _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);   \
    1155             :   }                                                                           \
    1156             :                                                                               \
    1157             :   template <typename _proto_TypeTraits,                                       \
    1158             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1159             :             bool _is_packed>                                                  \
    1160             :   inline void SetAllocatedExtension(                                          \
    1161             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1162             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    1163             :       typename _proto_TypeTraits::Singular::MutableType value) {              \
    1164             :     _proto_TypeTraits::SetAllocated(id.number(), _field_type,                 \
    1165             :                                     value, &_extensions_);                    \
    1166             :   }                                                                           \
    1167             :   template <typename _proto_TypeTraits,                                       \
    1168             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1169             :             bool _is_packed>                                                  \
    1170             :   inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension(  \
    1171             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1172             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    1173             :     return _proto_TypeTraits::Release(id.number(), _field_type,               \
    1174             :                                       &_extensions_);                         \
    1175             :   }                                                                           \
    1176             :                                                                               \
    1177             :   /* Repeated accessors */                                                    \
    1178             :   template <typename _proto_TypeTraits,                                       \
    1179             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1180             :             bool _is_packed>                                                  \
    1181             :   inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(        \
    1182             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1183             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    1184             :       int index) const {                                                      \
    1185             :     return _proto_TypeTraits::Get(id.number(), _extensions_, index);          \
    1186             :   }                                                                           \
    1187             :                                                                               \
    1188             :   template <typename _proto_TypeTraits,                                       \
    1189             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1190             :             bool _is_packed>                                                  \
    1191             :   inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(  \
    1192             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1193             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    1194             :       int index) {                                                            \
    1195             :     return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);     \
    1196             :   }                                                                           \
    1197             :                                                                               \
    1198             :   template <typename _proto_TypeTraits,                                       \
    1199             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1200             :             bool _is_packed>                                                  \
    1201             :   inline void SetExtension(                                                   \
    1202             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1203             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    1204             :       int index, typename _proto_TypeTraits::Repeated::ConstType value) {     \
    1205             :     _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);         \
    1206             :   }                                                                           \
    1207             :                                                                               \
    1208             :   template <typename _proto_TypeTraits,                                       \
    1209             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1210             :             bool _is_packed>                                                  \
    1211             :   inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(      \
    1212             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1213             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
    1214             :     return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);   \
    1215             :   }                                                                           \
    1216             :                                                                               \
    1217             :   template <typename _proto_TypeTraits,                                       \
    1218             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1219             :             bool _is_packed>                                                  \
    1220             :   inline void AddExtension(                                                   \
    1221             :       const ::google::protobuf::internal::ExtensionIdentifier<                          \
    1222             :         CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
    1223             :       typename _proto_TypeTraits::Repeated::ConstType value) {                \
    1224             :     _proto_TypeTraits::Add(id.number(), _field_type, _is_packed,              \
    1225             :                            value, &_extensions_);                             \
    1226             :   }                                                                           \
    1227             :                                                                               \
    1228             :   template <typename _proto_TypeTraits,                                       \
    1229             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1230             :             bool _is_packed>                                                  \
    1231             :   inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&       \
    1232             :       GetRepeatedExtension(                                                   \
    1233             :           const ::google::protobuf::internal::ExtensionIdentifier<                      \
    1234             :             CLASSNAME, _proto_TypeTraits, _field_type,                        \
    1235             :             _is_packed>& id) const {                                          \
    1236             :     return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);         \
    1237             :   }                                                                           \
    1238             :                                                                               \
    1239             :   template <typename _proto_TypeTraits,                                       \
    1240             :             ::google::protobuf::internal::FieldType _field_type,                        \
    1241             :             bool _is_packed>                                                  \
    1242             :   inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*             \
    1243             :       MutableRepeatedExtension(                                               \
    1244             :           const ::google::protobuf::internal::ExtensionIdentifier<                      \
    1245             :               CLASSNAME, _proto_TypeTraits, _field_type,                      \
    1246             :               _is_packed>& id) {                                              \
    1247             :     return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,       \
    1248             :                                               _is_packed, &_extensions_);     \
    1249             :   }
    1250             : 
    1251             : }  // namespace internal
    1252             : }  // namespace protobuf
    1253             : 
    1254             : }  // namespace google
    1255             : #endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__

Generated by: LCOV version 1.10