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