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