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