| 1 | // Protocol Buffers - Google's data interchange format | 
| 2 | // Copyright 2008 Google Inc.  All rights reserved. | 
| 3 | // https://developers.google.com/protocol-buffers/ | 
| 4 | // | 
| 5 | // Redistribution and use in source and binary forms, with or without | 
| 6 | // modification, are permitted provided that the following conditions are | 
| 7 | // met: | 
| 8 | // | 
| 9 | //     * Redistributions of source code must retain the above copyright | 
| 10 | // notice, this list of conditions and the following disclaimer. | 
| 11 | //     * Redistributions in binary form must reproduce the above | 
| 12 | // copyright notice, this list of conditions and the following disclaimer | 
| 13 | // in the documentation and/or other materials provided with the | 
| 14 | // distribution. | 
| 15 | //     * Neither the name of Google Inc. nor the names of its | 
| 16 | // contributors may be used to endorse or promote products derived from | 
| 17 | // this software without specific prior written permission. | 
| 18 | // | 
| 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
| 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
| 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
| 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
| 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
| 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
| 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
| 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
| 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
| 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 30 |  | 
| 31 | // Author: kenton@google.com (Kenton Varda) | 
| 32 | //  Based on original Protocol Buffers design by | 
| 33 | //  Sanjay Ghemawat, Jeff Dean, and others. | 
| 34 | // | 
| 35 | // This header is logically internal, but is made public because it is used | 
| 36 | // from protocol-compiler-generated code, which may reside in other components. | 
| 37 |  | 
| 38 | #ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__ | 
| 39 | #define GOOGLE_PROTOBUF_EXTENSION_SET_H__ | 
| 40 |  | 
| 41 |  | 
| 42 | #include <algorithm> | 
| 43 | #include <cassert> | 
| 44 | #include <map> | 
| 45 | #include <string> | 
| 46 | #include <utility> | 
| 47 | #include <vector> | 
| 48 |  | 
| 49 | #include <google/protobuf/stubs/common.h> | 
| 50 | #include <google/protobuf/stubs/logging.h> | 
| 51 | #include <google/protobuf/io/coded_stream.h> | 
| 52 | #include <google/protobuf/port.h> | 
| 53 | #include <google/protobuf/parse_context.h> | 
| 54 | #include <google/protobuf/repeated_field.h> | 
| 55 | #include <google/protobuf/wire_format_lite.h> | 
| 56 |  | 
| 57 | // clang-format off | 
| 58 | #include <google/protobuf/port_def.inc>  // Must be last | 
| 59 | // clang-format on | 
| 60 |  | 
| 61 | #ifdef SWIG | 
| 62 | #error "You cannot SWIG proto headers" | 
| 63 | #endif | 
| 64 |  | 
| 65 | namespace google { | 
| 66 | namespace protobuf { | 
| 67 | class Arena; | 
| 68 | class Descriptor;       // descriptor.h | 
| 69 | class FieldDescriptor;  // descriptor.h | 
| 70 | class DescriptorPool;   // descriptor.h | 
| 71 | class MessageLite;      // message_lite.h | 
| 72 | class Message;          // message.h | 
| 73 | class MessageFactory;   // message.h | 
| 74 | class Reflection;       // message.h | 
| 75 | class UnknownFieldSet;  // unknown_field_set.h | 
| 76 | namespace internal { | 
| 77 | class FieldSkipper;  // wire_format_lite.h | 
| 78 | enum class LazyVerifyOption; | 
| 79 | }  // namespace internal | 
| 80 | }  // namespace protobuf | 
| 81 | }  // namespace google | 
| 82 |  | 
| 83 | namespace google { | 
| 84 | namespace protobuf { | 
| 85 | namespace internal { | 
| 86 |  | 
| 87 | class InternalMetadata; | 
| 88 |  | 
| 89 | // Used to store values of type WireFormatLite::FieldType without having to | 
| 90 | // #include wire_format_lite.h.  Also, ensures that we use only one byte to | 
| 91 | // store these values, which is important to keep the layout of | 
| 92 | // ExtensionSet::Extension small. | 
| 93 | typedef uint8_t FieldType; | 
| 94 |  | 
| 95 | // A function which, given an integer value, returns true if the number | 
| 96 | // matches one of the defined values for the corresponding enum type.  This | 
| 97 | // is used with RegisterEnumExtension, below. | 
| 98 | typedef bool EnumValidityFunc(int number); | 
| 99 |  | 
| 100 | // Version of the above which takes an argument.  This is needed to deal with | 
| 101 | // extensions that are not compiled in. | 
| 102 | typedef bool EnumValidityFuncWithArg(const void* arg, int number); | 
| 103 |  | 
| 104 | // Information about a registered extension. | 
| 105 | struct ExtensionInfo { | 
| 106 |   constexpr ExtensionInfo() : enum_validity_check() {} | 
| 107 |   constexpr ExtensionInfo(const MessageLite* extendee, int param_number, | 
| 108 |                           FieldType type_param, bool isrepeated, bool ispacked, | 
| 109 |                           LazyEagerVerifyFnType verify_func) | 
| 110 |       : message(extendee), | 
| 111 |         number(param_number), | 
| 112 |         type(type_param), | 
| 113 |         is_repeated(isrepeated), | 
| 114 |         is_packed(ispacked), | 
| 115 |         enum_validity_check(), | 
| 116 |         lazy_eager_verify_func(verify_func) {} | 
| 117 |  | 
| 118 |   const MessageLite* message = nullptr; | 
| 119 |   int number = 0; | 
| 120 |  | 
| 121 |   FieldType type = 0; | 
| 122 |   bool is_repeated = false; | 
| 123 |   bool is_packed = false; | 
| 124 |  | 
| 125 |   struct EnumValidityCheck { | 
| 126 |     EnumValidityFuncWithArg* func; | 
| 127 |     const void* arg; | 
| 128 |   }; | 
| 129 |  | 
| 130 |   struct MessageInfo { | 
| 131 |     const MessageLite* prototype; | 
| 132 |   }; | 
| 133 |  | 
| 134 |   union { | 
| 135 |     EnumValidityCheck enum_validity_check; | 
| 136 |     MessageInfo message_info; | 
| 137 |   }; | 
| 138 |  | 
| 139 |   // The descriptor for this extension, if one exists and is known.  May be | 
| 140 |   // nullptr.  Must not be nullptr if the descriptor for the extension does not | 
| 141 |   // live in the same pool as the descriptor for the containing type. | 
| 142 |   const FieldDescriptor* descriptor = nullptr; | 
| 143 |  | 
| 144 |   // If this field is potentially lazy this function can be used as a cheap | 
| 145 |   // verification of the raw bytes. | 
| 146 |   // If nullptr then no verification is performed. | 
| 147 |   LazyEagerVerifyFnType lazy_eager_verify_func = nullptr; | 
| 148 | }; | 
| 149 |  | 
| 150 | // An ExtensionFinder is an object which looks up extension definitions.  It | 
| 151 | // must implement this method: | 
| 152 | // | 
| 153 | // bool Find(int number, ExtensionInfo* output); | 
| 154 |  | 
| 155 | // GeneratedExtensionFinder is an ExtensionFinder which finds extensions | 
| 156 | // defined in .proto files which have been compiled into the binary. | 
| 157 | class PROTOBUF_EXPORT GeneratedExtensionFinder { | 
| 158 |  public: | 
| 159 |   explicit GeneratedExtensionFinder(const MessageLite* extendee) | 
| 160 |       : extendee_(extendee) {} | 
| 161 |  | 
| 162 |   // Returns true and fills in *output if found, otherwise returns false. | 
| 163 |   bool Find(int number, ExtensionInfo* output); | 
| 164 |  | 
| 165 |  private: | 
| 166 |   const MessageLite* extendee_; | 
| 167 | }; | 
| 168 |  | 
| 169 | // Note:  extension_set_heavy.cc defines DescriptorPoolExtensionFinder for | 
| 170 | // finding extensions from a DescriptorPool. | 
| 171 |  | 
| 172 | // This is an internal helper class intended for use within the protocol buffer | 
| 173 | // library and generated classes.  Clients should not use it directly.  Instead, | 
| 174 | // use the generated accessors such as GetExtension() of the class being | 
| 175 | // extended. | 
| 176 | // | 
| 177 | // This class manages extensions for a protocol message object.  The | 
| 178 | // message's HasExtension(), GetExtension(), MutableExtension(), and | 
| 179 | // ClearExtension() methods are just thin wrappers around the embedded | 
| 180 | // ExtensionSet.  When parsing, if a tag number is encountered which is | 
| 181 | // inside one of the message type's extension ranges, the tag is passed | 
| 182 | // off to the ExtensionSet for parsing.  Etc. | 
| 183 | class PROTOBUF_EXPORT ExtensionSet { | 
| 184 |  public: | 
| 185 |   constexpr ExtensionSet(); | 
| 186 |   explicit ExtensionSet(Arena* arena); | 
| 187 |   ExtensionSet(ArenaInitialized, Arena* arena) : ExtensionSet(arena) {} | 
| 188 |   ~ExtensionSet(); | 
| 189 |  | 
| 190 |   // These are called at startup by protocol-compiler-generated code to | 
| 191 |   // register known extensions.  The registrations are used by ParseField() | 
| 192 |   // to look up extensions for parsed field numbers.  Note that dynamic parsing | 
| 193 |   // does not use ParseField(); only protocol-compiler-generated parsing | 
| 194 |   // methods do. | 
| 195 |   static void RegisterExtension(const MessageLite* extendee, int number, | 
| 196 |                                 FieldType type, bool is_repeated, | 
| 197 |                                 bool is_packed, | 
| 198 |                                 LazyEagerVerifyFnType verify_func); | 
| 199 |   static void RegisterEnumExtension(const MessageLite* extendee, int number, | 
| 200 |                                     FieldType type, bool is_repeated, | 
| 201 |                                     bool is_packed, EnumValidityFunc* is_valid); | 
| 202 |   static void RegisterMessageExtension(const MessageLite* extendee, int number, | 
| 203 |                                        FieldType type, bool is_repeated, | 
| 204 |                                        bool is_packed, | 
| 205 |                                        const MessageLite* prototype, | 
| 206 |                                        LazyEagerVerifyFnType verify_func); | 
| 207 |  | 
| 208 |   // ================================================================= | 
| 209 |  | 
| 210 |   // Add all fields which are currently present to the given vector.  This | 
| 211 |   // is useful to implement Reflection::ListFields(). | 
| 212 |   void AppendToList(const Descriptor* extendee, const DescriptorPool* pool, | 
| 213 |                     std::vector<const FieldDescriptor*>* output) const; | 
| 214 |  | 
| 215 |   // ================================================================= | 
| 216 |   // Accessors | 
| 217 |   // | 
| 218 |   // Generated message classes include type-safe templated wrappers around | 
| 219 |   // these methods.  Generally you should use those rather than call these | 
| 220 |   // directly, unless you are doing low-level memory management. | 
| 221 |   // | 
| 222 |   // When calling any of these accessors, the extension number requested | 
| 223 |   // MUST exist in the DescriptorPool provided to the constructor.  Otherwise, | 
| 224 |   // the method will fail an assert.  Normally, though, you would not call | 
| 225 |   // these directly; you would either call the generated accessors of your | 
| 226 |   // message class (e.g. GetExtension()) or you would call the accessors | 
| 227 |   // of the reflection interface.  In both cases, it is impossible to | 
| 228 |   // trigger this assert failure:  the generated accessors only accept | 
| 229 |   // linked-in extension types as parameters, while the Reflection interface | 
| 230 |   // requires you to provide the FieldDescriptor describing the extension. | 
| 231 |   // | 
| 232 |   // When calling any of these accessors, a protocol-compiler-generated | 
| 233 |   // implementation of the extension corresponding to the number MUST | 
| 234 |   // be linked in, and the FieldDescriptor used to refer to it MUST be | 
| 235 |   // the one generated by that linked-in code.  Otherwise, the method will | 
| 236 |   // die on an assert failure.  The message objects returned by the message | 
| 237 |   // accessors are guaranteed to be of the correct linked-in type. | 
| 238 |   // | 
| 239 |   // These methods pretty much match Reflection except that: | 
| 240 |   // - They're not virtual. | 
| 241 |   // - They identify fields by number rather than FieldDescriptors. | 
| 242 |   // - They identify enum values using integers rather than descriptors. | 
| 243 |   // - Strings provide Mutable() in addition to Set() accessors. | 
| 244 |  | 
| 245 |   bool Has(int number) const; | 
| 246 |   int ExtensionSize(int number) const;  // Size of a repeated extension. | 
| 247 |   int NumExtensions() const;            // The number of extensions | 
| 248 |   FieldType ExtensionType(int number) const; | 
| 249 |   void ClearExtension(int number); | 
| 250 |  | 
| 251 |   // singular fields ------------------------------------------------- | 
| 252 |  | 
| 253 |   int32_t GetInt32(int number, int32_t default_value) const; | 
| 254 |   int64_t GetInt64(int number, int64_t default_value) const; | 
| 255 |   uint32_t GetUInt32(int number, uint32_t default_value) const; | 
| 256 |   uint64_t GetUInt64(int number, uint64_t default_value) const; | 
| 257 |   float GetFloat(int number, float default_value) const; | 
| 258 |   double GetDouble(int number, double default_value) const; | 
| 259 |   bool GetBool(int number, bool default_value) const; | 
| 260 |   int GetEnum(int number, int default_value) const; | 
| 261 |   const std::string& GetString(int number, | 
| 262 |                                const std::string& default_value) const; | 
| 263 |   const MessageLite& GetMessage(int number, | 
| 264 |                                 const MessageLite& default_value) const; | 
| 265 |   const MessageLite& GetMessage(int number, const Descriptor* message_type, | 
| 266 |                                 MessageFactory* factory) const; | 
| 267 |  | 
| 268 |   // |descriptor| may be nullptr so long as it is known that the descriptor for | 
| 269 |   // the extension lives in the same pool as the descriptor for the containing | 
| 270 |   // type. | 
| 271 | #define desc const FieldDescriptor* descriptor  // avoid line wrapping | 
| 272 |   void SetInt32(int number, FieldType type, int32_t value, desc); | 
| 273 |   void SetInt64(int number, FieldType type, int64_t value, desc); | 
| 274 |   void SetUInt32(int number, FieldType type, uint32_t value, desc); | 
| 275 |   void SetUInt64(int number, FieldType type, uint64_t value, desc); | 
| 276 |   void SetFloat(int number, FieldType type, float value, desc); | 
| 277 |   void SetDouble(int number, FieldType type, double value, desc); | 
| 278 |   void SetBool(int number, FieldType type, bool value, desc); | 
| 279 |   void SetEnum(int number, FieldType type, int value, desc); | 
| 280 |   void SetString(int number, FieldType type, std::string value, desc); | 
| 281 |   std::string* MutableString(int number, FieldType type, desc); | 
| 282 |   MessageLite* MutableMessage(int number, FieldType type, | 
| 283 |                               const MessageLite& prototype, desc); | 
| 284 |   MessageLite* MutableMessage(const FieldDescriptor* descriptor, | 
| 285 |                               MessageFactory* factory); | 
| 286 |   // Adds the given message to the ExtensionSet, taking ownership of the | 
| 287 |   // message object. Existing message with the same number will be deleted. | 
| 288 |   // If "message" is nullptr, this is equivalent to "ClearExtension(number)". | 
| 289 |   void SetAllocatedMessage(int number, FieldType type, | 
| 290 |                            const FieldDescriptor* descriptor, | 
| 291 |                            MessageLite* message); | 
| 292 |   void UnsafeArenaSetAllocatedMessage(int number, FieldType type, | 
| 293 |                                       const FieldDescriptor* descriptor, | 
| 294 |                                       MessageLite* message); | 
| 295 |   PROTOBUF_NODISCARD MessageLite* ReleaseMessage(int number, | 
| 296 |                                                  const MessageLite& prototype); | 
| 297 |   MessageLite* UnsafeArenaReleaseMessage(int number, | 
| 298 |                                          const MessageLite& prototype); | 
| 299 |  | 
| 300 |   PROTOBUF_NODISCARD MessageLite* ReleaseMessage( | 
| 301 |       const FieldDescriptor* descriptor, MessageFactory* factory); | 
| 302 |   MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor, | 
| 303 |                                          MessageFactory* factory); | 
| 304 | #undef desc | 
| 305 |   Arena* GetArena() const { return arena_; } | 
| 306 |  | 
| 307 |   // repeated fields ------------------------------------------------- | 
| 308 |  | 
| 309 |   // Fetches a RepeatedField extension by number; returns |default_value| | 
| 310 |   // if no such extension exists. User should not touch this directly; it is | 
| 311 |   // used by the GetRepeatedExtension() method. | 
| 312 |   const void* GetRawRepeatedField(int number, const void* default_value) const; | 
| 313 |   // Fetches a mutable version of a RepeatedField extension by number, | 
| 314 |   // instantiating one if none exists. Similar to above, user should not use | 
| 315 |   // this directly; it underlies MutableRepeatedExtension(). | 
| 316 |   void* MutableRawRepeatedField(int number, FieldType field_type, bool packed, | 
| 317 |                                 const FieldDescriptor* desc); | 
| 318 |  | 
| 319 |   // This is an overload of MutableRawRepeatedField to maintain compatibility | 
| 320 |   // with old code using a previous API. This version of | 
| 321 |   // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension. | 
| 322 |   // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.) | 
| 323 |   void* MutableRawRepeatedField(int number); | 
| 324 |  | 
| 325 |   int32_t GetRepeatedInt32(int number, int index) const; | 
| 326 |   int64_t GetRepeatedInt64(int number, int index) const; | 
| 327 |   uint32_t GetRepeatedUInt32(int number, int index) const; | 
| 328 |   uint64_t GetRepeatedUInt64(int number, int index) const; | 
| 329 |   float GetRepeatedFloat(int number, int index) const; | 
| 330 |   double GetRepeatedDouble(int number, int index) const; | 
| 331 |   bool GetRepeatedBool(int number, int index) const; | 
| 332 |   int GetRepeatedEnum(int number, int index) const; | 
| 333 |   const std::string& GetRepeatedString(int number, int index) const; | 
| 334 |   const MessageLite& GetRepeatedMessage(int number, int index) const; | 
| 335 |  | 
| 336 |   void SetRepeatedInt32(int number, int index, int32_t value); | 
| 337 |   void SetRepeatedInt64(int number, int index, int64_t value); | 
| 338 |   void SetRepeatedUInt32(int number, int index, uint32_t value); | 
| 339 |   void SetRepeatedUInt64(int number, int index, uint64_t value); | 
| 340 |   void SetRepeatedFloat(int number, int index, float value); | 
| 341 |   void SetRepeatedDouble(int number, int index, double value); | 
| 342 |   void SetRepeatedBool(int number, int index, bool value); | 
| 343 |   void SetRepeatedEnum(int number, int index, int value); | 
| 344 |   void SetRepeatedString(int number, int index, std::string value); | 
| 345 |   std::string* MutableRepeatedString(int number, int index); | 
| 346 |   MessageLite* MutableRepeatedMessage(int number, int index); | 
| 347 |  | 
| 348 | #define desc const FieldDescriptor* descriptor  // avoid line wrapping | 
| 349 |   void AddInt32(int number, FieldType type, bool packed, int32_t value, desc); | 
| 350 |   void AddInt64(int number, FieldType type, bool packed, int64_t value, desc); | 
| 351 |   void AddUInt32(int number, FieldType type, bool packed, uint32_t value, desc); | 
| 352 |   void AddUInt64(int number, FieldType type, bool packed, uint64_t value, desc); | 
| 353 |   void AddFloat(int number, FieldType type, bool packed, float value, desc); | 
| 354 |   void AddDouble(int number, FieldType type, bool packed, double value, desc); | 
| 355 |   void AddBool(int number, FieldType type, bool packed, bool value, desc); | 
| 356 |   void AddEnum(int number, FieldType type, bool packed, int value, desc); | 
| 357 |   void AddString(int number, FieldType type, std::string value, desc); | 
| 358 |   std::string* AddString(int number, FieldType type, desc); | 
| 359 |   MessageLite* AddMessage(int number, FieldType type, | 
| 360 |                           const MessageLite& prototype, desc); | 
| 361 |   MessageLite* AddMessage(const FieldDescriptor* descriptor, | 
| 362 |                           MessageFactory* factory); | 
| 363 |   void AddAllocatedMessage(const FieldDescriptor* descriptor, | 
| 364 |                            MessageLite* new_entry); | 
| 365 |   void UnsafeArenaAddAllocatedMessage(const FieldDescriptor* descriptor, | 
| 366 |                                       MessageLite* new_entry); | 
| 367 | #undef desc | 
| 368 |  | 
| 369 |   void RemoveLast(int number); | 
| 370 |   PROTOBUF_NODISCARD MessageLite* ReleaseLast(int number); | 
| 371 |   MessageLite* UnsafeArenaReleaseLast(int number); | 
| 372 |   void SwapElements(int number, int index1, int index2); | 
| 373 |  | 
| 374 |   // ================================================================= | 
| 375 |   // convenience methods for implementing methods of Message | 
| 376 |   // | 
| 377 |   // These could all be implemented in terms of the other methods of this | 
| 378 |   // class, but providing them here helps keep the generated code size down. | 
| 379 |  | 
| 380 |   void Clear(); | 
| 381 |   void MergeFrom(const MessageLite* extendee, const ExtensionSet& other); | 
| 382 |   void Swap(const MessageLite* extendee, ExtensionSet* other); | 
| 383 |   void InternalSwap(ExtensionSet* other); | 
| 384 |   void SwapExtension(const MessageLite* extendee, ExtensionSet* other, | 
| 385 |                      int number); | 
| 386 |   void UnsafeShallowSwapExtension(ExtensionSet* other, int number); | 
| 387 |   bool IsInitialized() const; | 
| 388 |  | 
| 389 |   // Lite parser | 
| 390 |   const char* ParseField(uint64_t tag, const char* ptr, | 
| 391 |                          const MessageLite* extendee, | 
| 392 |                          internal::InternalMetadata* metadata, | 
| 393 |                          internal::ParseContext* ctx); | 
| 394 |   // Full parser | 
| 395 |   const char* ParseField(uint64_t tag, const char* ptr, const Message* extendee, | 
| 396 |                          internal::InternalMetadata* metadata, | 
| 397 |                          internal::ParseContext* ctx); | 
| 398 |   template <typename Msg> | 
| 399 |   const char* ParseMessageSet(const char* ptr, const Msg* extendee, | 
| 400 |                               InternalMetadata* metadata, | 
| 401 |                               internal::ParseContext* ctx) { | 
| 402 |     struct MessageSetItem { | 
| 403 |       const char* _InternalParse(const char* ptr, ParseContext* ctx) { | 
| 404 |         return me->ParseMessageSetItem(ptr, extendee, metadata, ctx); | 
| 405 |       } | 
| 406 |       ExtensionSet* me; | 
| 407 |       const Msg* extendee; | 
| 408 |       InternalMetadata* metadata; | 
| 409 |     } item{this, extendee, metadata}; | 
| 410 |     while (!ctx->Done(ptr: &ptr)) { | 
| 411 |       uint32_t tag; | 
| 412 |       ptr = ReadTag(p: ptr, out: &tag); | 
| 413 |       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); | 
| 414 |       if (tag == WireFormatLite::kMessageSetItemStartTag) { | 
| 415 |         ptr = ctx->ParseGroup(&item, ptr, tag); | 
| 416 |         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); | 
| 417 |       } else { | 
| 418 |         if (tag == 0 || (tag & 7) == 4) { | 
| 419 |           ctx->SetLastTag(tag); | 
| 420 |           return ptr; | 
| 421 |         } | 
| 422 |         ptr = ParseField(tag, ptr, extendee, metadata, ctx); | 
| 423 |         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); | 
| 424 |       } | 
| 425 |     } | 
| 426 |     return ptr; | 
| 427 |   } | 
| 428 |  | 
| 429 |   // Write all extension fields with field numbers in the range | 
| 430 |   //   [start_field_number, end_field_number) | 
| 431 |   // to the output stream, using the cached sizes computed when ByteSize() was | 
| 432 |   // last called.  Note that the range bounds are inclusive-exclusive. | 
| 433 |   void SerializeWithCachedSizes(const MessageLite* extendee, | 
| 434 |                                 int start_field_number, int end_field_number, | 
| 435 |                                 io::CodedOutputStream* output) const { | 
| 436 |     output->SetCur(_InternalSerialize(extendee, start_field_number, | 
| 437 |                                       end_field_number, target: output->Cur(), | 
| 438 |                                       stream: output->EpsCopy())); | 
| 439 |   } | 
| 440 |  | 
| 441 |   // Same as SerializeWithCachedSizes, but without any bounds checking. | 
| 442 |   // The caller must ensure that target has sufficient capacity for the | 
| 443 |   // serialized extensions. | 
| 444 |   // | 
| 445 |   // Returns a pointer past the last written byte. | 
| 446 |  | 
| 447 |   uint8_t* _InternalSerialize(const MessageLite* extendee, | 
| 448 |                               int start_field_number, int end_field_number, | 
| 449 |                               uint8_t* target, | 
| 450 |                               io::EpsCopyOutputStream* stream) const { | 
| 451 |     if (flat_size_ == 0) { | 
| 452 |       assert(!is_large()); | 
| 453 |       return target; | 
| 454 |     } | 
| 455 |     return _InternalSerializeImpl(extendee, start_field_number, | 
| 456 |                                   end_field_number, target, stream); | 
| 457 |   } | 
| 458 |  | 
| 459 |   // Like above but serializes in MessageSet format. | 
| 460 |   void SerializeMessageSetWithCachedSizes(const MessageLite* extendee, | 
| 461 |                                           io::CodedOutputStream* output) const { | 
| 462 |     output->SetCur(InternalSerializeMessageSetWithCachedSizesToArray( | 
| 463 |         extendee, target: output->Cur(), stream: output->EpsCopy())); | 
| 464 |   } | 
| 465 |   uint8_t* InternalSerializeMessageSetWithCachedSizesToArray( | 
| 466 |       const MessageLite* extendee, uint8_t* target, | 
| 467 |       io::EpsCopyOutputStream* stream) const; | 
| 468 |  | 
| 469 |   // For backward-compatibility, versions of two of the above methods that | 
| 470 |   // serialize deterministically iff SetDefaultSerializationDeterministic() | 
| 471 |   // has been called. | 
| 472 |   uint8_t* SerializeWithCachedSizesToArray(int start_field_number, | 
| 473 |                                            int end_field_number, | 
| 474 |                                            uint8_t* target) const; | 
| 475 |   uint8_t* SerializeMessageSetWithCachedSizesToArray( | 
| 476 |       const MessageLite* extendee, uint8_t* target) const; | 
| 477 |  | 
| 478 |   // Returns the total serialized size of all the extensions. | 
| 479 |   size_t ByteSize() const; | 
| 480 |  | 
| 481 |   // Like ByteSize() but uses MessageSet format. | 
| 482 |   size_t MessageSetByteSize() const; | 
| 483 |  | 
| 484 |   // Returns (an estimate of) the total number of bytes used for storing the | 
| 485 |   // extensions in memory, excluding sizeof(*this).  If the ExtensionSet is | 
| 486 |   // for a lite message (and thus possibly contains lite messages), the results | 
| 487 |   // are undefined (might work, might crash, might corrupt data, might not even | 
| 488 |   // be linked in).  It's up to the protocol compiler to avoid calling this on | 
| 489 |   // such ExtensionSets (easy enough since lite messages don't implement | 
| 490 |   // SpaceUsed()). | 
| 491 |   size_t SpaceUsedExcludingSelfLong() const; | 
| 492 |  | 
| 493 |   // This method just calls SpaceUsedExcludingSelfLong() but it can not be | 
| 494 |   // inlined because the definition of SpaceUsedExcludingSelfLong() is not | 
| 495 |   // included in lite runtime and when an inline method refers to it MSVC | 
| 496 |   // will complain about unresolved symbols when building the lite runtime | 
| 497 |   // as .dll. | 
| 498 |   int SpaceUsedExcludingSelf() const; | 
| 499 |  | 
| 500 |  private: | 
| 501 |   template <typename Type> | 
| 502 |   friend class PrimitiveTypeTraits; | 
| 503 |  | 
| 504 |   template <typename Type> | 
| 505 |   friend class RepeatedPrimitiveTypeTraits; | 
| 506 |  | 
| 507 |   template <typename Type, bool IsValid(int)> | 
| 508 |   friend class EnumTypeTraits; | 
| 509 |  | 
| 510 |   template <typename Type, bool IsValid(int)> | 
| 511 |   friend class RepeatedEnumTypeTraits; | 
| 512 |  | 
| 513 |   friend class google::protobuf::Reflection; | 
| 514 |  | 
| 515 |   const int32_t& GetRefInt32(int number, const int32_t& default_value) const; | 
| 516 |   const int64_t& GetRefInt64(int number, const int64_t& default_value) const; | 
| 517 |   const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const; | 
| 518 |   const uint64_t& GetRefUInt64(int number, const uint64_t& default_value) const; | 
| 519 |   const float& GetRefFloat(int number, const float& default_value) const; | 
| 520 |   const double& GetRefDouble(int number, const double& default_value) const; | 
| 521 |   const bool& GetRefBool(int number, const bool& default_value) const; | 
| 522 |   const int& GetRefEnum(int number, const int& default_value) const; | 
| 523 |   const int32_t& GetRefRepeatedInt32(int number, int index) const; | 
| 524 |   const int64_t& GetRefRepeatedInt64(int number, int index) const; | 
| 525 |   const uint32_t& GetRefRepeatedUInt32(int number, int index) const; | 
| 526 |   const uint64_t& GetRefRepeatedUInt64(int number, int index) const; | 
| 527 |   const float& GetRefRepeatedFloat(int number, int index) const; | 
| 528 |   const double& GetRefRepeatedDouble(int number, int index) const; | 
| 529 |   const bool& GetRefRepeatedBool(int number, int index) const; | 
| 530 |   const int& GetRefRepeatedEnum(int number, int index) const; | 
| 531 |  | 
| 532 |   // Implementation of _InternalSerialize for non-empty map_. | 
| 533 |   uint8_t* _InternalSerializeImpl(const MessageLite* extendee, | 
| 534 |                                   int start_field_number, int end_field_number, | 
| 535 |                                   uint8_t* target, | 
| 536 |                                   io::EpsCopyOutputStream* stream) const; | 
| 537 |   // Interface of a lazily parsed singular message extension. | 
| 538 |   class PROTOBUF_EXPORT LazyMessageExtension { | 
| 539 |    public: | 
| 540 |     LazyMessageExtension() {} | 
| 541 |     virtual ~LazyMessageExtension() {} | 
| 542 |  | 
| 543 |     virtual LazyMessageExtension* New(Arena* arena) const = 0; | 
| 544 |     virtual const MessageLite& GetMessage(const MessageLite& prototype, | 
| 545 |                                           Arena* arena) const = 0; | 
| 546 |     virtual MessageLite* MutableMessage(const MessageLite& prototype, | 
| 547 |                                         Arena* arena) = 0; | 
| 548 |     virtual void SetAllocatedMessage(MessageLite* message, Arena* arena) = 0; | 
| 549 |     virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message, | 
| 550 |                                                 Arena* arena) = 0; | 
| 551 |     PROTOBUF_NODISCARD virtual MessageLite* ReleaseMessage( | 
| 552 |         const MessageLite& prototype, Arena* arena) = 0; | 
| 553 |     virtual MessageLite* UnsafeArenaReleaseMessage(const MessageLite& prototype, | 
| 554 |                                                    Arena* arena) = 0; | 
| 555 |  | 
| 556 |     virtual bool IsInitialized() const = 0; | 
| 557 |  | 
| 558 |     PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead" ) | 
| 559 |     virtual int ByteSize() const { return internal::ToIntSize(size: ByteSizeLong()); } | 
| 560 |     virtual size_t ByteSizeLong() const = 0; | 
| 561 |     virtual size_t SpaceUsedLong() const = 0; | 
| 562 |  | 
| 563 |     virtual void MergeFrom(const MessageLite* prototype, | 
| 564 |                            const LazyMessageExtension& other, Arena* arena) = 0; | 
| 565 |     virtual void MergeFromMessage(const MessageLite& msg, Arena* arena) = 0; | 
| 566 |     virtual void Clear() = 0; | 
| 567 |  | 
| 568 |     virtual const char* _InternalParse(const Message& prototype, Arena* arena, | 
| 569 |                                        LazyVerifyOption option, const char* ptr, | 
| 570 |                                        ParseContext* ctx) = 0; | 
| 571 |     virtual uint8_t* WriteMessageToArray( | 
| 572 |         const MessageLite* prototype, int number, uint8_t* target, | 
| 573 |         io::EpsCopyOutputStream* stream) const = 0; | 
| 574 |  | 
| 575 |    private: | 
| 576 |     virtual void UnusedKeyMethod();  // Dummy key method to avoid weak vtable. | 
| 577 |  | 
| 578 |     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension); | 
| 579 |   }; | 
| 580 |   // Give access to function defined below to see LazyMessageExtension. | 
| 581 |   friend LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena); | 
| 582 |   struct Extension { | 
| 583 |     // The order of these fields packs Extension into 24 bytes when using 8 | 
| 584 |     // byte alignment. Consider this when adding or removing fields here. | 
| 585 |     union { | 
| 586 |       int32_t int32_t_value; | 
| 587 |       int64_t int64_t_value; | 
| 588 |       uint32_t uint32_t_value; | 
| 589 |       uint64_t uint64_t_value; | 
| 590 |       float float_value; | 
| 591 |       double double_value; | 
| 592 |       bool bool_value; | 
| 593 |       int enum_value; | 
| 594 |       std::string* string_value; | 
| 595 |       MessageLite* message_value; | 
| 596 |       LazyMessageExtension* lazymessage_value; | 
| 597 |  | 
| 598 |       RepeatedField<int32_t>* repeated_int32_t_value; | 
| 599 |       RepeatedField<int64_t>* repeated_int64_t_value; | 
| 600 |       RepeatedField<uint32_t>* repeated_uint32_t_value; | 
| 601 |       RepeatedField<uint64_t>* repeated_uint64_t_value; | 
| 602 |       RepeatedField<float>* repeated_float_value; | 
| 603 |       RepeatedField<double>* repeated_double_value; | 
| 604 |       RepeatedField<bool>* repeated_bool_value; | 
| 605 |       RepeatedField<int>* repeated_enum_value; | 
| 606 |       RepeatedPtrField<std::string>* repeated_string_value; | 
| 607 |       RepeatedPtrField<MessageLite>* repeated_message_value; | 
| 608 |     }; | 
| 609 |  | 
| 610 |     FieldType type; | 
| 611 |     bool is_repeated; | 
| 612 |  | 
| 613 |     // For singular types, indicates if the extension is "cleared".  This | 
| 614 |     // happens when an extension is set and then later cleared by the caller. | 
| 615 |     // We want to keep the Extension object around for reuse, so instead of | 
| 616 |     // removing it from the map, we just set is_cleared = true.  This has no | 
| 617 |     // meaning for repeated types; for those, the size of the RepeatedField | 
| 618 |     // simply becomes zero when cleared. | 
| 619 |     bool is_cleared : 4; | 
| 620 |  | 
| 621 |     // For singular message types, indicates whether lazy parsing is enabled | 
| 622 |     // for this extension. This field is only valid when type == TYPE_MESSAGE | 
| 623 |     // and !is_repeated because we only support lazy parsing for singular | 
| 624 |     // message types currently. If is_lazy = true, the extension is stored in | 
| 625 |     // lazymessage_value. Otherwise, the extension will be message_value. | 
| 626 |     bool is_lazy : 4; | 
| 627 |  | 
| 628 |     // For repeated types, this indicates if the [packed=true] option is set. | 
| 629 |     bool is_packed; | 
| 630 |  | 
| 631 |     // For packed fields, the size of the packed data is recorded here when | 
| 632 |     // ByteSize() is called then used during serialization. | 
| 633 |     // TODO(kenton):  Use atomic<int> when C++ supports it. | 
| 634 |     mutable int cached_size; | 
| 635 |  | 
| 636 |     // The descriptor for this extension, if one exists and is known.  May be | 
| 637 |     // nullptr.  Must not be nullptr if the descriptor for the extension does | 
| 638 |     // not live in the same pool as the descriptor for the containing type. | 
| 639 |     const FieldDescriptor* descriptor; | 
| 640 |  | 
| 641 |     // Some helper methods for operations on a single Extension. | 
| 642 |     uint8_t* InternalSerializeFieldWithCachedSizesToArray( | 
| 643 |         const MessageLite* extendee, const ExtensionSet* extension_set, | 
| 644 |         int number, uint8_t* target, io::EpsCopyOutputStream* stream) const; | 
| 645 |     uint8_t* InternalSerializeMessageSetItemWithCachedSizesToArray( | 
| 646 |         const MessageLite* extendee, const ExtensionSet* extension_set, | 
| 647 |         int number, uint8_t* target, io::EpsCopyOutputStream* stream) const; | 
| 648 |     size_t ByteSize(int number) const; | 
| 649 |     size_t MessageSetItemByteSize(int number) const; | 
| 650 |     void Clear(); | 
| 651 |     int GetSize() const; | 
| 652 |     void Free(); | 
| 653 |     size_t SpaceUsedExcludingSelfLong() const; | 
| 654 |     bool IsInitialized() const; | 
| 655 |   }; | 
| 656 |  | 
| 657 |   // The Extension struct is small enough to be passed by value, so we use it | 
| 658 |   // directly as the value type in mappings rather than use pointers.  We use | 
| 659 |   // sorted maps rather than hash-maps because we expect most ExtensionSets will | 
| 660 |   // only contain a small number of extension.  Also, we want AppendToList and | 
| 661 |   // deterministic serialization to order fields by field number. | 
| 662 |  | 
| 663 |   struct KeyValue { | 
| 664 |     int first; | 
| 665 |     Extension second; | 
| 666 |  | 
| 667 |     struct FirstComparator { | 
| 668 |       bool operator()(const KeyValue& lhs, const KeyValue& rhs) const { | 
| 669 |         return lhs.first < rhs.first; | 
| 670 |       } | 
| 671 |       bool operator()(const KeyValue& lhs, int key) const { | 
| 672 |         return lhs.first < key; | 
| 673 |       } | 
| 674 |       bool operator()(int key, const KeyValue& rhs) const { | 
| 675 |         return key < rhs.first; | 
| 676 |       } | 
| 677 |     }; | 
| 678 |   }; | 
| 679 |  | 
| 680 |   typedef std::map<int, Extension> LargeMap; | 
| 681 |  | 
| 682 |   // Wrapper API that switches between flat-map and LargeMap. | 
| 683 |  | 
| 684 |   // Finds a key (if present) in the ExtensionSet. | 
| 685 |   const Extension* FindOrNull(int key) const; | 
| 686 |   Extension* FindOrNull(int key); | 
| 687 |  | 
| 688 |   // Helper-functions that only inspect the LargeMap. | 
| 689 |   const Extension* FindOrNullInLargeMap(int key) const; | 
| 690 |   Extension* FindOrNullInLargeMap(int key); | 
| 691 |  | 
| 692 |   // Inserts a new (key, Extension) into the ExtensionSet (and returns true), or | 
| 693 |   // finds the already-existing Extension for that key (returns false). | 
| 694 |   // The Extension* will point to the new-or-found Extension. | 
| 695 |   std::pair<Extension*, bool> Insert(int key); | 
| 696 |  | 
| 697 |   // Grows the flat_capacity_. | 
| 698 |   // If flat_capacity_ > kMaximumFlatCapacity, converts to LargeMap. | 
| 699 |   void GrowCapacity(size_t minimum_new_capacity); | 
| 700 |   static constexpr uint16_t kMaximumFlatCapacity = 256; | 
| 701 |   bool is_large() const { return static_cast<int16_t>(flat_size_) < 0; } | 
| 702 |  | 
| 703 |   // Removes a key from the ExtensionSet. | 
| 704 |   void Erase(int key); | 
| 705 |  | 
| 706 |   size_t Size() const { | 
| 707 |     return PROTOBUF_PREDICT_FALSE(is_large()) ? map_.large->size() : flat_size_; | 
| 708 |   } | 
| 709 |  | 
| 710 |   // Similar to std::for_each. | 
| 711 |   // Each Iterator is decomposed into ->first and ->second fields, so | 
| 712 |   // that the KeyValueFunctor can be agnostic vis-a-vis KeyValue-vs-std::pair. | 
| 713 |   template <typename Iterator, typename KeyValueFunctor> | 
| 714 |   static KeyValueFunctor ForEach(Iterator begin, Iterator end, | 
| 715 |                                  KeyValueFunctor func) { | 
| 716 |     for (Iterator it = begin; it != end; ++it) func(it->first, it->second); | 
| 717 |     return std::move(func); | 
| 718 |   } | 
| 719 |  | 
| 720 |   // Applies a functor to the <int, Extension&> pairs in sorted order. | 
| 721 |   template <typename KeyValueFunctor> | 
| 722 |   KeyValueFunctor ForEach(KeyValueFunctor func) { | 
| 723 |     if (PROTOBUF_PREDICT_FALSE(is_large())) { | 
| 724 |       return ForEach(map_.large->begin(), map_.large->end(), std::move(func)); | 
| 725 |     } | 
| 726 |     return ForEach(flat_begin(), flat_end(), std::move(func)); | 
| 727 |   } | 
| 728 |  | 
| 729 |   // Applies a functor to the <int, const Extension&> pairs in sorted order. | 
| 730 |   template <typename KeyValueFunctor> | 
| 731 |   KeyValueFunctor ForEach(KeyValueFunctor func) const { | 
| 732 |     if (PROTOBUF_PREDICT_FALSE(is_large())) { | 
| 733 |       return ForEach(map_.large->begin(), map_.large->end(), std::move(func)); | 
| 734 |     } | 
| 735 |     return ForEach(flat_begin(), flat_end(), std::move(func)); | 
| 736 |   } | 
| 737 |  | 
| 738 |   // Merges existing Extension from other_extension | 
| 739 |   void InternalExtensionMergeFrom(const MessageLite* extendee, int number, | 
| 740 |                                   const Extension& other_extension, | 
| 741 |                                   Arena* other_arena); | 
| 742 |  | 
| 743 |   inline static bool is_packable(WireFormatLite::WireType type) { | 
| 744 |     switch (type) { | 
| 745 |       case WireFormatLite::WIRETYPE_VARINT: | 
| 746 |       case WireFormatLite::WIRETYPE_FIXED64: | 
| 747 |       case WireFormatLite::WIRETYPE_FIXED32: | 
| 748 |         return true; | 
| 749 |       case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: | 
| 750 |       case WireFormatLite::WIRETYPE_START_GROUP: | 
| 751 |       case WireFormatLite::WIRETYPE_END_GROUP: | 
| 752 |         return false; | 
| 753 |  | 
| 754 |         // Do not add a default statement. Let the compiler complain when | 
| 755 |         // someone | 
| 756 |         // adds a new wire type. | 
| 757 |     } | 
| 758 |     PROTOBUF_ASSUME(false);  // switch handles all possible enum values | 
| 759 |     return false; | 
| 760 |   } | 
| 761 |  | 
| 762 |   // Returns true and fills field_number and extension if extension is found. | 
| 763 |   // Note to support packed repeated field compatibility, it also fills whether | 
| 764 |   // the tag on wire is packed, which can be different from | 
| 765 |   // extension->is_packed (whether packed=true is specified). | 
| 766 |   template <typename ExtensionFinder> | 
| 767 |   bool FindExtensionInfoFromTag(uint32_t tag, ExtensionFinder* extension_finder, | 
| 768 |                                 int* field_number, ExtensionInfo* extension, | 
| 769 |                                 bool* was_packed_on_wire) { | 
| 770 |     *field_number = WireFormatLite::GetTagFieldNumber(tag); | 
| 771 |     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); | 
| 772 |     return FindExtensionInfoFromFieldNumber(wire_type, *field_number, | 
| 773 |                                             extension_finder, extension, | 
| 774 |                                             was_packed_on_wire); | 
| 775 |   } | 
| 776 |  | 
| 777 |   // Returns true and fills extension if extension is found. | 
| 778 |   // Note to support packed repeated field compatibility, it also fills whether | 
| 779 |   // the tag on wire is packed, which can be different from | 
| 780 |   // extension->is_packed (whether packed=true is specified). | 
| 781 |   template <typename ExtensionFinder> | 
| 782 |   bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number, | 
| 783 |                                         ExtensionFinder* extension_finder, | 
| 784 |                                         ExtensionInfo* extension, | 
| 785 |                                         bool* was_packed_on_wire) const { | 
| 786 |     if (!extension_finder->Find(field_number, extension)) { | 
| 787 |       return false; | 
| 788 |     } | 
| 789 |  | 
| 790 |     GOOGLE_DCHECK(extension->type > 0 && | 
| 791 |            extension->type <= WireFormatLite::MAX_FIELD_TYPE); | 
| 792 |     auto real_type = static_cast<WireFormatLite::FieldType>(extension->type); | 
| 793 |  | 
| 794 |     WireFormatLite::WireType expected_wire_type = | 
| 795 |         WireFormatLite::WireTypeForFieldType(type: real_type); | 
| 796 |  | 
| 797 |     // Check if this is a packed field. | 
| 798 |     *was_packed_on_wire = false; | 
| 799 |     if (extension->is_repeated && | 
| 800 |         wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED && | 
| 801 |         is_packable(type: expected_wire_type)) { | 
| 802 |       *was_packed_on_wire = true; | 
| 803 |       return true; | 
| 804 |     } | 
| 805 |     // Otherwise the wire type must match. | 
| 806 |     return expected_wire_type == wire_type; | 
| 807 |   } | 
| 808 |  | 
| 809 |   // Find the prototype for a LazyMessage from the extension registry. Returns | 
| 810 |   // null if the extension is not found. | 
| 811 |   const MessageLite* GetPrototypeForLazyMessage(const MessageLite* extendee, | 
| 812 |                                                 int number) const; | 
| 813 |  | 
| 814 |   // Returns true if extension is present and lazy. | 
| 815 |   bool HasLazy(int number) const; | 
| 816 |  | 
| 817 |   // Gets the extension with the given number, creating it if it does not | 
| 818 |   // already exist.  Returns true if the extension did not already exist. | 
| 819 |   bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, | 
| 820 |                          Extension** result); | 
| 821 |  | 
| 822 |   // Gets the repeated extension for the given descriptor, creating it if | 
| 823 |   // it does not exist. | 
| 824 |   Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor); | 
| 825 |  | 
| 826 |   bool FindExtension(int wire_type, uint32_t field, const MessageLite* extendee, | 
| 827 |                      const internal::ParseContext* /*ctx*/, | 
| 828 |                      ExtensionInfo* extension, bool* was_packed_on_wire) { | 
| 829 |     GeneratedExtensionFinder finder(extendee); | 
| 830 |     return FindExtensionInfoFromFieldNumber(wire_type, field_number: field, extension_finder: &finder, | 
| 831 |                                             extension, was_packed_on_wire); | 
| 832 |   } | 
| 833 |   inline bool FindExtension(int wire_type, uint32_t field, | 
| 834 |                             const Message* extendee, | 
| 835 |                             const internal::ParseContext* ctx, | 
| 836 |                             ExtensionInfo* extension, bool* was_packed_on_wire); | 
| 837 |   // Used for MessageSet only | 
| 838 |   const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr, | 
| 839 |                                     const MessageLite* extendee, | 
| 840 |                                     internal::InternalMetadata* metadata, | 
| 841 |                                     internal::ParseContext* ctx) { | 
| 842 |     // Lite MessageSet doesn't implement lazy. | 
| 843 |     return ParseField(tag, ptr, extendee, metadata, ctx); | 
| 844 |   } | 
| 845 |   const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr, | 
| 846 |                                     const Message* extendee, | 
| 847 |                                     internal::InternalMetadata* metadata, | 
| 848 |                                     internal::ParseContext* ctx); | 
| 849 |   const char* ParseMessageSetItem(const char* ptr, const MessageLite* extendee, | 
| 850 |                                   internal::InternalMetadata* metadata, | 
| 851 |                                   internal::ParseContext* ctx); | 
| 852 |   const char* ParseMessageSetItem(const char* ptr, const Message* extendee, | 
| 853 |                                   internal::InternalMetadata* metadata, | 
| 854 |                                   internal::ParseContext* ctx); | 
| 855 |  | 
| 856 |   // Implemented in extension_set_inl.h to keep code out of the header file. | 
| 857 |   template <typename T> | 
| 858 |   const char* ParseFieldWithExtensionInfo(int number, bool was_packed_on_wire, | 
| 859 |                                           const ExtensionInfo& info, | 
| 860 |                                           internal::InternalMetadata* metadata, | 
| 861 |                                           const char* ptr, | 
| 862 |                                           internal::ParseContext* ctx); | 
| 863 |   template <typename Msg, typename T> | 
| 864 |   const char* ParseMessageSetItemTmpl(const char* ptr, const Msg* extendee, | 
| 865 |                                       internal::InternalMetadata* metadata, | 
| 866 |                                       internal::ParseContext* ctx); | 
| 867 |  | 
| 868 |   // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This | 
| 869 |   //   friendship should automatically extend to ExtensionSet::Extension, but | 
| 870 |   //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this | 
| 871 |   //   correctly.  So, we must provide helpers for calling methods of that | 
| 872 |   //   class. | 
| 873 |  | 
| 874 |   // Defined in extension_set_heavy.cc. | 
| 875 |   static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong( | 
| 876 |       RepeatedPtrFieldBase* field); | 
| 877 |  | 
| 878 |   KeyValue* flat_begin() { | 
| 879 |     assert(!is_large()); | 
| 880 |     return map_.flat; | 
| 881 |   } | 
| 882 |   const KeyValue* flat_begin() const { | 
| 883 |     assert(!is_large()); | 
| 884 |     return map_.flat; | 
| 885 |   } | 
| 886 |   KeyValue* flat_end() { | 
| 887 |     assert(!is_large()); | 
| 888 |     return map_.flat + flat_size_; | 
| 889 |   } | 
| 890 |   const KeyValue* flat_end() const { | 
| 891 |     assert(!is_large()); | 
| 892 |     return map_.flat + flat_size_; | 
| 893 |   } | 
| 894 |  | 
| 895 |   Arena* arena_; | 
| 896 |  | 
| 897 |   // Manual memory-management: | 
| 898 |   // map_.flat is an allocated array of flat_capacity_ elements. | 
| 899 |   // [map_.flat, map_.flat + flat_size_) is the currently-in-use prefix. | 
| 900 |   uint16_t flat_capacity_; | 
| 901 |   uint16_t flat_size_;  // negative int16_t(flat_size_) indicates is_large() | 
| 902 |   union AllocatedData { | 
| 903 |     KeyValue* flat; | 
| 904 |  | 
| 905 |     // If flat_capacity_ > kMaximumFlatCapacity, switch to LargeMap, | 
| 906 |     // which guarantees O(n lg n) CPU but larger constant factors. | 
| 907 |     LargeMap* large; | 
| 908 |   } map_; | 
| 909 |  | 
| 910 |   static void DeleteFlatMap(const KeyValue* flat, uint16_t flat_capacity); | 
| 911 |  | 
| 912 |   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); | 
| 913 | }; | 
| 914 |  | 
| 915 | constexpr ExtensionSet::ExtensionSet() | 
| 916 |     : arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{.flat: nullptr} {} | 
| 917 |  | 
| 918 | // These are just for convenience... | 
| 919 | inline void ExtensionSet::SetString(int number, FieldType type, | 
| 920 |                                     std::string value, | 
| 921 |                                     const FieldDescriptor* descriptor) { | 
| 922 |   MutableString(number, type, descriptor)->assign(str: std::move(value)); | 
| 923 | } | 
| 924 | inline void ExtensionSet::SetRepeatedString(int number, int index, | 
| 925 |                                             std::string value) { | 
| 926 |   MutableRepeatedString(number, index)->assign(str: std::move(value)); | 
| 927 | } | 
| 928 | inline void ExtensionSet::AddString(int number, FieldType type, | 
| 929 |                                     std::string value, | 
| 930 |                                     const FieldDescriptor* descriptor) { | 
| 931 |   AddString(number, type, descriptor)->assign(str: std::move(value)); | 
| 932 | } | 
| 933 | // =================================================================== | 
| 934 | // Glue for generated extension accessors | 
| 935 |  | 
| 936 | // ------------------------------------------------------------------- | 
| 937 | // Template magic | 
| 938 |  | 
| 939 | // First we have a set of classes representing "type traits" for different | 
| 940 | // field types.  A type traits class knows how to implement basic accessors | 
| 941 | // for extensions of a particular type given an ExtensionSet.  The signature | 
| 942 | // for a type traits class looks like this: | 
| 943 | // | 
| 944 | //   class TypeTraits { | 
| 945 | //    public: | 
| 946 | //     typedef ? ConstType; | 
| 947 | //     typedef ? MutableType; | 
| 948 | //     // TypeTraits for singular fields and repeated fields will define the | 
| 949 | //     // symbol "Singular" or "Repeated" respectively. These two symbols will | 
| 950 | //     // be used in extension accessors to distinguish between singular | 
| 951 | //     // extensions and repeated extensions. If the TypeTraits for the passed | 
| 952 | //     // in extension doesn't have the expected symbol defined, it means the | 
| 953 | //     // user is passing a repeated extension to a singular accessor, or the | 
| 954 | //     // opposite. In that case the C++ compiler will generate an error | 
| 955 | //     // message "no matching member function" to inform the user. | 
| 956 | //     typedef ? Singular | 
| 957 | //     typedef ? Repeated | 
| 958 | // | 
| 959 | //     static inline ConstType Get(int number, const ExtensionSet& set); | 
| 960 | //     static inline void Set(int number, ConstType value, ExtensionSet* set); | 
| 961 | //     static inline MutableType Mutable(int number, ExtensionSet* set); | 
| 962 | // | 
| 963 | //     // Variants for repeated fields. | 
| 964 | //     static inline ConstType Get(int number, const ExtensionSet& set, | 
| 965 | //                                 int index); | 
| 966 | //     static inline void Set(int number, int index, | 
| 967 | //                            ConstType value, ExtensionSet* set); | 
| 968 | //     static inline MutableType Mutable(int number, int index, | 
| 969 | //                                       ExtensionSet* set); | 
| 970 | //     static inline void Add(int number, ConstType value, ExtensionSet* set); | 
| 971 | //     static inline MutableType Add(int number, ExtensionSet* set); | 
| 972 | //     This is used by the ExtensionIdentifier constructor to register | 
| 973 | //     the extension at dynamic initialization. | 
| 974 | //     template <typename ExtendeeT> | 
| 975 | //     static void Register(int number, FieldType type, bool is_packed); | 
| 976 | //   }; | 
| 977 | // | 
| 978 | // Not all of these methods make sense for all field types.  For example, the | 
| 979 | // "Mutable" methods only make sense for strings and messages, and the | 
| 980 | // repeated methods only make sense for repeated types.  So, each type | 
| 981 | // traits class implements only the set of methods from this signature that it | 
| 982 | // actually supports.  This will cause a compiler error if the user tries to | 
| 983 | // access an extension using a method that doesn't make sense for its type. | 
| 984 | // For example, if "foo" is an extension of type "optional int32", then if you | 
| 985 | // try to write code like: | 
| 986 | //   my_message.MutableExtension(foo) | 
| 987 | // you will get a compile error because PrimitiveTypeTraits<int32_t> does not | 
| 988 | // have a "Mutable()" method. | 
| 989 |  | 
| 990 | // ------------------------------------------------------------------- | 
| 991 | // PrimitiveTypeTraits | 
| 992 |  | 
| 993 | // Since the ExtensionSet has different methods for each primitive type, | 
| 994 | // we must explicitly define the methods of the type traits class for each | 
| 995 | // known type. | 
| 996 | template <typename Type> | 
| 997 | class PrimitiveTypeTraits { | 
| 998 |  public: | 
| 999 |   typedef Type ConstType; | 
| 1000 |   typedef Type MutableType; | 
| 1001 |   typedef PrimitiveTypeTraits<Type> Singular; | 
| 1002 |  | 
| 1003 |   static inline ConstType Get(int number, const ExtensionSet& set, | 
| 1004 |                               ConstType default_value); | 
| 1005 |  | 
| 1006 |   static inline const ConstType* GetPtr(int number, const ExtensionSet& set, | 
| 1007 |                                         const ConstType& default_value); | 
| 1008 |   static inline void Set(int number, FieldType field_type, ConstType value, | 
| 1009 |                          ExtensionSet* set); | 
| 1010 |   template <typename ExtendeeT> | 
| 1011 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1012 |                        LazyEagerVerifyFnType verify_func) { | 
| 1013 |     ExtensionSet::RegisterExtension(extendee: &ExtendeeT::default_instance(), number, | 
| 1014 |                                     type, is_repeated: false, is_packed, verify_func); | 
| 1015 |   } | 
| 1016 | }; | 
| 1017 |  | 
| 1018 | template <typename Type> | 
| 1019 | class RepeatedPrimitiveTypeTraits { | 
| 1020 |  public: | 
| 1021 |   typedef Type ConstType; | 
| 1022 |   typedef Type MutableType; | 
| 1023 |   typedef RepeatedPrimitiveTypeTraits<Type> Repeated; | 
| 1024 |  | 
| 1025 |   typedef RepeatedField<Type> RepeatedFieldType; | 
| 1026 |  | 
| 1027 |   static inline Type Get(int number, const ExtensionSet& set, int index); | 
| 1028 |   static inline const Type* GetPtr(int number, const ExtensionSet& set, | 
| 1029 |                                    int index); | 
| 1030 |   static inline const RepeatedField<ConstType>* GetRepeatedPtr( | 
| 1031 |       int number, const ExtensionSet& set); | 
| 1032 |   static inline void Set(int number, int index, Type value, ExtensionSet* set); | 
| 1033 |   static inline void Add(int number, FieldType field_type, bool is_packed, | 
| 1034 |                          Type value, ExtensionSet* set); | 
| 1035 |  | 
| 1036 |   static inline const RepeatedField<ConstType>& GetRepeated( | 
| 1037 |       int number, const ExtensionSet& set); | 
| 1038 |   static inline RepeatedField<Type>* MutableRepeated(int number, | 
| 1039 |                                                      FieldType field_type, | 
| 1040 |                                                      bool is_packed, | 
| 1041 |                                                      ExtensionSet* set); | 
| 1042 |  | 
| 1043 |   static const RepeatedFieldType* GetDefaultRepeatedField(); | 
| 1044 |   template <typename ExtendeeT> | 
| 1045 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1046 |                        LazyEagerVerifyFnType verify_func) { | 
| 1047 |     ExtensionSet::RegisterExtension(extendee: &ExtendeeT::default_instance(), number, | 
| 1048 |                                     type, is_repeated: true, is_packed, verify_func); | 
| 1049 |   } | 
| 1050 | }; | 
| 1051 |  | 
| 1052 | class PROTOBUF_EXPORT RepeatedPrimitiveDefaults { | 
| 1053 |  private: | 
| 1054 |   template <typename Type> | 
| 1055 |   friend class RepeatedPrimitiveTypeTraits; | 
| 1056 |   static const RepeatedPrimitiveDefaults* default_instance(); | 
| 1057 |   RepeatedField<int32_t> default_repeated_field_int32_t_; | 
| 1058 |   RepeatedField<int64_t> default_repeated_field_int64_t_; | 
| 1059 |   RepeatedField<uint32_t> default_repeated_field_uint32_t_; | 
| 1060 |   RepeatedField<uint64_t> default_repeated_field_uint64_t_; | 
| 1061 |   RepeatedField<double> default_repeated_field_double_; | 
| 1062 |   RepeatedField<float> default_repeated_field_float_; | 
| 1063 |   RepeatedField<bool> default_repeated_field_bool_; | 
| 1064 | }; | 
| 1065 |  | 
| 1066 | #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                           \ | 
| 1067 |   template <>                                                                  \ | 
| 1068 |   inline TYPE PrimitiveTypeTraits<TYPE>::Get(                                  \ | 
| 1069 |       int number, const ExtensionSet& set, TYPE default_value) {               \ | 
| 1070 |     return set.Get##METHOD(number, default_value);                             \ | 
| 1071 |   }                                                                            \ | 
| 1072 |   template <>                                                                  \ | 
| 1073 |   inline const TYPE* PrimitiveTypeTraits<TYPE>::GetPtr(                        \ | 
| 1074 |       int number, const ExtensionSet& set, const TYPE& default_value) {        \ | 
| 1075 |     return &set.GetRef##METHOD(number, default_value);                         \ | 
| 1076 |   }                                                                            \ | 
| 1077 |   template <>                                                                  \ | 
| 1078 |   inline void PrimitiveTypeTraits<TYPE>::Set(int number, FieldType field_type, \ | 
| 1079 |                                              TYPE value, ExtensionSet* set) {  \ | 
| 1080 |     set->Set##METHOD(number, field_type, value, nullptr);                      \ | 
| 1081 |   }                                                                            \ | 
| 1082 |                                                                                \ | 
| 1083 |   template <>                                                                  \ | 
| 1084 |   inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(                          \ | 
| 1085 |       int number, const ExtensionSet& set, int index) {                        \ | 
| 1086 |     return set.GetRepeated##METHOD(number, index);                             \ | 
| 1087 |   }                                                                            \ | 
| 1088 |   template <>                                                                  \ | 
| 1089 |   inline const TYPE* RepeatedPrimitiveTypeTraits<TYPE>::GetPtr(                \ | 
| 1090 |       int number, const ExtensionSet& set, int index) {                        \ | 
| 1091 |     return &set.GetRefRepeated##METHOD(number, index);                         \ | 
| 1092 |   }                                                                            \ | 
| 1093 |   template <>                                                                  \ | 
| 1094 |   inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(                          \ | 
| 1095 |       int number, int index, TYPE value, ExtensionSet* set) {                  \ | 
| 1096 |     set->SetRepeated##METHOD(number, index, value);                            \ | 
| 1097 |   }                                                                            \ | 
| 1098 |   template <>                                                                  \ | 
| 1099 |   inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(                          \ | 
| 1100 |       int number, FieldType field_type, bool is_packed, TYPE value,            \ | 
| 1101 |       ExtensionSet* set) {                                                     \ | 
| 1102 |     set->Add##METHOD(number, field_type, is_packed, value, nullptr);           \ | 
| 1103 |   }                                                                            \ | 
| 1104 |   template <>                                                                  \ | 
| 1105 |   inline const RepeatedField<TYPE>*                                            \ | 
| 1106 |   RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() {               \ | 
| 1107 |     return &RepeatedPrimitiveDefaults::default_instance()                      \ | 
| 1108 |                 ->default_repeated_field_##TYPE##_;                            \ | 
| 1109 |   }                                                                            \ | 
| 1110 |   template <>                                                                  \ | 
| 1111 |   inline const RepeatedField<TYPE>&                                            \ | 
| 1112 |   RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number,                   \ | 
| 1113 |                                                  const ExtensionSet& set) {    \ | 
| 1114 |     return *reinterpret_cast<const RepeatedField<TYPE>*>(                      \ | 
| 1115 |         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));           \ | 
| 1116 |   }                                                                            \ | 
| 1117 |   template <>                                                                  \ | 
| 1118 |   inline const RepeatedField<TYPE>*                                            \ | 
| 1119 |   RepeatedPrimitiveTypeTraits<TYPE>::GetRepeatedPtr(int number,                \ | 
| 1120 |                                                     const ExtensionSet& set) { \ | 
| 1121 |     return &GetRepeated(number, set);                                          \ | 
| 1122 |   }                                                                            \ | 
| 1123 |   template <>                                                                  \ | 
| 1124 |   inline RepeatedField<TYPE>*                                                  \ | 
| 1125 |   RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(                          \ | 
| 1126 |       int number, FieldType field_type, bool is_packed, ExtensionSet* set) {   \ | 
| 1127 |     return reinterpret_cast<RepeatedField<TYPE>*>(                             \ | 
| 1128 |         set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)); \ | 
| 1129 |   } | 
| 1130 |  | 
| 1131 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(int32_t, Int32) | 
| 1132 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64_t, Int64) | 
| 1133 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32_t, UInt32) | 
| 1134 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64_t, UInt64) | 
| 1135 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(float, Float) | 
| 1136 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) | 
| 1137 | PROTOBUF_DEFINE_PRIMITIVE_TYPE(bool, Bool) | 
| 1138 |  | 
| 1139 | #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE | 
| 1140 |  | 
| 1141 | // ------------------------------------------------------------------- | 
| 1142 | // StringTypeTraits | 
| 1143 |  | 
| 1144 | // Strings support both Set() and Mutable(). | 
| 1145 | class PROTOBUF_EXPORT StringTypeTraits { | 
| 1146 |  public: | 
| 1147 |   typedef const std::string& ConstType; | 
| 1148 |   typedef std::string* MutableType; | 
| 1149 |   typedef StringTypeTraits Singular; | 
| 1150 |  | 
| 1151 |   static inline const std::string& Get(int number, const ExtensionSet& set, | 
| 1152 |                                        ConstType default_value) { | 
| 1153 |     return set.GetString(number, default_value); | 
| 1154 |   } | 
| 1155 |   static inline const std::string* GetPtr(int number, const ExtensionSet& set, | 
| 1156 |                                           ConstType default_value) { | 
| 1157 |     return &Get(number, set, default_value); | 
| 1158 |   } | 
| 1159 |   static inline void Set(int number, FieldType field_type, | 
| 1160 |                          const std::string& value, ExtensionSet* set) { | 
| 1161 |     set->SetString(number, type: field_type, value, descriptor: nullptr); | 
| 1162 |   } | 
| 1163 |   static inline std::string* Mutable(int number, FieldType field_type, | 
| 1164 |                                      ExtensionSet* set) { | 
| 1165 |     return set->MutableString(number, type: field_type, descriptor: nullptr); | 
| 1166 |   } | 
| 1167 |   template <typename ExtendeeT> | 
| 1168 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1169 |                        LazyEagerVerifyFnType verify_func) { | 
| 1170 |     ExtensionSet::RegisterExtension(extendee: &ExtendeeT::default_instance(), number, | 
| 1171 |                                     type, is_repeated: false, is_packed, verify_func); | 
| 1172 |   } | 
| 1173 | }; | 
| 1174 |  | 
| 1175 | class PROTOBUF_EXPORT RepeatedStringTypeTraits { | 
| 1176 |  public: | 
| 1177 |   typedef const std::string& ConstType; | 
| 1178 |   typedef std::string* MutableType; | 
| 1179 |   typedef RepeatedStringTypeTraits Repeated; | 
| 1180 |  | 
| 1181 |   typedef RepeatedPtrField<std::string> RepeatedFieldType; | 
| 1182 |  | 
| 1183 |   static inline const std::string& Get(int number, const ExtensionSet& set, | 
| 1184 |                                        int index) { | 
| 1185 |     return set.GetRepeatedString(number, index); | 
| 1186 |   } | 
| 1187 |   static inline const std::string* GetPtr(int number, const ExtensionSet& set, | 
| 1188 |                                           int index) { | 
| 1189 |     return &Get(number, set, index); | 
| 1190 |   } | 
| 1191 |   static inline const RepeatedPtrField<std::string>* GetRepeatedPtr( | 
| 1192 |       int number, const ExtensionSet& set) { | 
| 1193 |     return &GetRepeated(number, set); | 
| 1194 |   } | 
| 1195 |   static inline void Set(int number, int index, const std::string& value, | 
| 1196 |                          ExtensionSet* set) { | 
| 1197 |     set->SetRepeatedString(number, index, value); | 
| 1198 |   } | 
| 1199 |   static inline std::string* Mutable(int number, int index, ExtensionSet* set) { | 
| 1200 |     return set->MutableRepeatedString(number, index); | 
| 1201 |   } | 
| 1202 |   static inline void Add(int number, FieldType field_type, bool /*is_packed*/, | 
| 1203 |                          const std::string& value, ExtensionSet* set) { | 
| 1204 |     set->AddString(number, type: field_type, value, descriptor: nullptr); | 
| 1205 |   } | 
| 1206 |   static inline std::string* Add(int number, FieldType field_type, | 
| 1207 |                                  ExtensionSet* set) { | 
| 1208 |     return set->AddString(number, type: field_type, descriptor: nullptr); | 
| 1209 |   } | 
| 1210 |   static inline const RepeatedPtrField<std::string>& GetRepeated( | 
| 1211 |       int number, const ExtensionSet& set) { | 
| 1212 |     return *reinterpret_cast<const RepeatedPtrField<std::string>*>( | 
| 1213 |         set.GetRawRepeatedField(number, default_value: GetDefaultRepeatedField())); | 
| 1214 |   } | 
| 1215 |  | 
| 1216 |   static inline RepeatedPtrField<std::string>* MutableRepeated( | 
| 1217 |       int number, FieldType field_type, bool is_packed, ExtensionSet* set) { | 
| 1218 |     return reinterpret_cast<RepeatedPtrField<std::string>*>( | 
| 1219 |         set->MutableRawRepeatedField(number, field_type, packed: is_packed, desc: nullptr)); | 
| 1220 |   } | 
| 1221 |  | 
| 1222 |   static const RepeatedFieldType* GetDefaultRepeatedField(); | 
| 1223 |  | 
| 1224 |   template <typename ExtendeeT> | 
| 1225 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1226 |                        LazyEagerVerifyFnType fn) { | 
| 1227 |     ExtensionSet::RegisterExtension(extendee: &ExtendeeT::default_instance(), number, | 
| 1228 |                                     type, is_repeated: true, is_packed, verify_func: fn); | 
| 1229 |   } | 
| 1230 |  | 
| 1231 |  private: | 
| 1232 |   static void InitializeDefaultRepeatedFields(); | 
| 1233 |   static void DestroyDefaultRepeatedFields(); | 
| 1234 | }; | 
| 1235 |  | 
| 1236 | // ------------------------------------------------------------------- | 
| 1237 | // EnumTypeTraits | 
| 1238 |  | 
| 1239 | // ExtensionSet represents enums using integers internally, so we have to | 
| 1240 | // static_cast around. | 
| 1241 | template <typename Type, bool IsValid(int)> | 
| 1242 | class EnumTypeTraits { | 
| 1243 |  public: | 
| 1244 |   typedef Type ConstType; | 
| 1245 |   typedef Type MutableType; | 
| 1246 |   typedef EnumTypeTraits<Type, IsValid> Singular; | 
| 1247 |  | 
| 1248 |   static inline ConstType Get(int number, const ExtensionSet& set, | 
| 1249 |                               ConstType default_value) { | 
| 1250 |     return static_cast<Type>(set.GetEnum(number, default_value)); | 
| 1251 |   } | 
| 1252 |   static inline const ConstType* GetPtr(int number, const ExtensionSet& set, | 
| 1253 |                                         const ConstType& default_value) { | 
| 1254 |     return reinterpret_cast<const Type*>( | 
| 1255 |         &set.GetRefEnum(number, default_value)); | 
| 1256 |   } | 
| 1257 |   static inline void Set(int number, FieldType field_type, ConstType value, | 
| 1258 |                          ExtensionSet* set) { | 
| 1259 |     GOOGLE_DCHECK(IsValid(value)); | 
| 1260 |     set->SetEnum(number, type: field_type, value, descriptor: nullptr); | 
| 1261 |   } | 
| 1262 |   template <typename ExtendeeT> | 
| 1263 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1264 |                        LazyEagerVerifyFnType fn) { | 
| 1265 |     ExtensionSet::RegisterEnumExtension(extendee: &ExtendeeT::default_instance(), number, | 
| 1266 |                                         type, is_repeated: false, is_packed, is_valid: IsValid); | 
| 1267 |   } | 
| 1268 | }; | 
| 1269 |  | 
| 1270 | template <typename Type, bool IsValid(int)> | 
| 1271 | class RepeatedEnumTypeTraits { | 
| 1272 |  public: | 
| 1273 |   typedef Type ConstType; | 
| 1274 |   typedef Type MutableType; | 
| 1275 |   typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated; | 
| 1276 |  | 
| 1277 |   typedef RepeatedField<Type> RepeatedFieldType; | 
| 1278 |  | 
| 1279 |   static inline ConstType Get(int number, const ExtensionSet& set, int index) { | 
| 1280 |     return static_cast<Type>(set.GetRepeatedEnum(number, index)); | 
| 1281 |   } | 
| 1282 |   static inline const ConstType* GetPtr(int number, const ExtensionSet& set, | 
| 1283 |                                         int index) { | 
| 1284 |     return reinterpret_cast<const Type*>( | 
| 1285 |         &set.GetRefRepeatedEnum(number, index)); | 
| 1286 |   } | 
| 1287 |   static inline void Set(int number, int index, ConstType value, | 
| 1288 |                          ExtensionSet* set) { | 
| 1289 |     GOOGLE_DCHECK(IsValid(value)); | 
| 1290 |     set->SetRepeatedEnum(number, index, value); | 
| 1291 |   } | 
| 1292 |   static inline void Add(int number, FieldType field_type, bool is_packed, | 
| 1293 |                          ConstType value, ExtensionSet* set) { | 
| 1294 |     GOOGLE_DCHECK(IsValid(value)); | 
| 1295 |     set->AddEnum(number, type: field_type, packed: is_packed, value, descriptor: nullptr); | 
| 1296 |   } | 
| 1297 |   static inline const RepeatedField<Type>& GetRepeated( | 
| 1298 |       int number, const ExtensionSet& set) { | 
| 1299 |     // Hack: the `Extension` struct stores a RepeatedField<int> for enums. | 
| 1300 |     // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType> | 
| 1301 |     // so we need to do some casting magic. See message.h for similar | 
| 1302 |     // contortions for non-extension fields. | 
| 1303 |     return *reinterpret_cast<const RepeatedField<Type>*>( | 
| 1304 |         set.GetRawRepeatedField(number, default_value: GetDefaultRepeatedField())); | 
| 1305 |   } | 
| 1306 |   static inline const RepeatedField<Type>* GetRepeatedPtr( | 
| 1307 |       int number, const ExtensionSet& set) { | 
| 1308 |     return &GetRepeated(number, set); | 
| 1309 |   } | 
| 1310 |   static inline RepeatedField<Type>* MutableRepeated(int number, | 
| 1311 |                                                      FieldType field_type, | 
| 1312 |                                                      bool is_packed, | 
| 1313 |                                                      ExtensionSet* set) { | 
| 1314 |     return reinterpret_cast<RepeatedField<Type>*>( | 
| 1315 |         set->MutableRawRepeatedField(number, field_type, packed: is_packed, desc: nullptr)); | 
| 1316 |   } | 
| 1317 |  | 
| 1318 |   static const RepeatedFieldType* GetDefaultRepeatedField() { | 
| 1319 |     // Hack: as noted above, repeated enum fields are internally stored as a | 
| 1320 |     // RepeatedField<int>. We need to be able to instantiate global static | 
| 1321 |     // objects to return as default (empty) repeated fields on non-existent | 
| 1322 |     // extensions. We would not be able to know a-priori all of the enum types | 
| 1323 |     // (values of |Type|) to instantiate all of these, so we just re-use | 
| 1324 |     // int32_t's default repeated field object. | 
| 1325 |     return reinterpret_cast<const RepeatedField<Type>*>( | 
| 1326 |         RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField()); | 
| 1327 |   } | 
| 1328 |   template <typename ExtendeeT> | 
| 1329 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1330 |                        LazyEagerVerifyFnType fn) { | 
| 1331 |     ExtensionSet::RegisterEnumExtension(extendee: &ExtendeeT::default_instance(), number, | 
| 1332 |                                         type, is_repeated: true, is_packed, is_valid: IsValid); | 
| 1333 |   } | 
| 1334 | }; | 
| 1335 |  | 
| 1336 | // ------------------------------------------------------------------- | 
| 1337 | // MessageTypeTraits | 
| 1338 |  | 
| 1339 | // ExtensionSet guarantees that when manipulating extensions with message | 
| 1340 | // types, the implementation used will be the compiled-in class representing | 
| 1341 | // that type.  So, we can static_cast down to the exact type we expect. | 
| 1342 | template <typename Type> | 
| 1343 | class MessageTypeTraits { | 
| 1344 |  public: | 
| 1345 |   typedef const Type& ConstType; | 
| 1346 |   typedef Type* MutableType; | 
| 1347 |   typedef MessageTypeTraits<Type> Singular; | 
| 1348 |  | 
| 1349 |   static inline ConstType Get(int number, const ExtensionSet& set, | 
| 1350 |                               ConstType default_value) { | 
| 1351 |     return static_cast<const Type&>(set.GetMessage(number, default_value)); | 
| 1352 |   } | 
| 1353 |   static inline std::nullptr_t GetPtr(int /* number */, | 
| 1354 |                                       const ExtensionSet& /* set */, | 
| 1355 |                                       ConstType /* default_value */) { | 
| 1356 |     // Cannot be implemented because of forward declared messages? | 
| 1357 |     return nullptr; | 
| 1358 |   } | 
| 1359 |   static inline MutableType Mutable(int number, FieldType field_type, | 
| 1360 |                                     ExtensionSet* set) { | 
| 1361 |     return static_cast<Type*>(set->MutableMessage( | 
| 1362 |         number, field_type, Type::default_instance(), nullptr)); | 
| 1363 |   } | 
| 1364 |   static inline void SetAllocated(int number, FieldType field_type, | 
| 1365 |                                   MutableType message, ExtensionSet* set) { | 
| 1366 |     set->SetAllocatedMessage(number, type: field_type, descriptor: nullptr, message); | 
| 1367 |   } | 
| 1368 |   static inline void UnsafeArenaSetAllocated(int number, FieldType field_type, | 
| 1369 |                                              MutableType message, | 
| 1370 |                                              ExtensionSet* set) { | 
| 1371 |     set->UnsafeArenaSetAllocatedMessage(number, type: field_type, descriptor: nullptr, message); | 
| 1372 |   } | 
| 1373 |   PROTOBUF_NODISCARD static inline MutableType Release( | 
| 1374 |       int number, FieldType /* field_type */, ExtensionSet* set) { | 
| 1375 |     return static_cast<Type*>( | 
| 1376 |         set->ReleaseMessage(number, Type::default_instance())); | 
| 1377 |   } | 
| 1378 |   static inline MutableType UnsafeArenaRelease(int number, | 
| 1379 |                                                FieldType /* field_type */, | 
| 1380 |                                                ExtensionSet* set) { | 
| 1381 |     return static_cast<Type*>( | 
| 1382 |         set->UnsafeArenaReleaseMessage(number, Type::default_instance())); | 
| 1383 |   } | 
| 1384 |   template <typename ExtendeeT> | 
| 1385 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1386 |                        LazyEagerVerifyFnType fn) { | 
| 1387 |     ExtensionSet::RegisterMessageExtension(extendee: &ExtendeeT::default_instance(), | 
| 1388 |                                            number, type, is_repeated: false, is_packed, | 
| 1389 |                                            prototype: &Type::default_instance(), verify_func: fn); | 
| 1390 |   } | 
| 1391 | }; | 
| 1392 |  | 
| 1393 | // Used by WireFormatVerify to extract the verify function from the registry. | 
| 1394 | LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn( | 
| 1395 |     const MessageLite* extendee, int number); | 
| 1396 |  | 
| 1397 | // forward declaration. | 
| 1398 | class RepeatedMessageGenericTypeTraits; | 
| 1399 |  | 
| 1400 | template <typename Type> | 
| 1401 | class RepeatedMessageTypeTraits { | 
| 1402 |  public: | 
| 1403 |   typedef const Type& ConstType; | 
| 1404 |   typedef Type* MutableType; | 
| 1405 |   typedef RepeatedMessageTypeTraits<Type> Repeated; | 
| 1406 |  | 
| 1407 |   typedef RepeatedPtrField<Type> RepeatedFieldType; | 
| 1408 |  | 
| 1409 |   static inline ConstType Get(int number, const ExtensionSet& set, int index) { | 
| 1410 |     return static_cast<const Type&>(set.GetRepeatedMessage(number, index)); | 
| 1411 |   } | 
| 1412 |   static inline std::nullptr_t GetPtr(int /* number */, | 
| 1413 |                                       const ExtensionSet& /* set */, | 
| 1414 |                                       int /* index */) { | 
| 1415 |     // Cannot be implemented because of forward declared messages? | 
| 1416 |     return nullptr; | 
| 1417 |   } | 
| 1418 |   static inline std::nullptr_t GetRepeatedPtr(int /* number */, | 
| 1419 |                                               const ExtensionSet& /* set */) { | 
| 1420 |     // Cannot be implemented because of forward declared messages? | 
| 1421 |     return nullptr; | 
| 1422 |   } | 
| 1423 |   static inline MutableType Mutable(int number, int index, ExtensionSet* set) { | 
| 1424 |     return static_cast<Type*>(set->MutableRepeatedMessage(number, index)); | 
| 1425 |   } | 
| 1426 |   static inline MutableType Add(int number, FieldType field_type, | 
| 1427 |                                 ExtensionSet* set) { | 
| 1428 |     return static_cast<Type*>( | 
| 1429 |         set->AddMessage(number, field_type, Type::default_instance(), nullptr)); | 
| 1430 |   } | 
| 1431 |   static inline const RepeatedPtrField<Type>& GetRepeated( | 
| 1432 |       int number, const ExtensionSet& set) { | 
| 1433 |     // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same | 
| 1434 |     // casting hack applies here, because a RepeatedPtrField<MessageLite> | 
| 1435 |     // cannot naturally become a RepeatedPtrType<Type> even though Type is | 
| 1436 |     // presumably a message. google::protobuf::Message goes through similar contortions | 
| 1437 |     // with a reinterpret_cast<>. | 
| 1438 |     return *reinterpret_cast<const RepeatedPtrField<Type>*>( | 
| 1439 |         set.GetRawRepeatedField(number, default_value: GetDefaultRepeatedField())); | 
| 1440 |   } | 
| 1441 |   static inline RepeatedPtrField<Type>* MutableRepeated(int number, | 
| 1442 |                                                         FieldType field_type, | 
| 1443 |                                                         bool is_packed, | 
| 1444 |                                                         ExtensionSet* set) { | 
| 1445 |     return reinterpret_cast<RepeatedPtrField<Type>*>( | 
| 1446 |         set->MutableRawRepeatedField(number, field_type, packed: is_packed, desc: nullptr)); | 
| 1447 |   } | 
| 1448 |  | 
| 1449 |   static const RepeatedFieldType* GetDefaultRepeatedField(); | 
| 1450 |   template <typename ExtendeeT> | 
| 1451 |   static void Register(int number, FieldType type, bool is_packed, | 
| 1452 |                        LazyEagerVerifyFnType fn) { | 
| 1453 |     ExtensionSet::RegisterMessageExtension(extendee: &ExtendeeT::default_instance(), | 
| 1454 |                                            number, type, is_repeated: true, is_packed, | 
| 1455 |                                            prototype: &Type::default_instance(), verify_func: fn); | 
| 1456 |   } | 
| 1457 | }; | 
| 1458 |  | 
| 1459 | template <typename Type> | 
| 1460 | inline const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType* | 
| 1461 | RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() { | 
| 1462 |   static auto instance = OnShutdownDelete(new RepeatedFieldType); | 
| 1463 |   return instance; | 
| 1464 | } | 
| 1465 |  | 
| 1466 | // ------------------------------------------------------------------- | 
| 1467 | // ExtensionIdentifier | 
| 1468 |  | 
| 1469 | // This is the type of actual extension objects.  E.g. if you have: | 
| 1470 | //   extend Foo { | 
| 1471 | //     optional int32 bar = 1234; | 
| 1472 | //   } | 
| 1473 | // then "bar" will be defined in C++ as: | 
| 1474 | //   ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32_t>, 5, false> bar(1234); | 
| 1475 | // | 
| 1476 | // Note that we could, in theory, supply the field number as a template | 
| 1477 | // parameter, and thus make an instance of ExtensionIdentifier have no | 
| 1478 | // actual contents.  However, if we did that, then using an extension | 
| 1479 | // identifier would not necessarily cause the compiler to output any sort | 
| 1480 | // of reference to any symbol defined in the extension's .pb.o file.  Some | 
| 1481 | // linkers will actually drop object files that are not explicitly referenced, | 
| 1482 | // but that would be bad because it would cause this extension to not be | 
| 1483 | // registered at static initialization, and therefore using it would crash. | 
| 1484 |  | 
| 1485 | template <typename ExtendeeType, typename TypeTraitsType, FieldType field_type, | 
| 1486 |           bool is_packed> | 
| 1487 | class ExtensionIdentifier { | 
| 1488 |  public: | 
| 1489 |   typedef TypeTraitsType TypeTraits; | 
| 1490 |   typedef ExtendeeType Extendee; | 
| 1491 |  | 
| 1492 |   ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value, | 
| 1493 |                       LazyEagerVerifyFnType verify_func = nullptr) | 
| 1494 |       : number_(number), default_value_(default_value) { | 
| 1495 |     Register(number, verify_func); | 
| 1496 |   } | 
| 1497 |   inline int number() const { return number_; } | 
| 1498 |   typename TypeTraits::ConstType default_value() const { | 
| 1499 |     return default_value_; | 
| 1500 |   } | 
| 1501 |  | 
| 1502 |   static void Register(int number, LazyEagerVerifyFnType verify_func) { | 
| 1503 |     TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed, | 
| 1504 |                                                 verify_func); | 
| 1505 |   } | 
| 1506 |  | 
| 1507 |   typename TypeTraits::ConstType const& default_value_ref() const { | 
| 1508 |     return default_value_; | 
| 1509 |   } | 
| 1510 |  | 
| 1511 |  private: | 
| 1512 |   const int number_; | 
| 1513 |   typename TypeTraits::ConstType default_value_; | 
| 1514 | }; | 
| 1515 |  | 
| 1516 | // ------------------------------------------------------------------- | 
| 1517 | // Generated accessors | 
| 1518 |  | 
| 1519 |  | 
| 1520 | // Used to retrieve a lazy extension, may return nullptr in some environments. | 
| 1521 | extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension* | 
| 1522 | MaybeCreateLazyExtension(Arena* arena); | 
| 1523 |  | 
| 1524 | }  // namespace internal | 
| 1525 |  | 
| 1526 | // Call this function to ensure that this extensions's reflection is linked into | 
| 1527 | // the binary: | 
| 1528 | // | 
| 1529 | //   google::protobuf::LinkExtensionReflection(Foo::my_extension); | 
| 1530 | // | 
| 1531 | // This will ensure that the following lookup will succeed: | 
| 1532 | // | 
| 1533 | //   DescriptorPool::generated_pool()->FindExtensionByName("Foo.my_extension"); | 
| 1534 | // | 
| 1535 | // This is often relevant for parsing extensions in text mode. | 
| 1536 | // | 
| 1537 | // As a side-effect, it will also guarantee that anything else from the same | 
| 1538 | // .proto file will also be available for lookup in the generated pool. | 
| 1539 | // | 
| 1540 | // This function does not actually register the extension, so it does not need | 
| 1541 | // to be called before the lookup.  However it does need to occur in a function | 
| 1542 | // that cannot be stripped from the binary (ie. it must be reachable from main). | 
| 1543 | // | 
| 1544 | // Best practice is to call this function as close as possible to where the | 
| 1545 | // reflection is actually needed.  This function is very cheap to call, so you | 
| 1546 | // should not need to worry about its runtime overhead except in tight loops (on | 
| 1547 | // x86-64 it compiles into two "mov" instructions). | 
| 1548 | template <typename ExtendeeType, typename TypeTraitsType, | 
| 1549 |           internal::FieldType field_type, bool is_packed> | 
| 1550 | void LinkExtensionReflection( | 
| 1551 |     const google::protobuf::internal::ExtensionIdentifier< | 
| 1552 |         ExtendeeType, TypeTraitsType, field_type, is_packed>& extension) { | 
| 1553 |   internal::StrongReference(extension); | 
| 1554 | } | 
| 1555 |  | 
| 1556 | }  // namespace protobuf | 
| 1557 | }  // namespace google | 
| 1558 |  | 
| 1559 | #include <google/protobuf/port_undef.inc> | 
| 1560 |  | 
| 1561 | #endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__ | 
| 1562 |  |