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