Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:20

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 //
0012 // This header is logically internal, but is made public because it is used
0013 // from protocol-compiler-generated code, which may reside in other components.
0014 
0015 #ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
0016 #define GOOGLE_PROTOBUF_EXTENSION_SET_H__
0017 
0018 #include <algorithm>
0019 #include <atomic>
0020 #include <cassert>
0021 #include <cstddef>
0022 #include <cstdint>
0023 #include <initializer_list>
0024 #include <string>
0025 #include <type_traits>
0026 #include <utility>
0027 #include <vector>
0028 
0029 #include "google/protobuf/stubs/common.h"
0030 #include "absl/base/call_once.h"
0031 #include "absl/container/btree_map.h"
0032 #include "absl/log/absl_check.h"
0033 #include "google/protobuf/internal_visibility.h"
0034 #include "google/protobuf/port.h"
0035 #include "google/protobuf/io/coded_stream.h"
0036 #include "google/protobuf/message_lite.h"
0037 #include "google/protobuf/parse_context.h"
0038 #include "google/protobuf/repeated_field.h"
0039 #include "google/protobuf/repeated_ptr_field.h"
0040 #include "google/protobuf/wire_format_lite.h"
0041 
0042 // clang-format off
0043 #include "google/protobuf/port_def.inc"  // Must be last
0044 // clang-format on
0045 
0046 #ifdef SWIG
0047 #error "You cannot SWIG proto headers"
0048 #endif
0049 
0050 
0051 namespace google {
0052 namespace protobuf {
0053 class Arena;
0054 class Descriptor;       // descriptor.h
0055 class FieldDescriptor;  // descriptor.h
0056 class DescriptorPool;   // descriptor.h
0057 class MessageLite;      // message_lite.h
0058 class Message;          // message.h
0059 class MessageFactory;   // message.h
0060 class Reflection;       // message.h
0061 class UnknownFieldSet;  // unknown_field_set.h
0062 class FeatureSet;
0063 namespace internal {
0064 struct DescriptorTable;
0065 class FieldSkipper;     // wire_format_lite.h
0066 class ReflectionVisit;  // message_reflection_util.h
0067 class WireFormat;
0068 struct DynamicExtensionInfoHelper;
0069 void InitializeLazyExtensionSet();
0070 }  // namespace internal
0071 }  // namespace protobuf
0072 }  // namespace google
0073 namespace pb {
0074 class CppFeatures;
0075 }  // namespace pb
0076 
0077 namespace google {
0078 namespace protobuf {
0079 namespace internal {
0080 
0081 class InternalMetadata;
0082 
0083 // Used to store values of type WireFormatLite::FieldType without having to
0084 // #include wire_format_lite.h.  Also, ensures that we use only one byte to
0085 // store these values, which is important to keep the layout of
0086 // ExtensionSet::Extension small.
0087 typedef uint8_t FieldType;
0088 
0089 // A function which, given an integer value, returns true if the number
0090 // matches one of the defined values for the corresponding enum type.  This
0091 // is used with RegisterEnumExtension, below.
0092 typedef bool EnumValidityFunc(int number);
0093 
0094 // Version of the above which takes an argument.  This is needed to deal with
0095 // extensions that are not compiled in.
0096 typedef bool EnumValidityFuncWithArg(const void* arg, int number);
0097 
0098 enum class LazyAnnotation : int8_t {
0099   kUndefined = 0,
0100   kLazy = 1,
0101   kEager = 2,
0102 };
0103 
0104 // Information about a registered extension.
0105 struct ExtensionInfo {
0106   constexpr ExtensionInfo() : enum_validity_check() {}
0107   constexpr ExtensionInfo(const MessageLite* extendee, int param_number,
0108                           FieldType type_param, bool isrepeated, bool ispacked)
0109       : message(extendee),
0110         number(param_number),
0111         type(type_param),
0112         is_repeated(isrepeated),
0113         is_packed(ispacked),
0114         enum_validity_check() {}
0115   constexpr ExtensionInfo(const MessageLite* extendee, int param_number,
0116                           FieldType type_param, bool isrepeated, bool ispacked,
0117                           LazyEagerVerifyFnType verify_func,
0118                           LazyAnnotation islazy = LazyAnnotation::kUndefined)
0119       : message(extendee),
0120         number(param_number),
0121         type(type_param),
0122         is_repeated(isrepeated),
0123         is_packed(ispacked),
0124         is_lazy(islazy),
0125         enum_validity_check(),
0126         lazy_eager_verify_func(verify_func) {}
0127 
0128   const MessageLite* message = nullptr;
0129   int number = 0;
0130 
0131   FieldType type = 0;
0132   bool is_repeated = false;
0133   bool is_packed = false;
0134   LazyAnnotation is_lazy = LazyAnnotation::kUndefined;
0135 
0136   struct EnumValidityCheck {
0137     EnumValidityFuncWithArg* func;
0138     const void* arg;
0139   };
0140 
0141   struct MessageInfo {
0142     const MessageLite* prototype;
0143     // The TcParse table used for this object.
0144     // Never null. (except in platforms that don't constant initialize default
0145     // instances)
0146     const internal::TcParseTableBase* tc_table;
0147   };
0148 
0149   union {
0150     EnumValidityCheck enum_validity_check;
0151     MessageInfo message_info;
0152   };
0153 
0154   // The descriptor for this extension, if one exists and is known.  May be
0155   // nullptr.  Must not be nullptr if the descriptor for the extension does not
0156   // live in the same pool as the descriptor for the containing type.
0157   const FieldDescriptor* descriptor = nullptr;
0158 
0159   // If this field is potentially lazy this function can be used as a cheap
0160   // verification of the raw bytes.
0161   // If nullptr then no verification is performed.
0162   LazyEagerVerifyFnType lazy_eager_verify_func = nullptr;
0163 };
0164 
0165 
0166 // An ExtensionFinder is an object which looks up extension definitions.  It
0167 // must implement this method:
0168 //
0169 // bool Find(int number, ExtensionInfo* output);
0170 
0171 // GeneratedExtensionFinder is an ExtensionFinder which finds extensions
0172 // defined in .proto files which have been compiled into the binary.
0173 class PROTOBUF_EXPORT GeneratedExtensionFinder {
0174  public:
0175   explicit GeneratedExtensionFinder(const MessageLite* extendee)
0176       : extendee_(extendee) {}
0177 
0178   // Returns true and fills in *output if found, otherwise returns false.
0179   bool Find(int number, ExtensionInfo* output);
0180 
0181  private:
0182   const MessageLite* extendee_;
0183 };
0184 
0185 // Note:  extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
0186 // finding extensions from a DescriptorPool.
0187 
0188 // This is an internal helper class intended for use within the protocol buffer
0189 // library and generated classes.  Clients should not use it directly.  Instead,
0190 // use the generated accessors such as GetExtension() of the class being
0191 // extended.
0192 //
0193 // This class manages extensions for a protocol message object.  The
0194 // message's HasExtension(), GetExtension(), MutableExtension(), and
0195 // ClearExtension() methods are just thin wrappers around the embedded
0196 // ExtensionSet.  When parsing, if a tag number is encountered which is
0197 // inside one of the message type's extension ranges, the tag is passed
0198 // off to the ExtensionSet for parsing.  Etc.
0199 class PROTOBUF_EXPORT ExtensionSet {
0200  public:
0201   constexpr ExtensionSet() : ExtensionSet(nullptr) {}
0202   ExtensionSet(const ExtensionSet& rhs) = delete;
0203 
0204   // Arena enabled constructors: for internal use only.
0205   ExtensionSet(internal::InternalVisibility, Arena* arena)
0206       : ExtensionSet(arena) {}
0207 
0208   // TODO: make constructor private, and migrate `ArenaInitialized`
0209   // to `InternalVisibility` overloaded constructor(s).
0210   explicit constexpr ExtensionSet(Arena* arena);
0211   ExtensionSet(ArenaInitialized, Arena* arena) : ExtensionSet(arena) {}
0212 
0213   ExtensionSet& operator=(const ExtensionSet&) = delete;
0214   ~ExtensionSet();
0215 
0216   // These are called at startup by protocol-compiler-generated code to
0217   // register known extensions.  The registrations are used by ParseField()
0218   // to look up extensions for parsed field numbers.  Note that dynamic parsing
0219   // does not use ParseField(); only protocol-compiler-generated parsing
0220   // methods do.
0221   static void RegisterExtension(const MessageLite* extendee, int number,
0222                                 FieldType type, bool is_repeated,
0223                                 bool is_packed);
0224   static void RegisterEnumExtension(const MessageLite* extendee, int number,
0225                                     FieldType type, bool is_repeated,
0226                                     bool is_packed, EnumValidityFunc* is_valid);
0227   static void RegisterMessageExtension(const MessageLite* extendee, int number,
0228                                        FieldType type, bool is_repeated,
0229                                        bool is_packed,
0230                                        const MessageLite* prototype,
0231                                        LazyEagerVerifyFnType verify_func,
0232                                        LazyAnnotation is_lazy);
0233 
0234   // In weak descriptor mode we register extensions in two phases.
0235   // This function determines if it is the right time to register a particular
0236   // extension.
0237   // During "preregistration" we only register extensions that have all their
0238   // types linked in.
0239   struct WeakPrototypeRef {
0240     const internal::DescriptorTable* table;
0241     int index;
0242   };
0243   static bool ShouldRegisterAtThisTime(
0244       std::initializer_list<WeakPrototypeRef> messages,
0245       bool is_preregistration);
0246 
0247   // =================================================================
0248 
0249   // Add all fields which are currently present to the given vector.  This
0250   // is useful to implement Reflection::ListFields(). Descriptors are appended
0251   // in increasing tag order.
0252   void AppendToList(const Descriptor* extendee, const DescriptorPool* pool,
0253                     std::vector<const FieldDescriptor*>* output) const;
0254 
0255   // =================================================================
0256   // Accessors
0257   //
0258   // Generated message classes include type-safe templated wrappers around
0259   // these methods.  Generally you should use those rather than call these
0260   // directly, unless you are doing low-level memory management.
0261   //
0262   // When calling any of these accessors, the extension number requested
0263   // MUST exist in the DescriptorPool provided to the constructor.  Otherwise,
0264   // the method will fail an assert.  Normally, though, you would not call
0265   // these directly; you would either call the generated accessors of your
0266   // message class (e.g. GetExtension()) or you would call the accessors
0267   // of the reflection interface.  In both cases, it is impossible to
0268   // trigger this assert failure:  the generated accessors only accept
0269   // linked-in extension types as parameters, while the Reflection interface
0270   // requires you to provide the FieldDescriptor describing the extension.
0271   //
0272   // When calling any of these accessors, a protocol-compiler-generated
0273   // implementation of the extension corresponding to the number MUST
0274   // be linked in, and the FieldDescriptor used to refer to it MUST be
0275   // the one generated by that linked-in code.  Otherwise, the method will
0276   // die on an assert failure.  The message objects returned by the message
0277   // accessors are guaranteed to be of the correct linked-in type.
0278   //
0279   // These methods pretty much match Reflection except that:
0280   // - They're not virtual.
0281   // - They identify fields by number rather than FieldDescriptors.
0282   // - They identify enum values using integers rather than descriptors.
0283   // - Strings provide Mutable() in addition to Set() accessors.
0284 
0285   bool Has(int number) const;
0286   int ExtensionSize(int number) const;  // Size of a repeated extension.
0287   int NumExtensions() const;            // The number of extensions
0288   FieldType ExtensionType(int number) const;
0289   void ClearExtension(int number);
0290 
0291   // singular fields -------------------------------------------------
0292 
0293   int32_t GetInt32(int number, int32_t default_value) const;
0294   int64_t GetInt64(int number, int64_t default_value) const;
0295   uint32_t GetUInt32(int number, uint32_t default_value) const;
0296   uint64_t GetUInt64(int number, uint64_t default_value) const;
0297   float GetFloat(int number, float default_value) const;
0298   double GetDouble(int number, double default_value) const;
0299   bool GetBool(int number, bool default_value) const;
0300   int GetEnum(int number, int default_value) const;
0301   const std::string& GetString(int number,
0302                                const std::string& default_value) const;
0303   const MessageLite& GetMessage(int number,
0304                                 const MessageLite& default_value) const;
0305   const MessageLite& GetMessage(int number, const Descriptor* message_type,
0306                                 MessageFactory* factory) const;
0307 
0308   // |descriptor| may be nullptr so long as it is known that the descriptor for
0309   // the extension lives in the same pool as the descriptor for the containing
0310   // type.
0311 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
0312   void SetInt32(int number, FieldType type, int32_t value, desc);
0313   void SetInt64(int number, FieldType type, int64_t value, desc);
0314   void SetUInt32(int number, FieldType type, uint32_t value, desc);
0315   void SetUInt64(int number, FieldType type, uint64_t value, desc);
0316   void SetFloat(int number, FieldType type, float value, desc);
0317   void SetDouble(int number, FieldType type, double value, desc);
0318   void SetBool(int number, FieldType type, bool value, desc);
0319   void SetEnum(int number, FieldType type, int value, desc);
0320   void SetString(int number, FieldType type, std::string value, desc);
0321   std::string* MutableString(int number, FieldType type, desc);
0322   MessageLite* MutableMessage(int number, FieldType type,
0323                               const MessageLite& prototype, desc);
0324   MessageLite* MutableMessage(const FieldDescriptor* descriptor,
0325                               MessageFactory* factory);
0326   // Adds the given message to the ExtensionSet, taking ownership of the
0327   // message object. Existing message with the same number will be deleted.
0328   // If "message" is nullptr, this is equivalent to "ClearExtension(number)".
0329   void SetAllocatedMessage(int number, FieldType type,
0330                            const FieldDescriptor* descriptor,
0331                            MessageLite* message);
0332   void UnsafeArenaSetAllocatedMessage(int number, FieldType type,
0333                                       const FieldDescriptor* descriptor,
0334                                       MessageLite* message);
0335   PROTOBUF_NODISCARD MessageLite* ReleaseMessage(int number,
0336                                                  const MessageLite& prototype);
0337   MessageLite* UnsafeArenaReleaseMessage(int number,
0338                                          const MessageLite& prototype);
0339 
0340   PROTOBUF_NODISCARD MessageLite* ReleaseMessage(
0341       const FieldDescriptor* descriptor, MessageFactory* factory);
0342   MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor,
0343                                          MessageFactory* factory);
0344 #undef desc
0345   Arena* GetArena() const { return arena_; }
0346 
0347   // repeated fields -------------------------------------------------
0348 
0349   // Fetches a RepeatedField extension by number; returns |default_value|
0350   // if no such extension exists. User should not touch this directly; it is
0351   // used by the GetRepeatedExtension() method.
0352   const void* GetRawRepeatedField(int number, const void* default_value) const;
0353   // Fetches a mutable version of a RepeatedField extension by number,
0354   // instantiating one if none exists. Similar to above, user should not use
0355   // this directly; it underlies MutableRepeatedExtension().
0356   void* MutableRawRepeatedField(int number, FieldType field_type, bool packed,
0357                                 const FieldDescriptor* desc);
0358 
0359   // This is an overload of MutableRawRepeatedField to maintain compatibility
0360   // with old code using a previous API. This version of
0361   // MutableRawRepeatedField() will ABSL_CHECK-fail on a missing extension.
0362   // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
0363   void* MutableRawRepeatedField(int number);
0364 
0365   int32_t GetRepeatedInt32(int number, int index) const;
0366   int64_t GetRepeatedInt64(int number, int index) const;
0367   uint32_t GetRepeatedUInt32(int number, int index) const;
0368   uint64_t GetRepeatedUInt64(int number, int index) const;
0369   float GetRepeatedFloat(int number, int index) const;
0370   double GetRepeatedDouble(int number, int index) const;
0371   bool GetRepeatedBool(int number, int index) const;
0372   int GetRepeatedEnum(int number, int index) const;
0373   const std::string& GetRepeatedString(int number, int index) const;
0374   const MessageLite& GetRepeatedMessage(int number, int index) const;
0375 
0376   void SetRepeatedInt32(int number, int index, int32_t value);
0377   void SetRepeatedInt64(int number, int index, int64_t value);
0378   void SetRepeatedUInt32(int number, int index, uint32_t value);
0379   void SetRepeatedUInt64(int number, int index, uint64_t value);
0380   void SetRepeatedFloat(int number, int index, float value);
0381   void SetRepeatedDouble(int number, int index, double value);
0382   void SetRepeatedBool(int number, int index, bool value);
0383   void SetRepeatedEnum(int number, int index, int value);
0384   void SetRepeatedString(int number, int index, std::string value);
0385   std::string* MutableRepeatedString(int number, int index);
0386   MessageLite* MutableRepeatedMessage(int number, int index);
0387 
0388 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
0389   void AddInt32(int number, FieldType type, bool packed, int32_t value, desc);
0390   void AddInt64(int number, FieldType type, bool packed, int64_t value, desc);
0391   void AddUInt32(int number, FieldType type, bool packed, uint32_t value, desc);
0392   void AddUInt64(int number, FieldType type, bool packed, uint64_t value, desc);
0393   void AddFloat(int number, FieldType type, bool packed, float value, desc);
0394   void AddDouble(int number, FieldType type, bool packed, double value, desc);
0395   void AddBool(int number, FieldType type, bool packed, bool value, desc);
0396   void AddEnum(int number, FieldType type, bool packed, int value, desc);
0397   void AddString(int number, FieldType type, std::string value, desc);
0398   std::string* AddString(int number, FieldType type, desc);
0399   MessageLite* AddMessage(int number, FieldType type,
0400                           const MessageLite& prototype, desc);
0401   MessageLite* AddMessage(const FieldDescriptor* descriptor,
0402                           MessageFactory* factory);
0403   void AddAllocatedMessage(const FieldDescriptor* descriptor,
0404                            MessageLite* new_entry);
0405   void UnsafeArenaAddAllocatedMessage(const FieldDescriptor* descriptor,
0406                                       MessageLite* new_entry);
0407 #undef desc
0408 
0409   void RemoveLast(int number);
0410   PROTOBUF_NODISCARD MessageLite* ReleaseLast(int number);
0411   MessageLite* UnsafeArenaReleaseLast(int number);
0412   void SwapElements(int number, int index1, int index2);
0413 
0414   // =================================================================
0415   // convenience methods for implementing methods of Message
0416   //
0417   // These could all be implemented in terms of the other methods of this
0418   // class, but providing them here helps keep the generated code size down.
0419 
0420   void Clear();
0421   void MergeFrom(const MessageLite* extendee, const ExtensionSet& other);
0422   void Swap(const MessageLite* extendee, ExtensionSet* other);
0423   void InternalSwap(ExtensionSet* other);
0424   void SwapExtension(const MessageLite* extendee, ExtensionSet* other,
0425                      int number);
0426   void UnsafeShallowSwapExtension(ExtensionSet* other, int number);
0427   bool IsInitialized(const MessageLite* extendee) const;
0428 
0429   // Lite parser
0430   const char* ParseField(uint64_t tag, const char* ptr,
0431                          const MessageLite* extendee,
0432                          internal::InternalMetadata* metadata,
0433                          internal::ParseContext* ctx);
0434   // Full parser
0435   const char* ParseField(uint64_t tag, const char* ptr, const Message* extendee,
0436                          internal::InternalMetadata* metadata,
0437                          internal::ParseContext* ctx);
0438   template <typename Msg>
0439   const char* ParseMessageSet(const char* ptr, const Msg* extendee,
0440                               InternalMetadata* metadata,
0441                               internal::ParseContext* ctx) {
0442     while (!ctx->Done(&ptr)) {
0443       uint32_t tag;
0444       ptr = ReadTag(ptr, &tag);
0445       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
0446       if (tag == WireFormatLite::kMessageSetItemStartTag) {
0447         ptr = ctx->ParseGroupInlined(ptr, tag, [&](const char* ptr) {
0448           return ParseMessageSetItem(ptr, extendee, metadata, ctx);
0449         });
0450         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
0451       } else {
0452         if (tag == 0 || (tag & 7) == 4) {
0453           ctx->SetLastTag(tag);
0454           return ptr;
0455         }
0456         ptr = ParseField(tag, ptr, extendee, metadata, ctx);
0457         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
0458       }
0459     }
0460     return ptr;
0461   }
0462 
0463   // Write all extension fields with field numbers in the range
0464   //   [start_field_number, end_field_number)
0465   // to the output stream, using the cached sizes computed when ByteSize() was
0466   // last called.  Note that the range bounds are inclusive-exclusive.
0467   void SerializeWithCachedSizes(const MessageLite* extendee,
0468                                 int start_field_number, int end_field_number,
0469                                 io::CodedOutputStream* output) const {
0470     output->SetCur(_InternalSerialize(extendee, start_field_number,
0471                                       end_field_number, output->Cur(),
0472                                       output->EpsCopy()));
0473   }
0474 
0475   // Same as SerializeWithCachedSizes, but without any bounds checking.
0476   // The caller must ensure that target has sufficient capacity for the
0477   // serialized extensions.
0478   //
0479   // Returns a pointer past the last written byte.
0480 
0481   uint8_t* _InternalSerialize(const MessageLite* extendee,
0482                               int start_field_number, int end_field_number,
0483                               uint8_t* target,
0484                               io::EpsCopyOutputStream* stream) const {
0485     if (flat_size_ == 0) {
0486       assert(!is_large());
0487       return target;
0488     }
0489     return _InternalSerializeImpl(extendee, start_field_number,
0490                                   end_field_number, target, stream);
0491   }
0492 
0493   // Like above but serializes in MessageSet format.
0494   void SerializeMessageSetWithCachedSizes(const MessageLite* extendee,
0495                                           io::CodedOutputStream* output) const {
0496     output->SetCur(InternalSerializeMessageSetWithCachedSizesToArray(
0497         extendee, output->Cur(), output->EpsCopy()));
0498   }
0499   uint8_t* InternalSerializeMessageSetWithCachedSizesToArray(
0500       const MessageLite* extendee, uint8_t* target,
0501       io::EpsCopyOutputStream* stream) const;
0502 
0503   // For backward-compatibility, versions of two of the above methods that
0504   // serialize deterministically iff SetDefaultSerializationDeterministic()
0505   // has been called.
0506   uint8_t* SerializeWithCachedSizesToArray(int start_field_number,
0507                                            int end_field_number,
0508                                            uint8_t* target) const;
0509   uint8_t* SerializeMessageSetWithCachedSizesToArray(
0510       const MessageLite* extendee, uint8_t* target) const;
0511 
0512   // Returns the total serialized size of all the extensions.
0513   size_t ByteSize() const;
0514 
0515   // Like ByteSize() but uses MessageSet format.
0516   size_t MessageSetByteSize() const;
0517 
0518   // Returns (an estimate of) the total number of bytes used for storing the
0519   // extensions in memory, excluding sizeof(*this).  If the ExtensionSet is
0520   // for a lite message (and thus possibly contains lite messages), the results
0521   // are undefined (might work, might crash, might corrupt data, might not even
0522   // be linked in).  It's up to the protocol compiler to avoid calling this on
0523   // such ExtensionSets (easy enough since lite messages don't implement
0524   // SpaceUsed()).
0525   size_t SpaceUsedExcludingSelfLong() const;
0526 
0527   // This method just calls SpaceUsedExcludingSelfLong() but it can not be
0528   // inlined because the definition of SpaceUsedExcludingSelfLong() is not
0529   // included in lite runtime and when an inline method refers to it MSVC
0530   // will complain about unresolved symbols when building the lite runtime
0531   // as .dll.
0532   int SpaceUsedExcludingSelf() const;
0533 
0534  private:
0535   template <typename Type>
0536   friend class PrimitiveTypeTraits;
0537 
0538   template <typename Type>
0539   friend class RepeatedPrimitiveTypeTraits;
0540 
0541   template <typename Type, bool IsValid(int)>
0542   friend class EnumTypeTraits;
0543 
0544   template <typename Type, bool IsValid(int)>
0545   friend class RepeatedEnumTypeTraits;
0546 
0547   friend class google::protobuf::Reflection;
0548   friend class google::protobuf::internal::ReflectionVisit;
0549   friend struct google::protobuf::internal::DynamicExtensionInfoHelper;
0550   friend class google::protobuf::internal::WireFormat;
0551 
0552   friend void internal::InitializeLazyExtensionSet();
0553 
0554   const int32_t& GetRefInt32(int number, const int32_t& default_value) const;
0555   const int64_t& GetRefInt64(int number, const int64_t& default_value) const;
0556   const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const;
0557   const uint64_t& GetRefUInt64(int number, const uint64_t& default_value) const;
0558   const float& GetRefFloat(int number, const float& default_value) const;
0559   const double& GetRefDouble(int number, const double& default_value) const;
0560   const bool& GetRefBool(int number, const bool& default_value) const;
0561   const int& GetRefEnum(int number, const int& default_value) const;
0562   const int32_t& GetRefRepeatedInt32(int number, int index) const;
0563   const int64_t& GetRefRepeatedInt64(int number, int index) const;
0564   const uint32_t& GetRefRepeatedUInt32(int number, int index) const;
0565   const uint64_t& GetRefRepeatedUInt64(int number, int index) const;
0566   const float& GetRefRepeatedFloat(int number, int index) const;
0567   const double& GetRefRepeatedDouble(int number, int index) const;
0568   const bool& GetRefRepeatedBool(int number, int index) const;
0569   const int& GetRefRepeatedEnum(int number, int index) const;
0570 
0571   // Implementation of _InternalSerialize for non-empty map_.
0572   uint8_t* _InternalSerializeImpl(const MessageLite* extendee,
0573                                   int start_field_number, int end_field_number,
0574                                   uint8_t* target,
0575                                   io::EpsCopyOutputStream* stream) const;
0576   // Interface of a lazily parsed singular message extension.
0577   class PROTOBUF_EXPORT LazyMessageExtension {
0578    public:
0579     LazyMessageExtension() = default;
0580     LazyMessageExtension(const LazyMessageExtension&) = delete;
0581     LazyMessageExtension& operator=(const LazyMessageExtension&) = delete;
0582     virtual ~LazyMessageExtension() = default;
0583 
0584     virtual LazyMessageExtension* New(Arena* arena) const = 0;
0585     virtual const MessageLite& GetMessage(const MessageLite& prototype,
0586                                           Arena* arena) const = 0;
0587     virtual const MessageLite& GetMessageIgnoreUnparsed(
0588         const MessageLite& prototype, Arena* arena) const = 0;
0589     virtual MessageLite* MutableMessage(const MessageLite& prototype,
0590                                         Arena* arena) = 0;
0591     virtual void SetAllocatedMessage(MessageLite* message, Arena* arena) = 0;
0592     virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message,
0593                                                 Arena* arena) = 0;
0594     PROTOBUF_NODISCARD virtual MessageLite* ReleaseMessage(
0595         const MessageLite& prototype, Arena* arena) = 0;
0596     virtual MessageLite* UnsafeArenaReleaseMessage(const MessageLite& prototype,
0597                                                    Arena* arena) = 0;
0598 
0599     virtual bool IsInitialized(const MessageLite* prototype,
0600                                Arena* arena) const = 0;
0601     virtual bool IsEagerSerializeSafe(const MessageLite* prototype,
0602                                       Arena* arena) const = 0;
0603 
0604     [[deprecated("Please use ByteSizeLong() instead")]] virtual int ByteSize()
0605         const {
0606       return internal::ToIntSize(ByteSizeLong());
0607     }
0608     virtual size_t ByteSizeLong() const = 0;
0609     virtual size_t SpaceUsedLong() const = 0;
0610 
0611     virtual void MergeFrom(const MessageLite* prototype,
0612                            const LazyMessageExtension& other, Arena* arena,
0613                            Arena* other_arena) = 0;
0614     virtual void MergeFromMessage(const MessageLite& msg, Arena* arena) = 0;
0615     virtual void Clear() = 0;
0616 
0617     virtual const char* _InternalParse(const MessageLite& prototype,
0618                                        Arena* arena, const char* ptr,
0619                                        ParseContext* ctx) = 0;
0620     virtual uint8_t* WriteMessageToArray(
0621         const MessageLite* prototype, int number, uint8_t* target,
0622         io::EpsCopyOutputStream* stream) const = 0;
0623 
0624    private:
0625     virtual void UnusedKeyMethod();  // Dummy key method to avoid weak vtable.
0626   };
0627   // Give access to function defined below to see LazyMessageExtension.
0628   static LazyMessageExtension* MaybeCreateLazyExtensionImpl(Arena* arena);
0629   static LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena) {
0630     auto* f = maybe_create_lazy_extension_.load(std::memory_order_relaxed);
0631     return f != nullptr ? f(arena) : nullptr;
0632   }
0633   static std::atomic<LazyMessageExtension* (*)(Arena* arena)>
0634       maybe_create_lazy_extension_;
0635   struct Extension {
0636     // The order of these fields packs Extension into 24 bytes when using 8
0637     // byte alignment. Consider this when adding or removing fields here.
0638     union {
0639       int32_t int32_t_value;
0640       int64_t int64_t_value;
0641       uint32_t uint32_t_value;
0642       uint64_t uint64_t_value;
0643       float float_value;
0644       double double_value;
0645       bool bool_value;
0646       int enum_value;
0647       std::string* string_value;
0648       MessageLite* message_value;
0649       LazyMessageExtension* lazymessage_value;
0650 
0651       RepeatedField<int32_t>* repeated_int32_t_value;
0652       RepeatedField<int64_t>* repeated_int64_t_value;
0653       RepeatedField<uint32_t>* repeated_uint32_t_value;
0654       RepeatedField<uint64_t>* repeated_uint64_t_value;
0655       RepeatedField<float>* repeated_float_value;
0656       RepeatedField<double>* repeated_double_value;
0657       RepeatedField<bool>* repeated_bool_value;
0658       RepeatedField<int>* repeated_enum_value;
0659       RepeatedPtrField<std::string>* repeated_string_value;
0660       RepeatedPtrField<MessageLite>* repeated_message_value;
0661     };
0662 
0663     FieldType type;
0664     bool is_repeated;
0665 
0666     // For singular types, indicates if the extension is "cleared".  This
0667     // happens when an extension is set and then later cleared by the caller.
0668     // We want to keep the Extension object around for reuse, so instead of
0669     // removing it from the map, we just set is_cleared = true.  This has no
0670     // meaning for repeated types; for those, the size of the RepeatedField
0671     // simply becomes zero when cleared.
0672     bool is_cleared : 4;
0673 
0674     // For singular message types, indicates whether lazy parsing is enabled
0675     // for this extension. This field is only valid when type == TYPE_MESSAGE
0676     // and !is_repeated because we only support lazy parsing for singular
0677     // message types currently. If is_lazy = true, the extension is stored in
0678     // lazymessage_value. Otherwise, the extension will be message_value.
0679     bool is_lazy : 4;
0680 
0681     // For repeated types, this indicates if the [packed=true] option is set.
0682     bool is_packed;
0683 
0684     // For packed fields, the size of the packed data is recorded here when
0685     // ByteSize() is called then used during serialization.
0686     // TODO:  Use atomic<int> when C++ supports it.
0687     mutable int cached_size;
0688 
0689     // The descriptor for this extension, if one exists and is known.  May be
0690     // nullptr.  Must not be nullptr if the descriptor for the extension does
0691     // not live in the same pool as the descriptor for the containing type.
0692     const FieldDescriptor* descriptor;
0693 
0694     // Some helper methods for operations on a single Extension.
0695     uint8_t* InternalSerializeFieldWithCachedSizesToArray(
0696         const MessageLite* extendee, const ExtensionSet* extension_set,
0697         int number, uint8_t* target, io::EpsCopyOutputStream* stream) const;
0698     uint8_t* InternalSerializeMessageSetItemWithCachedSizesToArray(
0699         const MessageLite* extendee, const ExtensionSet* extension_set,
0700         int number, uint8_t* target, io::EpsCopyOutputStream* stream) const;
0701     size_t ByteSize(int number) const;
0702     size_t MessageSetItemByteSize(int number) const;
0703     void Clear();
0704     int GetSize() const;
0705     void Free();
0706     size_t SpaceUsedExcludingSelfLong() const;
0707     bool IsInitialized(const ExtensionSet* ext_set, const MessageLite* extendee,
0708                        int number, Arena* arena) const;
0709   };
0710 
0711   // The Extension struct is small enough to be passed by value, so we use it
0712   // directly as the value type in mappings rather than use pointers.  We use
0713   // sorted maps rather than hash-maps because we expect most ExtensionSets will
0714   // only contain a small number of extension.  Also, we want AppendToList and
0715   // deterministic serialization to order fields by field number.
0716 
0717   struct KeyValue {
0718     int first;
0719     Extension second;
0720 
0721     struct FirstComparator {
0722       bool operator()(const KeyValue& lhs, const KeyValue& rhs) const {
0723         return lhs.first < rhs.first;
0724       }
0725       bool operator()(const KeyValue& lhs, int key) const {
0726         return lhs.first < key;
0727       }
0728       bool operator()(int key, const KeyValue& rhs) const {
0729         return key < rhs.first;
0730       }
0731     };
0732   };
0733 
0734   using LargeMap = absl::btree_map<int, Extension>;
0735 
0736   // Wrapper API that switches between flat-map and LargeMap.
0737 
0738   // Finds a key (if present) in the ExtensionSet.
0739   const Extension* FindOrNull(int key) const;
0740   Extension* FindOrNull(int key);
0741 
0742   // Helper-functions that only inspect the LargeMap.
0743   const Extension* FindOrNullInLargeMap(int key) const;
0744   Extension* FindOrNullInLargeMap(int key);
0745 
0746   // Inserts a new (key, Extension) into the ExtensionSet (and returns true), or
0747   // finds the already-existing Extension for that key (returns false).
0748   // The Extension* will point to the new-or-found Extension.
0749   std::pair<Extension*, bool> Insert(int key);
0750 
0751   // Grows the flat_capacity_.
0752   // If flat_capacity_ > kMaximumFlatCapacity, converts to LargeMap.
0753   void GrowCapacity(size_t minimum_new_capacity);
0754   static constexpr uint16_t kMaximumFlatCapacity = 256;
0755   bool is_large() const { return static_cast<int16_t>(flat_size_) < 0; }
0756 
0757   // Removes a key from the ExtensionSet.
0758   void Erase(int key);
0759 
0760   size_t Size() const {
0761     return PROTOBUF_PREDICT_FALSE(is_large()) ? map_.large->size() : flat_size_;
0762   }
0763 
0764   // Similar to std::for_each.
0765   // Each Iterator is decomposed into ->first and ->second fields, so
0766   // that the KeyValueFunctor can be agnostic vis-a-vis KeyValue-vs-std::pair.
0767   template <typename Iterator, typename KeyValueFunctor>
0768   static KeyValueFunctor ForEach(Iterator begin, Iterator end,
0769                                  KeyValueFunctor func) {
0770     for (Iterator it = begin; it != end; ++it) func(it->first, it->second);
0771     return std::move(func);
0772   }
0773 
0774   // Applies a functor to the <int, Extension&> pairs in sorted order.
0775   template <typename KeyValueFunctor>
0776   KeyValueFunctor ForEach(KeyValueFunctor func) {
0777     if (PROTOBUF_PREDICT_FALSE(is_large())) {
0778       return ForEach(map_.large->begin(), map_.large->end(), std::move(func));
0779     }
0780     return ForEach(flat_begin(), flat_end(), std::move(func));
0781   }
0782 
0783   // Applies a functor to the <int, const Extension&> pairs in sorted order.
0784   template <typename KeyValueFunctor>
0785   KeyValueFunctor ForEach(KeyValueFunctor func) const {
0786     if (PROTOBUF_PREDICT_FALSE(is_large())) {
0787       return ForEach(map_.large->begin(), map_.large->end(), std::move(func));
0788     }
0789     return ForEach(flat_begin(), flat_end(), std::move(func));
0790   }
0791 
0792   // Merges existing Extension from other_extension
0793   void InternalExtensionMergeFrom(const MessageLite* extendee, int number,
0794                                   const Extension& other_extension,
0795                                   Arena* other_arena);
0796 
0797   inline static bool is_packable(WireFormatLite::WireType type) {
0798     switch (type) {
0799       case WireFormatLite::WIRETYPE_VARINT:
0800       case WireFormatLite::WIRETYPE_FIXED64:
0801       case WireFormatLite::WIRETYPE_FIXED32:
0802         return true;
0803       case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
0804       case WireFormatLite::WIRETYPE_START_GROUP:
0805       case WireFormatLite::WIRETYPE_END_GROUP:
0806         return false;
0807 
0808         // Do not add a default statement. Let the compiler complain when
0809         // someone
0810         // adds a new wire type.
0811     }
0812     Unreachable();  // switch handles all possible enum values
0813     return false;
0814   }
0815 
0816   // Returns true and fills field_number and extension if extension is found.
0817   // Note to support packed repeated field compatibility, it also fills whether
0818   // the tag on wire is packed, which can be different from
0819   // extension->is_packed (whether packed=true is specified).
0820   template <typename ExtensionFinder>
0821   bool FindExtensionInfoFromTag(uint32_t tag, ExtensionFinder* extension_finder,
0822                                 int* field_number, ExtensionInfo* extension,
0823                                 bool* was_packed_on_wire) {
0824     *field_number = WireFormatLite::GetTagFieldNumber(tag);
0825     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
0826     return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
0827                                             extension_finder, extension,
0828                                             was_packed_on_wire);
0829   }
0830 
0831   // Returns true and fills extension if extension is found.
0832   // Note to support packed repeated field compatibility, it also fills whether
0833   // the tag on wire is packed, which can be different from
0834   // extension->is_packed (whether packed=true is specified).
0835   template <typename ExtensionFinder>
0836   bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number,
0837                                         ExtensionFinder* extension_finder,
0838                                         ExtensionInfo* extension,
0839                                         bool* was_packed_on_wire) const {
0840     if (!extension_finder->Find(field_number, extension)) {
0841       return false;
0842     }
0843 
0844     ABSL_DCHECK(extension->type > 0 &&
0845                 extension->type <= WireFormatLite::MAX_FIELD_TYPE);
0846     auto real_type = static_cast<WireFormatLite::FieldType>(extension->type);
0847 
0848     WireFormatLite::WireType expected_wire_type =
0849         WireFormatLite::WireTypeForFieldType(real_type);
0850 
0851     // Check if this is a packed field.
0852     *was_packed_on_wire = false;
0853     if (extension->is_repeated &&
0854         wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
0855         is_packable(expected_wire_type)) {
0856       *was_packed_on_wire = true;
0857       return true;
0858     }
0859     // Otherwise the wire type must match.
0860     return expected_wire_type == wire_type;
0861   }
0862 
0863   // Find the prototype for a LazyMessage from the extension registry. Returns
0864   // null if the extension is not found.
0865   const MessageLite* GetPrototypeForLazyMessage(const MessageLite* extendee,
0866                                                 int number) const;
0867 
0868   // Returns true if extension is present and lazy.
0869   bool HasLazy(int number) const;
0870 
0871   // Gets the extension with the given number, creating it if it does not
0872   // already exist.  Returns true if the extension did not already exist.
0873   bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
0874                          Extension** result);
0875 
0876   // Gets the repeated extension for the given descriptor, creating it if
0877   // it does not exist.
0878   Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor);
0879 
0880   bool FindExtension(int wire_type, uint32_t field, const MessageLite* extendee,
0881                      const internal::ParseContext* /*ctx*/,
0882                      ExtensionInfo* extension, bool* was_packed_on_wire) {
0883     GeneratedExtensionFinder finder(extendee);
0884     return FindExtensionInfoFromFieldNumber(wire_type, field, &finder,
0885                                             extension, was_packed_on_wire);
0886   }
0887   inline bool FindExtension(int wire_type, uint32_t field,
0888                             const Message* extendee,
0889                             const internal::ParseContext* ctx,
0890                             ExtensionInfo* extension, bool* was_packed_on_wire);
0891   // Used for MessageSet only
0892   const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr,
0893                                     const MessageLite* extendee,
0894                                     internal::InternalMetadata* metadata,
0895                                     internal::ParseContext* ctx) {
0896     // Lite MessageSet doesn't implement lazy.
0897     return ParseField(tag, ptr, extendee, metadata, ctx);
0898   }
0899   const char* ParseFieldMaybeLazily(uint64_t tag, const char* ptr,
0900                                     const Message* extendee,
0901                                     internal::InternalMetadata* metadata,
0902                                     internal::ParseContext* ctx);
0903   const char* ParseMessageSetItem(const char* ptr, const MessageLite* extendee,
0904                                   internal::InternalMetadata* metadata,
0905                                   internal::ParseContext* ctx);
0906   const char* ParseMessageSetItem(const char* ptr, const Message* extendee,
0907                                   internal::InternalMetadata* metadata,
0908                                   internal::ParseContext* ctx);
0909 
0910   // Implemented in extension_set_inl.h to keep code out of the header file.
0911   template <typename T>
0912   const char* ParseFieldWithExtensionInfo(int number, bool was_packed_on_wire,
0913                                           const ExtensionInfo& info,
0914                                           internal::InternalMetadata* metadata,
0915                                           const char* ptr,
0916                                           internal::ParseContext* ctx);
0917   template <typename Msg, typename T>
0918   const char* ParseMessageSetItemTmpl(const char* ptr, const Msg* extendee,
0919                                       internal::InternalMetadata* metadata,
0920                                       internal::ParseContext* ctx);
0921 
0922   // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
0923   //   friendship should automatically extend to ExtensionSet::Extension, but
0924   //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
0925   //   correctly.  So, we must provide helpers for calling methods of that
0926   //   class.
0927 
0928   // Defined in extension_set_heavy.cc.
0929   static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong(
0930       RepeatedPtrFieldBase* field);
0931 
0932   KeyValue* flat_begin() {
0933     assert(!is_large());
0934     return map_.flat;
0935   }
0936   const KeyValue* flat_begin() const {
0937     assert(!is_large());
0938     return map_.flat;
0939   }
0940   KeyValue* flat_end() {
0941     assert(!is_large());
0942     return map_.flat + flat_size_;
0943   }
0944   const KeyValue* flat_end() const {
0945     assert(!is_large());
0946     return map_.flat + flat_size_;
0947   }
0948 
0949   Arena* arena_;
0950 
0951   // Manual memory-management:
0952   // map_.flat is an allocated array of flat_capacity_ elements.
0953   // [map_.flat, map_.flat + flat_size_) is the currently-in-use prefix.
0954   uint16_t flat_capacity_;
0955   uint16_t flat_size_;  // negative int16_t(flat_size_) indicates is_large()
0956   union AllocatedData {
0957     KeyValue* flat;
0958 
0959     // If flat_capacity_ > kMaximumFlatCapacity, switch to LargeMap,
0960     // which guarantees O(n lg n) CPU but larger constant factors.
0961     LargeMap* large;
0962   } map_;
0963 
0964   static void DeleteFlatMap(const KeyValue* flat, uint16_t flat_capacity);
0965 };
0966 
0967 constexpr ExtensionSet::ExtensionSet(Arena* arena)
0968     : arena_(arena), flat_capacity_(0), flat_size_(0), map_{nullptr} {}
0969 
0970 // These are just for convenience...
0971 inline void ExtensionSet::SetString(int number, FieldType type,
0972                                     std::string value,
0973                                     const FieldDescriptor* descriptor) {
0974   MutableString(number, type, descriptor)->assign(std::move(value));
0975 }
0976 inline void ExtensionSet::SetRepeatedString(int number, int index,
0977                                             std::string value) {
0978   MutableRepeatedString(number, index)->assign(std::move(value));
0979 }
0980 inline void ExtensionSet::AddString(int number, FieldType type,
0981                                     std::string value,
0982                                     const FieldDescriptor* descriptor) {
0983   AddString(number, type, descriptor)->assign(std::move(value));
0984 }
0985 // ===================================================================
0986 // Glue for generated extension accessors
0987 
0988 // -------------------------------------------------------------------
0989 // Template magic
0990 
0991 // First we have a set of classes representing "type traits" for different
0992 // field types.  A type traits class knows how to implement basic accessors
0993 // for extensions of a particular type given an ExtensionSet.  The signature
0994 // for a type traits class looks like this:
0995 //
0996 //   class TypeTraits {
0997 //    public:
0998 //     typedef ? ConstType;
0999 //     typedef ? MutableType;
1000 //     // TypeTraits for singular fields and repeated fields will define the
1001 //     // symbol "Singular" or "Repeated" respectively. These two symbols will
1002 //     // be used in extension accessors to distinguish between singular
1003 //     // extensions and repeated extensions. If the TypeTraits for the passed
1004 //     // in extension doesn't have the expected symbol defined, it means the
1005 //     // user is passing a repeated extension to a singular accessor, or the
1006 //     // opposite. In that case the C++ compiler will generate an error
1007 //     // message "no matching member function" to inform the user.
1008 //     typedef ? Singular
1009 //     typedef ? Repeated
1010 //
1011 //     static inline ConstType Get(int number, const ExtensionSet& set);
1012 //     static inline void Set(int number, ConstType value, ExtensionSet* set);
1013 //     static inline MutableType Mutable(int number, ExtensionSet* set);
1014 //
1015 //     // Variants for repeated fields.
1016 //     static inline ConstType Get(int number, const ExtensionSet& set,
1017 //                                 int index);
1018 //     static inline void Set(int number, int index,
1019 //                            ConstType value, ExtensionSet* set);
1020 //     static inline MutableType Mutable(int number, int index,
1021 //                                       ExtensionSet* set);
1022 //     static inline void Add(int number, ConstType value, ExtensionSet* set);
1023 //     static inline MutableType Add(int number, ExtensionSet* set);
1024 //     This is used by the ExtensionIdentifier constructor to register
1025 //     the extension at dynamic initialization.
1026 //   };
1027 //
1028 // Not all of these methods make sense for all field types.  For example, the
1029 // "Mutable" methods only make sense for strings and messages, and the
1030 // repeated methods only make sense for repeated types.  So, each type
1031 // traits class implements only the set of methods from this signature that it
1032 // actually supports.  This will cause a compiler error if the user tries to
1033 // access an extension using a method that doesn't make sense for its type.
1034 // For example, if "foo" is an extension of type "optional int32", then if you
1035 // try to write code like:
1036 //   my_message.MutableExtension(foo)
1037 // you will get a compile error because PrimitiveTypeTraits<int32_t> does not
1038 // have a "Mutable()" method.
1039 
1040 // -------------------------------------------------------------------
1041 // PrimitiveTypeTraits
1042 
1043 // Since the ExtensionSet has different methods for each primitive type,
1044 // we must explicitly define the methods of the type traits class for each
1045 // known type.
1046 template <typename Type>
1047 class PrimitiveTypeTraits {
1048  public:
1049   typedef Type ConstType;
1050   typedef Type MutableType;
1051   using InitType = ConstType;
1052   static const ConstType& FromInitType(const InitType& v) { return v; }
1053   typedef PrimitiveTypeTraits<Type> Singular;
1054   static constexpr bool kLifetimeBound = false;
1055 
1056   static inline ConstType Get(int number, const ExtensionSet& set,
1057                               ConstType default_value);
1058 
1059   static inline const ConstType* GetPtr(int number, const ExtensionSet& set,
1060                                         const ConstType& default_value);
1061   static inline void Set(int number, FieldType field_type, ConstType value,
1062                          ExtensionSet* set);
1063 };
1064 
1065 template <typename Type>
1066 class RepeatedPrimitiveTypeTraits {
1067  public:
1068   typedef Type ConstType;
1069   typedef Type MutableType;
1070   using InitType = ConstType;
1071   static const ConstType& FromInitType(const InitType& v) { return v; }
1072   typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
1073   static constexpr bool kLifetimeBound = false;
1074 
1075   typedef RepeatedField<Type> RepeatedFieldType;
1076 
1077   static inline Type Get(int number, const ExtensionSet& set, int index);
1078   static inline const Type* GetPtr(int number, const ExtensionSet& set,
1079                                    int index);
1080   static inline const RepeatedField<ConstType>* GetRepeatedPtr(
1081       int number, const ExtensionSet& set);
1082   static inline void Set(int number, int index, Type value, ExtensionSet* set);
1083   static inline void Add(int number, FieldType field_type, bool is_packed,
1084                          Type value, ExtensionSet* set);
1085 
1086   static inline const RepeatedField<ConstType>& GetRepeated(
1087       int number, const ExtensionSet& set);
1088   static inline RepeatedField<Type>* MutableRepeated(int number,
1089                                                      FieldType field_type,
1090                                                      bool is_packed,
1091                                                      ExtensionSet* set);
1092 
1093   static const RepeatedFieldType* GetDefaultRepeatedField();
1094 };
1095 
1096 class PROTOBUF_EXPORT RepeatedPrimitiveDefaults {
1097  private:
1098   template <typename Type>
1099   friend class RepeatedPrimitiveTypeTraits;
1100   static const RepeatedPrimitiveDefaults* default_instance();
1101   RepeatedField<int32_t> default_repeated_field_int32_t_;
1102   RepeatedField<int64_t> default_repeated_field_int64_t_;
1103   RepeatedField<uint32_t> default_repeated_field_uint32_t_;
1104   RepeatedField<uint64_t> default_repeated_field_uint64_t_;
1105   RepeatedField<double> default_repeated_field_double_;
1106   RepeatedField<float> default_repeated_field_float_;
1107   RepeatedField<bool> default_repeated_field_bool_;
1108 };
1109 
1110 #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                           \
1111   template <>                                                                  \
1112   inline TYPE PrimitiveTypeTraits<TYPE>::Get(                                  \
1113       int number, const ExtensionSet& set, TYPE default_value) {               \
1114     return set.Get##METHOD(number, default_value);                             \
1115   }                                                                            \
1116   template <>                                                                  \
1117   inline const TYPE* PrimitiveTypeTraits<TYPE>::GetPtr(                        \
1118       int number, const ExtensionSet& set, const TYPE& default_value) {        \
1119     return &set.GetRef##METHOD(number, default_value);                         \
1120   }                                                                            \
1121   template <>                                                                  \
1122   inline void PrimitiveTypeTraits<TYPE>::Set(int number, FieldType field_type, \
1123                                              TYPE value, ExtensionSet* set) {  \
1124     set->Set##METHOD(number, field_type, value, nullptr);                      \
1125   }                                                                            \
1126                                                                                \
1127   template <>                                                                  \
1128   inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(                          \
1129       int number, const ExtensionSet& set, int index) {                        \
1130     return set.GetRepeated##METHOD(number, index);                             \
1131   }                                                                            \
1132   template <>                                                                  \
1133   inline const TYPE* RepeatedPrimitiveTypeTraits<TYPE>::GetPtr(                \
1134       int number, const ExtensionSet& set, int index) {                        \
1135     return &set.GetRefRepeated##METHOD(number, index);                         \
1136   }                                                                            \
1137   template <>                                                                  \
1138   inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(                          \
1139       int number, int index, TYPE value, ExtensionSet* set) {                  \
1140     set->SetRepeated##METHOD(number, index, value);                            \
1141   }                                                                            \
1142   template <>                                                                  \
1143   inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(                          \
1144       int number, FieldType field_type, bool is_packed, TYPE value,            \
1145       ExtensionSet* set) {                                                     \
1146     set->Add##METHOD(number, field_type, is_packed, value, nullptr);           \
1147   }                                                                            \
1148   template <>                                                                  \
1149   inline const RepeatedField<TYPE>*                                            \
1150   RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() {               \
1151     return &RepeatedPrimitiveDefaults::default_instance()                      \
1152                 ->default_repeated_field_##TYPE##_;                            \
1153   }                                                                            \
1154   template <>                                                                  \
1155   inline const RepeatedField<TYPE>&                                            \
1156   RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number,                   \
1157                                                  const ExtensionSet& set) {    \
1158     return *reinterpret_cast<const RepeatedField<TYPE>*>(                      \
1159         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));           \
1160   }                                                                            \
1161   template <>                                                                  \
1162   inline const RepeatedField<TYPE>*                                            \
1163   RepeatedPrimitiveTypeTraits<TYPE>::GetRepeatedPtr(int number,                \
1164                                                     const ExtensionSet& set) { \
1165     return &GetRepeated(number, set);                                          \
1166   }                                                                            \
1167   template <>                                                                  \
1168   inline RepeatedField<TYPE>*                                                  \
1169   RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(                          \
1170       int number, FieldType field_type, bool is_packed, ExtensionSet* set) {   \
1171     return reinterpret_cast<RepeatedField<TYPE>*>(                             \
1172         set->MutableRawRepeatedField(number, field_type, is_packed, nullptr)); \
1173   }
1174 
1175 PROTOBUF_DEFINE_PRIMITIVE_TYPE(int32_t, Int32)
1176 PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64_t, Int64)
1177 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32_t, UInt32)
1178 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64_t, UInt64)
1179 PROTOBUF_DEFINE_PRIMITIVE_TYPE(float, Float)
1180 PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
1181 PROTOBUF_DEFINE_PRIMITIVE_TYPE(bool, Bool)
1182 
1183 #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
1184 
1185 // -------------------------------------------------------------------
1186 // StringTypeTraits
1187 
1188 // Strings support both Set() and Mutable().
1189 class PROTOBUF_EXPORT StringTypeTraits {
1190  public:
1191   typedef const std::string& ConstType;
1192   typedef std::string* MutableType;
1193   using InitType = ConstType;
1194   static ConstType FromInitType(InitType v) { return v; }
1195   typedef StringTypeTraits Singular;
1196   static constexpr bool kLifetimeBound = true;
1197 
1198   static inline const std::string& Get(int number, const ExtensionSet& set,
1199                                        ConstType default_value) {
1200     return set.GetString(number, default_value);
1201   }
1202   static inline const std::string* GetPtr(int number, const ExtensionSet& set,
1203                                           ConstType default_value) {
1204     return &Get(number, set, default_value);
1205   }
1206   static inline void Set(int number, FieldType field_type,
1207                          const std::string& value, ExtensionSet* set) {
1208     set->SetString(number, field_type, value, nullptr);
1209   }
1210   static inline std::string* Mutable(int number, FieldType field_type,
1211                                      ExtensionSet* set) {
1212     return set->MutableString(number, field_type, nullptr);
1213   }
1214 };
1215 
1216 class PROTOBUF_EXPORT RepeatedStringTypeTraits {
1217  public:
1218   typedef const std::string& ConstType;
1219   typedef std::string* MutableType;
1220   using InitType = ConstType;
1221   static ConstType FromInitType(InitType v) { return v; }
1222   typedef RepeatedStringTypeTraits Repeated;
1223   static constexpr bool kLifetimeBound = true;
1224 
1225   typedef RepeatedPtrField<std::string> RepeatedFieldType;
1226 
1227   static inline const std::string& Get(int number, const ExtensionSet& set,
1228                                        int index) {
1229     return set.GetRepeatedString(number, index);
1230   }
1231   static inline const std::string* GetPtr(int number, const ExtensionSet& set,
1232                                           int index) {
1233     return &Get(number, set, index);
1234   }
1235   static inline const RepeatedPtrField<std::string>* GetRepeatedPtr(
1236       int number, const ExtensionSet& set) {
1237     return &GetRepeated(number, set);
1238   }
1239   static inline void Set(int number, int index, const std::string& value,
1240                          ExtensionSet* set) {
1241     set->SetRepeatedString(number, index, value);
1242   }
1243   static inline std::string* Mutable(int number, int index, ExtensionSet* set) {
1244     return set->MutableRepeatedString(number, index);
1245   }
1246   static inline void Add(int number, FieldType field_type, bool /*is_packed*/,
1247                          const std::string& value, ExtensionSet* set) {
1248     set->AddString(number, field_type, value, nullptr);
1249   }
1250   static inline std::string* Add(int number, FieldType field_type,
1251                                  ExtensionSet* set) {
1252     return set->AddString(number, field_type, nullptr);
1253   }
1254   static inline const RepeatedPtrField<std::string>& GetRepeated(
1255       int number, const ExtensionSet& set) {
1256     return *reinterpret_cast<const RepeatedPtrField<std::string>*>(
1257         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
1258   }
1259 
1260   static inline RepeatedPtrField<std::string>* MutableRepeated(
1261       int number, FieldType field_type, bool is_packed, ExtensionSet* set) {
1262     return reinterpret_cast<RepeatedPtrField<std::string>*>(
1263         set->MutableRawRepeatedField(number, field_type, is_packed, nullptr));
1264   }
1265 
1266   static const RepeatedFieldType* GetDefaultRepeatedField();
1267 
1268  private:
1269   static void InitializeDefaultRepeatedFields();
1270   static void DestroyDefaultRepeatedFields();
1271 };
1272 
1273 // -------------------------------------------------------------------
1274 // EnumTypeTraits
1275 
1276 // ExtensionSet represents enums using integers internally, so we have to
1277 // static_cast around.
1278 template <typename Type, bool IsValid(int)>
1279 class EnumTypeTraits {
1280  public:
1281   typedef Type ConstType;
1282   typedef Type MutableType;
1283   using InitType = ConstType;
1284   static const ConstType& FromInitType(const InitType& v) { return v; }
1285   typedef EnumTypeTraits<Type, IsValid> Singular;
1286   static constexpr bool kLifetimeBound = false;
1287 
1288   static inline ConstType Get(int number, const ExtensionSet& set,
1289                               ConstType default_value) {
1290     return static_cast<Type>(set.GetEnum(number, default_value));
1291   }
1292   static inline const ConstType* GetPtr(int number, const ExtensionSet& set,
1293                                         const ConstType& default_value) {
1294     return reinterpret_cast<const Type*>(
1295         &set.GetRefEnum(number, default_value));
1296   }
1297   static inline void Set(int number, FieldType field_type, ConstType value,
1298                          ExtensionSet* set) {
1299     ABSL_DCHECK(IsValid(value));
1300     set->SetEnum(number, field_type, value, nullptr);
1301   }
1302 };
1303 
1304 template <typename Type, bool IsValid(int)>
1305 class RepeatedEnumTypeTraits {
1306  public:
1307   typedef Type ConstType;
1308   typedef Type MutableType;
1309   using InitType = ConstType;
1310   static const ConstType& FromInitType(const InitType& v) { return v; }
1311   typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
1312   static constexpr bool kLifetimeBound = false;
1313 
1314   typedef RepeatedField<Type> RepeatedFieldType;
1315 
1316   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
1317     return static_cast<Type>(set.GetRepeatedEnum(number, index));
1318   }
1319   static inline const ConstType* GetPtr(int number, const ExtensionSet& set,
1320                                         int index) {
1321     return reinterpret_cast<const Type*>(
1322         &set.GetRefRepeatedEnum(number, index));
1323   }
1324   static inline void Set(int number, int index, ConstType value,
1325                          ExtensionSet* set) {
1326     ABSL_DCHECK(IsValid(value));
1327     set->SetRepeatedEnum(number, index, value);
1328   }
1329   static inline void Add(int number, FieldType field_type, bool is_packed,
1330                          ConstType value, ExtensionSet* set) {
1331     ABSL_DCHECK(IsValid(value));
1332     set->AddEnum(number, field_type, is_packed, value, nullptr);
1333   }
1334   static inline const RepeatedField<Type>& GetRepeated(
1335       int number, const ExtensionSet& set) {
1336     // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
1337     // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
1338     // so we need to do some casting magic. See message.h for similar
1339     // contortions for non-extension fields.
1340     return *reinterpret_cast<const RepeatedField<Type>*>(
1341         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
1342   }
1343   static inline const RepeatedField<Type>* GetRepeatedPtr(
1344       int number, const ExtensionSet& set) {
1345     return &GetRepeated(number, set);
1346   }
1347   static inline RepeatedField<Type>* MutableRepeated(int number,
1348                                                      FieldType field_type,
1349                                                      bool is_packed,
1350                                                      ExtensionSet* set) {
1351     return reinterpret_cast<RepeatedField<Type>*>(
1352         set->MutableRawRepeatedField(number, field_type, is_packed, nullptr));
1353   }
1354 
1355   static const RepeatedFieldType* GetDefaultRepeatedField() {
1356     // Hack: as noted above, repeated enum fields are internally stored as a
1357     // RepeatedField<int>. We need to be able to instantiate global static
1358     // objects to return as default (empty) repeated fields on non-existent
1359     // extensions. We would not be able to know a-priori all of the enum types
1360     // (values of |Type|) to instantiate all of these, so we just re-use
1361     // int32_t's default repeated field object.
1362     return reinterpret_cast<const RepeatedField<Type>*>(
1363         RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField());
1364   }
1365 };
1366 
1367 // -------------------------------------------------------------------
1368 // MessageTypeTraits
1369 
1370 // ExtensionSet guarantees that when manipulating extensions with message
1371 // types, the implementation used will be the compiled-in class representing
1372 // that type.  So, we can static_cast down to the exact type we expect.
1373 template <typename Type>
1374 class MessageTypeTraits {
1375  public:
1376   typedef const Type& ConstType;
1377   typedef Type* MutableType;
1378   using InitType = const void*;
1379   static ConstType FromInitType(InitType v) {
1380     return *static_cast<const Type*>(v);
1381   }
1382   typedef MessageTypeTraits<Type> Singular;
1383   static constexpr bool kLifetimeBound = true;
1384 
1385   static inline ConstType Get(int number, const ExtensionSet& set,
1386                               ConstType default_value) {
1387     return static_cast<const Type&>(set.GetMessage(number, default_value));
1388   }
1389   static inline std::nullptr_t GetPtr(int /* number */,
1390                                       const ExtensionSet& /* set */,
1391                                       ConstType /* default_value */) {
1392     // Cannot be implemented because of forward declared messages?
1393     return nullptr;
1394   }
1395   static inline MutableType Mutable(int number, FieldType field_type,
1396                                     ExtensionSet* set) {
1397     return static_cast<Type*>(set->MutableMessage(
1398         number, field_type, Type::default_instance(), nullptr));
1399   }
1400   static inline void SetAllocated(int number, FieldType field_type,
1401                                   MutableType message, ExtensionSet* set) {
1402     set->SetAllocatedMessage(number, field_type, nullptr, message);
1403   }
1404   static inline void UnsafeArenaSetAllocated(int number, FieldType field_type,
1405                                              MutableType message,
1406                                              ExtensionSet* set) {
1407     set->UnsafeArenaSetAllocatedMessage(number, field_type, nullptr, message);
1408   }
1409   PROTOBUF_NODISCARD static inline MutableType Release(
1410       int number, FieldType /* field_type */, ExtensionSet* set) {
1411     return static_cast<Type*>(
1412         set->ReleaseMessage(number, Type::default_instance()));
1413   }
1414   static inline MutableType UnsafeArenaRelease(int number,
1415                                                FieldType /* field_type */,
1416                                                ExtensionSet* set) {
1417     return static_cast<Type*>(
1418         set->UnsafeArenaReleaseMessage(number, Type::default_instance()));
1419   }
1420 };
1421 
1422 // Used by WireFormatVerify to extract the verify function from the registry.
1423 LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn(
1424     const MessageLite* extendee, int number);
1425 
1426 // forward declaration.
1427 class RepeatedMessageGenericTypeTraits;
1428 
1429 template <typename Type>
1430 class RepeatedMessageTypeTraits {
1431  public:
1432   typedef const Type& ConstType;
1433   typedef Type* MutableType;
1434   using InitType = const void*;
1435   static ConstType FromInitType(InitType v) {
1436     return *static_cast<const Type*>(v);
1437   }
1438   typedef RepeatedMessageTypeTraits<Type> Repeated;
1439   static constexpr bool kLifetimeBound = true;
1440 
1441   typedef RepeatedPtrField<Type> RepeatedFieldType;
1442 
1443   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
1444     return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
1445   }
1446   static inline std::nullptr_t GetPtr(int /* number */,
1447                                       const ExtensionSet& /* set */,
1448                                       int /* index */) {
1449     // Cannot be implemented because of forward declared messages?
1450     return nullptr;
1451   }
1452   static inline std::nullptr_t GetRepeatedPtr(int /* number */,
1453                                               const ExtensionSet& /* set */) {
1454     // Cannot be implemented because of forward declared messages?
1455     return nullptr;
1456   }
1457   static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
1458     return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
1459   }
1460   static inline MutableType Add(int number, FieldType field_type,
1461                                 ExtensionSet* set) {
1462     return static_cast<Type*>(
1463         set->AddMessage(number, field_type, Type::default_instance(), nullptr));
1464   }
1465   static inline const RepeatedPtrField<Type>& GetRepeated(
1466       int number, const ExtensionSet& set) {
1467     // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
1468     // casting hack applies here, because a RepeatedPtrField<MessageLite>
1469     // cannot naturally become a RepeatedPtrType<Type> even though Type is
1470     // presumably a message. google::protobuf::Message goes through similar contortions
1471     // with a reinterpret_cast<>.
1472     return *reinterpret_cast<const RepeatedPtrField<Type>*>(
1473         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
1474   }
1475   static inline RepeatedPtrField<Type>* MutableRepeated(int number,
1476                                                         FieldType field_type,
1477                                                         bool is_packed,
1478                                                         ExtensionSet* set) {
1479     return reinterpret_cast<RepeatedPtrField<Type>*>(
1480         set->MutableRawRepeatedField(number, field_type, is_packed, nullptr));
1481   }
1482 
1483   static const RepeatedFieldType* GetDefaultRepeatedField();
1484 };
1485 
1486 template <typename Type>
1487 inline const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
1488 RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
1489   static auto instance = OnShutdownDelete(new RepeatedFieldType);
1490   return instance;
1491 }
1492 
1493 // -------------------------------------------------------------------
1494 // ExtensionIdentifier
1495 
1496 // This is the type of actual extension objects.  E.g. if you have:
1497 //   extend Foo {
1498 //     optional int32 bar = 1234;
1499 //   }
1500 // then "bar" will be defined in C++ as:
1501 //   ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32_t>, 5, false> bar(1234);
1502 //
1503 // Note that we could, in theory, supply the field number as a template
1504 // parameter, and thus make an instance of ExtensionIdentifier have no
1505 // actual contents.  However, if we did that, then using an extension
1506 // identifier would not necessarily cause the compiler to output any sort
1507 // of reference to any symbol defined in the extension's .pb.o file.  Some
1508 // linkers will actually drop object files that are not explicitly referenced,
1509 // but that would be bad because it would cause this extension to not be
1510 // registered at static initialization, and therefore using it would crash.
1511 
1512 template <typename ExtendeeType, typename TypeTraitsType, FieldType field_type,
1513           bool is_packed>
1514 class ExtensionIdentifier {
1515  public:
1516   typedef TypeTraitsType TypeTraits;
1517   typedef ExtendeeType Extendee;
1518 
1519   constexpr ExtensionIdentifier(int number,
1520                                 typename TypeTraits::InitType default_value)
1521       : number_(number), default_value_(default_value) {}
1522 
1523   inline int number() const { return number_; }
1524   typename TypeTraits::ConstType default_value() const {
1525     return TypeTraits::FromInitType(default_value_);
1526   }
1527 
1528   typename TypeTraits::ConstType const& default_value_ref() const {
1529     return TypeTraits::FromInitType(default_value_);
1530   }
1531 
1532  private:
1533   const int number_;
1534   typename TypeTraits::InitType default_value_;
1535 };
1536 
1537 // -------------------------------------------------------------------
1538 // Generated accessors
1539 
1540 
1541 }  // namespace internal
1542 
1543 // Call this function to ensure that this extensions's reflection is linked into
1544 // the binary:
1545 //
1546 //   google::protobuf::LinkExtensionReflection(Foo::my_extension);
1547 //
1548 // This will ensure that the following lookup will succeed:
1549 //
1550 //   DescriptorPool::generated_pool()->FindExtensionByName("Foo.my_extension");
1551 //
1552 // This is often relevant for parsing extensions in text mode.
1553 //
1554 // As a side-effect, it will also guarantee that anything else from the same
1555 // .proto file will also be available for lookup in the generated pool.
1556 //
1557 // This function does not actually register the extension, so it does not need
1558 // to be called before the lookup.  However it does need to occur in a function
1559 // that cannot be stripped from the binary (ie. it must be reachable from main).
1560 //
1561 // Best practice is to call this function as close as possible to where the
1562 // reflection is actually needed.  This function is very cheap to call, so you
1563 // should not need to worry about its runtime overhead except in tight loops (on
1564 // x86-64 it compiles into two "mov" instructions).
1565 template <typename ExtendeeType, typename TypeTraitsType,
1566           internal::FieldType field_type, bool is_packed>
1567 void LinkExtensionReflection(
1568     const google::protobuf::internal::ExtensionIdentifier<
1569         ExtendeeType, TypeTraitsType, field_type, is_packed>& extension) {
1570   internal::StrongReference(extension);
1571 }
1572 
1573 // Returns the field descriptor for a generated extension identifier.  This is
1574 // useful when doing reflection over generated extensions.
1575 template <typename ExtendeeType, typename TypeTraitsType,
1576           internal::FieldType field_type, bool is_packed,
1577           typename PoolType = DescriptorPool>
1578 const FieldDescriptor* GetExtensionReflection(
1579     const google::protobuf::internal::ExtensionIdentifier<
1580         ExtendeeType, TypeTraitsType, field_type, is_packed>& extension) {
1581   return PoolType::generated_pool()->FindExtensionByNumber(
1582       google::protobuf::internal::ExtensionIdentifier<ExtendeeType, TypeTraitsType,
1583                                             field_type,
1584                                             is_packed>::Extendee::descriptor(),
1585       extension.number());
1586 }
1587 
1588 }  // namespace protobuf
1589 }  // namespace google
1590 
1591 #include "google/protobuf/port_undef.inc"
1592 
1593 #endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__