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