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 #include <google/protobuf/stubs/hash.h>
36 #include <google/protobuf/stubs/common.h>
37 #include <google/protobuf/stubs/once.h>
38 #include <google/protobuf/extension_set.h>
39 #include <google/protobuf/message_lite.h>
40 #include <google/protobuf/io/coded_stream.h>
41 #include <google/protobuf/wire_format_lite_inl.h>
42 #include <google/protobuf/repeated_field.h>
43 #include <google/protobuf/stubs/map_util.h>
44
45 namespace google {
46 namespace protobuf {
47 namespace internal {
48
49 namespace {
50
real_type(FieldType type)51 inline WireFormatLite::FieldType real_type(FieldType type) {
52 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
53 return static_cast<WireFormatLite::FieldType>(type);
54 }
55
cpp_type(FieldType type)56 inline WireFormatLite::CppType cpp_type(FieldType type) {
57 return WireFormatLite::FieldTypeToCppType(real_type(type));
58 }
59
is_packable(WireFormatLite::WireType type)60 inline bool is_packable(WireFormatLite::WireType type) {
61 switch (type) {
62 case WireFormatLite::WIRETYPE_VARINT:
63 case WireFormatLite::WIRETYPE_FIXED64:
64 case WireFormatLite::WIRETYPE_FIXED32:
65 return true;
66 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
67 case WireFormatLite::WIRETYPE_START_GROUP:
68 case WireFormatLite::WIRETYPE_END_GROUP:
69 return false;
70
71 // Do not add a default statement. Let the compiler complain when someone
72 // adds a new wire type.
73 }
74 GOOGLE_LOG(FATAL) << "can't reach here.";
75 return false;
76 }
77
78 // Registry stuff.
79 typedef hash_map<pair<const MessageLite*, int>,
80 ExtensionInfo> ExtensionRegistry;
81 ExtensionRegistry* registry_ = NULL;
82 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
83
DeleteRegistry()84 void DeleteRegistry() {
85 delete registry_;
86 registry_ = NULL;
87 }
88
InitRegistry()89 void InitRegistry() {
90 registry_ = new ExtensionRegistry;
91 OnShutdown(&DeleteRegistry);
92 }
93
94 // This function is only called at startup, so there is no need for thread-
95 // safety.
Register(const MessageLite * containing_type,int number,ExtensionInfo info)96 void Register(const MessageLite* containing_type,
97 int number, ExtensionInfo info) {
98 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry);
99
100 if (!InsertIfNotPresent(registry_, std::make_pair(containing_type, number),
101 info)) {
102 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
103 << containing_type->GetTypeName()
104 << "\", field number " << number << ".";
105 }
106 }
107
FindRegisteredExtension(const MessageLite * containing_type,int number)108 const ExtensionInfo* FindRegisteredExtension(
109 const MessageLite* containing_type, int number) {
110 return (registry_ == NULL)
111 ? NULL
112 : FindOrNull(*registry_, std::make_pair(containing_type, number));
113 }
114
115 } // namespace
116
~ExtensionFinder()117 ExtensionFinder::~ExtensionFinder() {}
118
Find(int number,ExtensionInfo * output)119 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
120 const ExtensionInfo* extension =
121 FindRegisteredExtension(containing_type_, number);
122 if (extension == NULL) {
123 return false;
124 } else {
125 *output = *extension;
126 return true;
127 }
128 }
129
RegisterExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed)130 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
131 int number, FieldType type,
132 bool is_repeated, bool is_packed) {
133 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
134 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
135 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
136 ExtensionInfo info(type, is_repeated, is_packed);
137 Register(containing_type, number, info);
138 }
139
CallNoArgValidityFunc(const void * arg,int number)140 static bool CallNoArgValidityFunc(const void* arg, int number) {
141 // Note: Must use C-style cast here rather than reinterpret_cast because
142 // the C++ standard at one point did not allow casts between function and
143 // data pointers and some compilers enforce this for C++-style casts. No
144 // compiler enforces it for C-style casts since lots of C-style code has
145 // relied on these kinds of casts for a long time, despite being
146 // technically undefined. See:
147 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
148 // Also note: Some compilers do not allow function pointers to be "const".
149 // Which makes sense, I suppose, because it's meaningless.
150 return ((EnumValidityFunc*)arg)(number);
151 }
152
RegisterEnumExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,EnumValidityFunc * is_valid)153 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
154 int number, FieldType type,
155 bool is_repeated, bool is_packed,
156 EnumValidityFunc* is_valid) {
157 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
158 ExtensionInfo info(type, is_repeated, is_packed);
159 info.enum_validity_check.func = CallNoArgValidityFunc;
160 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
161 info.enum_validity_check.arg = (void*)is_valid;
162 Register(containing_type, number, info);
163 }
164
RegisterMessageExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,const MessageLite * prototype)165 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
166 int number, FieldType type,
167 bool is_repeated, bool is_packed,
168 const MessageLite* prototype) {
169 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
170 type == WireFormatLite::TYPE_GROUP);
171 ExtensionInfo info(type, is_repeated, is_packed);
172 info.message_prototype = prototype;
173 Register(containing_type, number, info);
174 }
175
176
177 // ===================================================================
178 // Constructors and basic methods.
179
ExtensionSet(::google::protobuf::Arena * arena)180 ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena)
181 : arena_(arena) {
182 if (arena_ != NULL) {
183 arena_->OwnDestructor(&extensions_);
184 }
185 }
186
ExtensionSet()187 ExtensionSet::ExtensionSet() : arena_(NULL) {}
188
~ExtensionSet()189 ExtensionSet::~ExtensionSet() {
190 // Deletes all allocated extensions.
191 if (arena_ == NULL) {
192 for (ExtensionMap::iterator iter = extensions_.begin();
193 iter != extensions_.end(); ++iter) {
194 iter->second.Free();
195 }
196 }
197 }
198
199 // Defined in extension_set_heavy.cc.
200 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
201 // const DescriptorPool* pool,
202 // vector<const FieldDescriptor*>* output) const
203
Has(int number) const204 bool ExtensionSet::Has(int number) const {
205 ExtensionMap::const_iterator iter = extensions_.find(number);
206 if (iter == extensions_.end()) return false;
207 GOOGLE_DCHECK(!iter->second.is_repeated);
208 return !iter->second.is_cleared;
209 }
210
NumExtensions() const211 int ExtensionSet::NumExtensions() const {
212 int result = 0;
213 for (ExtensionMap::const_iterator iter = extensions_.begin();
214 iter != extensions_.end(); ++iter) {
215 if (!iter->second.is_cleared) {
216 ++result;
217 }
218 }
219 return result;
220 }
221
ExtensionSize(int number) const222 int ExtensionSet::ExtensionSize(int number) const {
223 ExtensionMap::const_iterator iter = extensions_.find(number);
224 if (iter == extensions_.end()) return false;
225 return iter->second.GetSize();
226 }
227
ExtensionType(int number) const228 FieldType ExtensionSet::ExtensionType(int number) const {
229 ExtensionMap::const_iterator iter = extensions_.find(number);
230 if (iter == extensions_.end()) {
231 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
232 return 0;
233 }
234 if (iter->second.is_cleared) {
235 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
236 }
237 return iter->second.type;
238 }
239
ClearExtension(int number)240 void ExtensionSet::ClearExtension(int number) {
241 ExtensionMap::iterator iter = extensions_.find(number);
242 if (iter == extensions_.end()) return;
243 iter->second.Clear();
244 }
245
246 // ===================================================================
247 // Field accessors
248
249 namespace {
250
251 enum Cardinality {
252 REPEATED,
253 OPTIONAL
254 };
255
256 } // namespace
257
258 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
259 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
260 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
261
262 // -------------------------------------------------------------------
263 // Primitives
264
265 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
266 \
267 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
268 LOWERCASE default_value) const { \
269 ExtensionMap::const_iterator iter = extensions_.find(number); \
270 if (iter == extensions_.end() || iter->second.is_cleared) { \
271 return default_value; \
272 } else { \
273 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
274 return iter->second.LOWERCASE##_value; \
275 } \
276 } \
277 \
278 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
279 LOWERCASE value, \
280 const FieldDescriptor* descriptor) { \
281 Extension* extension; \
282 if (MaybeNewExtension(number, descriptor, &extension)) { \
283 extension->type = type; \
284 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
285 extension->is_repeated = false; \
286 } else { \
287 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
288 } \
289 extension->is_cleared = false; \
290 extension->LOWERCASE##_value = value; \
291 } \
292 \
293 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
294 ExtensionMap::const_iterator iter = extensions_.find(number); \
295 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
296 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
297 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
298 } \
299 \
300 void ExtensionSet::SetRepeated##CAMELCASE( \
301 int number, int index, LOWERCASE value) { \
302 ExtensionMap::iterator iter = extensions_.find(number); \
303 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
304 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
305 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
306 } \
307 \
308 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
309 bool packed, LOWERCASE value, \
310 const FieldDescriptor* descriptor) { \
311 Extension* extension; \
312 if (MaybeNewExtension(number, descriptor, &extension)) { \
313 extension->type = type; \
314 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
315 extension->is_repeated = true; \
316 extension->is_packed = packed; \
317 extension->repeated_##LOWERCASE##_value = \
318 Arena::CreateMessage<RepeatedField<LOWERCASE> >(arena_); \
319 } else { \
320 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
321 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
322 } \
323 extension->repeated_##LOWERCASE##_value->Add(value); \
324 }
325
PRIMITIVE_ACCESSORS(INT32,int32,Int32)326 PRIMITIVE_ACCESSORS( INT32, int32, Int32)
327 PRIMITIVE_ACCESSORS( INT64, int64, Int64)
328 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
329 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
330 PRIMITIVE_ACCESSORS( FLOAT, float, Float)
331 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
332 PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
333
334 #undef PRIMITIVE_ACCESSORS
335
336 const void* ExtensionSet::GetRawRepeatedField(int number,
337 const void* default_value) const {
338 ExtensionMap::const_iterator iter = extensions_.find(number);
339 if (iter == extensions_.end()) {
340 return default_value;
341 }
342 // We assume that all the RepeatedField<>* pointers have the same
343 // size and alignment within the anonymous union in Extension.
344 return iter->second.repeated_int32_value;
345 }
346
MutableRawRepeatedField(int number,FieldType field_type,bool packed,const FieldDescriptor * desc)347 void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
348 bool packed,
349 const FieldDescriptor* desc) {
350 Extension* extension;
351
352 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
353 // extension.
354 if (MaybeNewExtension(number, desc, &extension)) {
355 extension->is_repeated = true;
356 extension->type = field_type;
357 extension->is_packed = packed;
358
359 switch (WireFormatLite::FieldTypeToCppType(
360 static_cast<WireFormatLite::FieldType>(field_type))) {
361 case WireFormatLite::CPPTYPE_INT32:
362 extension->repeated_int32_value =
363 Arena::CreateMessage<RepeatedField<int32> >(arena_);
364 break;
365 case WireFormatLite::CPPTYPE_INT64:
366 extension->repeated_int64_value =
367 Arena::CreateMessage<RepeatedField<int64> >(arena_);
368 break;
369 case WireFormatLite::CPPTYPE_UINT32:
370 extension->repeated_uint32_value =
371 Arena::CreateMessage<RepeatedField<uint32> >(arena_);
372 break;
373 case WireFormatLite::CPPTYPE_UINT64:
374 extension->repeated_uint64_value =
375 Arena::CreateMessage<RepeatedField<uint64> >(arena_);
376 break;
377 case WireFormatLite::CPPTYPE_DOUBLE:
378 extension->repeated_double_value =
379 Arena::CreateMessage<RepeatedField<double> >(arena_);
380 break;
381 case WireFormatLite::CPPTYPE_FLOAT:
382 extension->repeated_float_value =
383 Arena::CreateMessage<RepeatedField<float> >(arena_);
384 break;
385 case WireFormatLite::CPPTYPE_BOOL:
386 extension->repeated_bool_value =
387 Arena::CreateMessage<RepeatedField<bool> >(arena_);
388 break;
389 case WireFormatLite::CPPTYPE_ENUM:
390 extension->repeated_enum_value =
391 Arena::CreateMessage<RepeatedField<int> >(arena_);
392 break;
393 case WireFormatLite::CPPTYPE_STRING:
394 extension->repeated_string_value =
395 Arena::CreateMessage<RepeatedPtrField< ::std::string> >(arena_);
396 break;
397 case WireFormatLite::CPPTYPE_MESSAGE:
398 extension->repeated_message_value =
399 Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
400 break;
401 }
402 }
403
404 // We assume that all the RepeatedField<>* pointers have the same
405 // size and alignment within the anonymous union in Extension.
406 return extension->repeated_int32_value;
407 }
408
409 // Compatible version using old call signature. Does not create extensions when
410 // the don't already exist; instead, just GOOGLE_CHECK-fails.
MutableRawRepeatedField(int number)411 void* ExtensionSet::MutableRawRepeatedField(int number) {
412 ExtensionMap::iterator iter = extensions_.find(number);
413 GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
414 // We assume that all the RepeatedField<>* pointers have the same
415 // size and alignment within the anonymous union in Extension.
416 return iter->second.repeated_int32_value;
417 }
418
419
420 // -------------------------------------------------------------------
421 // Enums
422
GetEnum(int number,int default_value) const423 int ExtensionSet::GetEnum(int number, int default_value) const {
424 ExtensionMap::const_iterator iter = extensions_.find(number);
425 if (iter == extensions_.end() || iter->second.is_cleared) {
426 // Not present. Return the default value.
427 return default_value;
428 } else {
429 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
430 return iter->second.enum_value;
431 }
432 }
433
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)434 void ExtensionSet::SetEnum(int number, FieldType type, int value,
435 const FieldDescriptor* descriptor) {
436 Extension* extension;
437 if (MaybeNewExtension(number, descriptor, &extension)) {
438 extension->type = type;
439 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
440 extension->is_repeated = false;
441 } else {
442 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
443 }
444 extension->is_cleared = false;
445 extension->enum_value = value;
446 }
447
GetRepeatedEnum(int number,int index) const448 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
449 ExtensionMap::const_iterator iter = extensions_.find(number);
450 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
451 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
452 return iter->second.repeated_enum_value->Get(index);
453 }
454
SetRepeatedEnum(int number,int index,int value)455 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
456 ExtensionMap::iterator iter = extensions_.find(number);
457 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
458 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
459 iter->second.repeated_enum_value->Set(index, value);
460 }
461
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)462 void ExtensionSet::AddEnum(int number, FieldType type,
463 bool packed, int value,
464 const FieldDescriptor* descriptor) {
465 Extension* extension;
466 if (MaybeNewExtension(number, descriptor, &extension)) {
467 extension->type = type;
468 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
469 extension->is_repeated = true;
470 extension->is_packed = packed;
471 extension->repeated_enum_value =
472 Arena::CreateMessage<RepeatedField<int> >(arena_);
473 } else {
474 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
475 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
476 }
477 extension->repeated_enum_value->Add(value);
478 }
479
480 // -------------------------------------------------------------------
481 // Strings
482
GetString(int number,const string & default_value) const483 const string& ExtensionSet::GetString(int number,
484 const string& default_value) const {
485 ExtensionMap::const_iterator iter = extensions_.find(number);
486 if (iter == extensions_.end() || iter->second.is_cleared) {
487 // Not present. Return the default value.
488 return default_value;
489 } else {
490 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
491 return *iter->second.string_value;
492 }
493 }
494
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)495 string* ExtensionSet::MutableString(int number, FieldType type,
496 const FieldDescriptor* descriptor) {
497 Extension* extension;
498 if (MaybeNewExtension(number, descriptor, &extension)) {
499 extension->type = type;
500 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
501 extension->is_repeated = false;
502 extension->string_value = Arena::Create<string>(arena_);
503 } else {
504 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
505 }
506 extension->is_cleared = false;
507 return extension->string_value;
508 }
509
GetRepeatedString(int number,int index) const510 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
511 ExtensionMap::const_iterator iter = extensions_.find(number);
512 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
513 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
514 return iter->second.repeated_string_value->Get(index);
515 }
516
MutableRepeatedString(int number,int index)517 string* ExtensionSet::MutableRepeatedString(int number, int index) {
518 ExtensionMap::iterator iter = extensions_.find(number);
519 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
520 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
521 return iter->second.repeated_string_value->Mutable(index);
522 }
523
AddString(int number,FieldType type,const FieldDescriptor * descriptor)524 string* ExtensionSet::AddString(int number, FieldType type,
525 const FieldDescriptor* descriptor) {
526 Extension* extension;
527 if (MaybeNewExtension(number, descriptor, &extension)) {
528 extension->type = type;
529 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
530 extension->is_repeated = true;
531 extension->is_packed = false;
532 extension->repeated_string_value =
533 Arena::CreateMessage<RepeatedPtrField<string> >(arena_);
534 } else {
535 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
536 }
537 return extension->repeated_string_value->Add();
538 }
539
540 // -------------------------------------------------------------------
541 // Messages
542
GetMessage(int number,const MessageLite & default_value) const543 const MessageLite& ExtensionSet::GetMessage(
544 int number, const MessageLite& default_value) const {
545 ExtensionMap::const_iterator iter = extensions_.find(number);
546 if (iter == extensions_.end()) {
547 // Not present. Return the default value.
548 return default_value;
549 } else {
550 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
551 if (iter->second.is_lazy) {
552 return iter->second.lazymessage_value->GetMessage(default_value);
553 } else {
554 return *iter->second.message_value;
555 }
556 }
557 }
558
559 // Defined in extension_set_heavy.cc.
560 // const MessageLite& ExtensionSet::GetMessage(int number,
561 // const Descriptor* message_type,
562 // MessageFactory* factory) const
563
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)564 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
565 const MessageLite& prototype,
566 const FieldDescriptor* descriptor) {
567 Extension* extension;
568 if (MaybeNewExtension(number, descriptor, &extension)) {
569 extension->type = type;
570 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
571 extension->is_repeated = false;
572 extension->is_lazy = false;
573 extension->message_value = prototype.New(arena_);
574 extension->is_cleared = false;
575 return extension->message_value;
576 } else {
577 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
578 extension->is_cleared = false;
579 if (extension->is_lazy) {
580 return extension->lazymessage_value->MutableMessage(prototype);
581 } else {
582 return extension->message_value;
583 }
584 }
585 }
586
587 // Defined in extension_set_heavy.cc.
588 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
589 // const Descriptor* message_type,
590 // MessageFactory* factory)
591
SetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)592 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
593 const FieldDescriptor* descriptor,
594 MessageLite* message) {
595 if (message == NULL) {
596 ClearExtension(number);
597 return;
598 }
599 ::google::protobuf::Arena* message_arena = message->GetArena();
600 Extension* extension;
601 if (MaybeNewExtension(number, descriptor, &extension)) {
602 extension->type = type;
603 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
604 extension->is_repeated = false;
605 extension->is_lazy = false;
606 if (message_arena == arena_) {
607 extension->message_value = message;
608 } else if (message_arena == NULL) {
609 extension->message_value = message;
610 arena_->Own(message); // not NULL because not equal to message_arena
611 } else {
612 extension->message_value = message->New(arena_);
613 extension->message_value->CheckTypeAndMergeFrom(*message);
614 }
615 } else {
616 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
617 if (extension->is_lazy) {
618 extension->lazymessage_value->SetAllocatedMessage(message);
619 } else {
620 if (arena_ == NULL) {
621 delete extension->message_value;
622 }
623 if (message_arena == arena_) {
624 extension->message_value = message;
625 } else if (message_arena == NULL) {
626 extension->message_value = message;
627 arena_->Own(message); // not NULL because not equal to message_arena
628 } else {
629 extension->message_value = message->New(arena_);
630 extension->message_value->CheckTypeAndMergeFrom(*message);
631 }
632 }
633 }
634 extension->is_cleared = false;
635 }
636
UnsafeArenaSetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)637 void ExtensionSet::UnsafeArenaSetAllocatedMessage(
638 int number, FieldType type, const FieldDescriptor* descriptor,
639 MessageLite* message) {
640 if (message == NULL) {
641 ClearExtension(number);
642 return;
643 }
644 Extension* extension;
645 if (MaybeNewExtension(number, descriptor, &extension)) {
646 extension->type = type;
647 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
648 extension->is_repeated = false;
649 extension->is_lazy = false;
650 extension->message_value = message;
651 } else {
652 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
653 if (extension->is_lazy) {
654 extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message);
655 } else {
656 if (arena_ == NULL) {
657 delete extension->message_value;
658 }
659 extension->message_value = message;
660 }
661 }
662 extension->is_cleared = false;
663 }
664
665
ReleaseMessage(int number,const MessageLite & prototype)666 MessageLite* ExtensionSet::ReleaseMessage(int number,
667 const MessageLite& prototype) {
668 ExtensionMap::iterator iter = extensions_.find(number);
669 if (iter == extensions_.end()) {
670 // Not present. Return NULL.
671 return NULL;
672 } else {
673 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
674 MessageLite* ret = NULL;
675 if (iter->second.is_lazy) {
676 ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
677 if (arena_ == NULL) {
678 delete iter->second.lazymessage_value;
679 }
680 } else {
681 if (arena_ == NULL) {
682 ret = iter->second.message_value;
683 } else {
684 // ReleaseMessage() always returns a heap-allocated message, and we are
685 // on an arena, so we need to make a copy of this message to return.
686 ret = (iter->second.message_value)->New();
687 ret->CheckTypeAndMergeFrom(*iter->second.message_value);
688 }
689 }
690 extensions_.erase(number);
691 return ret;
692 }
693 }
694
UnsafeArenaReleaseMessage(int number,const MessageLite & prototype)695 MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
696 int number, const MessageLite& prototype) {
697 ExtensionMap::iterator iter = extensions_.find(number);
698 if (iter == extensions_.end()) {
699 // Not present. Return NULL.
700 return NULL;
701 } else {
702 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
703 MessageLite* ret = NULL;
704 if (iter->second.is_lazy) {
705 ret =
706 iter->second.lazymessage_value->UnsafeArenaReleaseMessage(prototype);
707 if (arena_ == NULL) {
708 delete iter->second.lazymessage_value;
709 }
710 } else {
711 ret = iter->second.message_value;
712 }
713 extensions_.erase(number);
714 return ret;
715 }
716 }
717
718 // Defined in extension_set_heavy.cc.
719 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
720 // MessageFactory* factory);
721
GetRepeatedMessage(int number,int index) const722 const MessageLite& ExtensionSet::GetRepeatedMessage(
723 int number, int index) const {
724 ExtensionMap::const_iterator iter = extensions_.find(number);
725 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
726 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
727 return iter->second.repeated_message_value->Get(index);
728 }
729
MutableRepeatedMessage(int number,int index)730 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
731 ExtensionMap::iterator iter = extensions_.find(number);
732 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
733 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
734 return iter->second.repeated_message_value->Mutable(index);
735 }
736
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)737 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
738 const MessageLite& prototype,
739 const FieldDescriptor* descriptor) {
740 Extension* extension;
741 if (MaybeNewExtension(number, descriptor, &extension)) {
742 extension->type = type;
743 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
744 extension->is_repeated = true;
745 extension->repeated_message_value =
746 Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
747 } else {
748 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
749 }
750
751 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
752 // allocate an abstract object, so we have to be tricky.
753 MessageLite* result = extension->repeated_message_value
754 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
755 if (result == NULL) {
756 result = prototype.New(arena_);
757 extension->repeated_message_value->AddAllocated(result);
758 }
759 return result;
760 }
761
762 // Defined in extension_set_heavy.cc.
763 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
764 // const Descriptor* message_type,
765 // MessageFactory* factory)
766
767 #undef GOOGLE_DCHECK_TYPE
768
RemoveLast(int number)769 void ExtensionSet::RemoveLast(int number) {
770 ExtensionMap::iterator iter = extensions_.find(number);
771 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
772
773 Extension* extension = &iter->second;
774 GOOGLE_DCHECK(extension->is_repeated);
775
776 switch(cpp_type(extension->type)) {
777 case WireFormatLite::CPPTYPE_INT32:
778 extension->repeated_int32_value->RemoveLast();
779 break;
780 case WireFormatLite::CPPTYPE_INT64:
781 extension->repeated_int64_value->RemoveLast();
782 break;
783 case WireFormatLite::CPPTYPE_UINT32:
784 extension->repeated_uint32_value->RemoveLast();
785 break;
786 case WireFormatLite::CPPTYPE_UINT64:
787 extension->repeated_uint64_value->RemoveLast();
788 break;
789 case WireFormatLite::CPPTYPE_FLOAT:
790 extension->repeated_float_value->RemoveLast();
791 break;
792 case WireFormatLite::CPPTYPE_DOUBLE:
793 extension->repeated_double_value->RemoveLast();
794 break;
795 case WireFormatLite::CPPTYPE_BOOL:
796 extension->repeated_bool_value->RemoveLast();
797 break;
798 case WireFormatLite::CPPTYPE_ENUM:
799 extension->repeated_enum_value->RemoveLast();
800 break;
801 case WireFormatLite::CPPTYPE_STRING:
802 extension->repeated_string_value->RemoveLast();
803 break;
804 case WireFormatLite::CPPTYPE_MESSAGE:
805 extension->repeated_message_value->RemoveLast();
806 break;
807 }
808 }
809
ReleaseLast(int number)810 MessageLite* ExtensionSet::ReleaseLast(int number) {
811 ExtensionMap::iterator iter = extensions_.find(number);
812 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
813
814 Extension* extension = &iter->second;
815 GOOGLE_DCHECK(extension->is_repeated);
816 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
817 return extension->repeated_message_value->ReleaseLast();
818 }
819
SwapElements(int number,int index1,int index2)820 void ExtensionSet::SwapElements(int number, int index1, int index2) {
821 ExtensionMap::iterator iter = extensions_.find(number);
822 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
823
824 Extension* extension = &iter->second;
825 GOOGLE_DCHECK(extension->is_repeated);
826
827 switch(cpp_type(extension->type)) {
828 case WireFormatLite::CPPTYPE_INT32:
829 extension->repeated_int32_value->SwapElements(index1, index2);
830 break;
831 case WireFormatLite::CPPTYPE_INT64:
832 extension->repeated_int64_value->SwapElements(index1, index2);
833 break;
834 case WireFormatLite::CPPTYPE_UINT32:
835 extension->repeated_uint32_value->SwapElements(index1, index2);
836 break;
837 case WireFormatLite::CPPTYPE_UINT64:
838 extension->repeated_uint64_value->SwapElements(index1, index2);
839 break;
840 case WireFormatLite::CPPTYPE_FLOAT:
841 extension->repeated_float_value->SwapElements(index1, index2);
842 break;
843 case WireFormatLite::CPPTYPE_DOUBLE:
844 extension->repeated_double_value->SwapElements(index1, index2);
845 break;
846 case WireFormatLite::CPPTYPE_BOOL:
847 extension->repeated_bool_value->SwapElements(index1, index2);
848 break;
849 case WireFormatLite::CPPTYPE_ENUM:
850 extension->repeated_enum_value->SwapElements(index1, index2);
851 break;
852 case WireFormatLite::CPPTYPE_STRING:
853 extension->repeated_string_value->SwapElements(index1, index2);
854 break;
855 case WireFormatLite::CPPTYPE_MESSAGE:
856 extension->repeated_message_value->SwapElements(index1, index2);
857 break;
858 }
859 }
860
861 // ===================================================================
862
Clear()863 void ExtensionSet::Clear() {
864 for (ExtensionMap::iterator iter = extensions_.begin();
865 iter != extensions_.end(); ++iter) {
866 iter->second.Clear();
867 }
868 }
869
MergeFrom(const ExtensionSet & other)870 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
871 for (ExtensionMap::const_iterator iter = other.extensions_.begin();
872 iter != other.extensions_.end(); ++iter) {
873 const Extension& other_extension = iter->second;
874 InternalExtensionMergeFrom(iter->first, other_extension);
875 }
876 }
877
InternalExtensionMergeFrom(int number,const Extension & other_extension)878 void ExtensionSet::InternalExtensionMergeFrom(
879 int number, const Extension& other_extension) {
880 if (other_extension.is_repeated) {
881 Extension* extension;
882 bool is_new = MaybeNewExtension(number, other_extension.descriptor,
883 &extension);
884 if (is_new) {
885 // Extension did not already exist in set.
886 extension->type = other_extension.type;
887 extension->is_packed = other_extension.is_packed;
888 extension->is_repeated = true;
889 } else {
890 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
891 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
892 GOOGLE_DCHECK(extension->is_repeated);
893 }
894
895 switch (cpp_type(other_extension.type)) {
896 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
897 case WireFormatLite::CPPTYPE_##UPPERCASE: \
898 if (is_new) { \
899 extension->repeated_##LOWERCASE##_value = \
900 Arena::CreateMessage<REPEATED_TYPE >(arena_); \
901 } \
902 extension->repeated_##LOWERCASE##_value->MergeFrom( \
903 *other_extension.repeated_##LOWERCASE##_value); \
904 break;
905
906 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
907 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
908 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
909 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
910 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
911 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
912 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
913 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
914 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
915 #undef HANDLE_TYPE
916
917 case WireFormatLite::CPPTYPE_MESSAGE:
918 if (is_new) {
919 extension->repeated_message_value =
920 Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
921 }
922 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
923 // it would attempt to allocate new objects.
924 RepeatedPtrField<MessageLite>* other_repeated_message =
925 other_extension.repeated_message_value;
926 for (int i = 0; i < other_repeated_message->size(); i++) {
927 const MessageLite& other_message = other_repeated_message->Get(i);
928 MessageLite* target = extension->repeated_message_value
929 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
930 if (target == NULL) {
931 target = other_message.New(arena_);
932 extension->repeated_message_value->AddAllocated(target);
933 }
934 target->CheckTypeAndMergeFrom(other_message);
935 }
936 break;
937 }
938 } else {
939 if (!other_extension.is_cleared) {
940 switch (cpp_type(other_extension.type)) {
941 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
942 case WireFormatLite::CPPTYPE_##UPPERCASE: \
943 Set##CAMELCASE(number, other_extension.type, \
944 other_extension.LOWERCASE##_value, \
945 other_extension.descriptor); \
946 break;
947
948 HANDLE_TYPE( INT32, int32, Int32);
949 HANDLE_TYPE( INT64, int64, Int64);
950 HANDLE_TYPE(UINT32, uint32, UInt32);
951 HANDLE_TYPE(UINT64, uint64, UInt64);
952 HANDLE_TYPE( FLOAT, float, Float);
953 HANDLE_TYPE(DOUBLE, double, Double);
954 HANDLE_TYPE( BOOL, bool, Bool);
955 HANDLE_TYPE( ENUM, enum, Enum);
956 #undef HANDLE_TYPE
957 case WireFormatLite::CPPTYPE_STRING:
958 SetString(number, other_extension.type,
959 *other_extension.string_value,
960 other_extension.descriptor);
961 break;
962 case WireFormatLite::CPPTYPE_MESSAGE: {
963 Extension* extension;
964 bool is_new = MaybeNewExtension(number,
965 other_extension.descriptor,
966 &extension);
967 if (is_new) {
968 extension->type = other_extension.type;
969 extension->is_packed = other_extension.is_packed;
970 extension->is_repeated = false;
971 if (other_extension.is_lazy) {
972 extension->is_lazy = true;
973 extension->lazymessage_value =
974 other_extension.lazymessage_value->New(arena_);
975 extension->lazymessage_value->MergeFrom(
976 *other_extension.lazymessage_value);
977 } else {
978 extension->is_lazy = false;
979 extension->message_value =
980 other_extension.message_value->New(arena_);
981 extension->message_value->CheckTypeAndMergeFrom(
982 *other_extension.message_value);
983 }
984 } else {
985 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
986 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
987 GOOGLE_DCHECK(!extension->is_repeated);
988 if (other_extension.is_lazy) {
989 if (extension->is_lazy) {
990 extension->lazymessage_value->MergeFrom(
991 *other_extension.lazymessage_value);
992 } else {
993 extension->message_value->CheckTypeAndMergeFrom(
994 other_extension.lazymessage_value->GetMessage(
995 *extension->message_value));
996 }
997 } else {
998 if (extension->is_lazy) {
999 extension->lazymessage_value->MutableMessage(
1000 *other_extension.message_value)->CheckTypeAndMergeFrom(
1001 *other_extension.message_value);
1002 } else {
1003 extension->message_value->CheckTypeAndMergeFrom(
1004 *other_extension.message_value);
1005 }
1006 }
1007 }
1008 extension->is_cleared = false;
1009 break;
1010 }
1011 }
1012 }
1013 }
1014 }
1015
Swap(ExtensionSet * x)1016 void ExtensionSet::Swap(ExtensionSet* x) {
1017 if (GetArenaNoVirtual() == x->GetArenaNoVirtual()) {
1018 extensions_.swap(x->extensions_);
1019 } else {
1020 // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
1021 // swapping from heap to arena-allocated extension set, by just Own()'ing
1022 // the extensions.
1023 ExtensionSet extension_set;
1024 extension_set.MergeFrom(*x);
1025 x->Clear();
1026 x->MergeFrom(*this);
1027 Clear();
1028 MergeFrom(extension_set);
1029 }
1030 }
1031
SwapExtension(ExtensionSet * other,int number)1032 void ExtensionSet::SwapExtension(ExtensionSet* other,
1033 int number) {
1034 if (this == other) return;
1035 ExtensionMap::iterator this_iter = extensions_.find(number);
1036 ExtensionMap::iterator other_iter = other->extensions_.find(number);
1037
1038 if (this_iter == extensions_.end() &&
1039 other_iter == other->extensions_.end()) {
1040 return;
1041 }
1042
1043 if (this_iter != extensions_.end() &&
1044 other_iter != other->extensions_.end()) {
1045 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1046 using std::swap;
1047 swap(this_iter->second, other_iter->second);
1048 } else {
1049 // TODO(cfallin, rohananil): We could further optimize these cases,
1050 // especially avoid creation of ExtensionSet, and move MergeFrom logic
1051 // into Extensions itself (which takes arena as an argument).
1052 // We do it this way to reuse the copy-across-arenas logic already
1053 // implemented in ExtensionSet's MergeFrom.
1054 ExtensionSet temp;
1055 temp.InternalExtensionMergeFrom(number, other_iter->second);
1056 ExtensionMap::iterator temp_iter = temp.extensions_.find(number);
1057 other_iter->second.Clear();
1058 other->InternalExtensionMergeFrom(number, this_iter->second);
1059 this_iter->second.Clear();
1060 InternalExtensionMergeFrom(number, temp_iter->second);
1061 }
1062 return;
1063 }
1064
1065 if (this_iter == extensions_.end()) {
1066 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1067 extensions_.insert(std::make_pair(number, other_iter->second));
1068 } else {
1069 InternalExtensionMergeFrom(number, other_iter->second);
1070 }
1071 other->extensions_.erase(number);
1072 return;
1073 }
1074
1075 if (other_iter == other->extensions_.end()) {
1076 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1077 other->extensions_.insert(std::make_pair(number, this_iter->second));
1078 } else {
1079 other->InternalExtensionMergeFrom(number, this_iter->second);
1080 }
1081 extensions_.erase(number);
1082 return;
1083 }
1084 }
1085
IsInitialized() const1086 bool ExtensionSet::IsInitialized() const {
1087 // Extensions are never required. However, we need to check that all
1088 // embedded messages are initialized.
1089 for (ExtensionMap::const_iterator iter = extensions_.begin();
1090 iter != extensions_.end(); ++iter) {
1091 const Extension& extension = iter->second;
1092 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
1093 if (extension.is_repeated) {
1094 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
1095 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
1096 return false;
1097 }
1098 }
1099 } else {
1100 if (!extension.is_cleared) {
1101 if (extension.is_lazy) {
1102 if (!extension.lazymessage_value->IsInitialized()) return false;
1103 } else {
1104 if (!extension.message_value->IsInitialized()) return false;
1105 }
1106 }
1107 }
1108 }
1109 }
1110
1111 return true;
1112 }
1113
FindExtensionInfoFromTag(uint32 tag,ExtensionFinder * extension_finder,int * field_number,ExtensionInfo * extension,bool * was_packed_on_wire)1114 bool ExtensionSet::FindExtensionInfoFromTag(
1115 uint32 tag, ExtensionFinder* extension_finder, int* field_number,
1116 ExtensionInfo* extension, bool* was_packed_on_wire) {
1117 *field_number = WireFormatLite::GetTagFieldNumber(tag);
1118 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
1119 return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
1120 extension_finder, extension,
1121 was_packed_on_wire);
1122 }
1123
FindExtensionInfoFromFieldNumber(int wire_type,int field_number,ExtensionFinder * extension_finder,ExtensionInfo * extension,bool * was_packed_on_wire)1124 bool ExtensionSet::FindExtensionInfoFromFieldNumber(
1125 int wire_type, int field_number, ExtensionFinder* extension_finder,
1126 ExtensionInfo* extension, bool* was_packed_on_wire) {
1127 if (!extension_finder->Find(field_number, extension)) {
1128 return false;
1129 }
1130
1131 WireFormatLite::WireType expected_wire_type =
1132 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
1133
1134 // Check if this is a packed field.
1135 *was_packed_on_wire = false;
1136 if (extension->is_repeated &&
1137 wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
1138 is_packable(expected_wire_type)) {
1139 *was_packed_on_wire = true;
1140 return true;
1141 }
1142 // Otherwise the wire type must match.
1143 return expected_wire_type == wire_type;
1144 }
1145
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)1146 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1147 ExtensionFinder* extension_finder,
1148 FieldSkipper* field_skipper) {
1149 int number;
1150 bool was_packed_on_wire;
1151 ExtensionInfo extension;
1152 if (!FindExtensionInfoFromTag(
1153 tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
1154 return field_skipper->SkipField(input, tag);
1155 } else {
1156 return ParseFieldWithExtensionInfo(
1157 number, was_packed_on_wire, extension, input, field_skipper);
1158 }
1159 }
1160
ParseFieldWithExtensionInfo(int number,bool was_packed_on_wire,const ExtensionInfo & extension,io::CodedInputStream * input,FieldSkipper * field_skipper)1161 bool ExtensionSet::ParseFieldWithExtensionInfo(
1162 int number, bool was_packed_on_wire, const ExtensionInfo& extension,
1163 io::CodedInputStream* input,
1164 FieldSkipper* field_skipper) {
1165 // Explicitly not read extension.is_packed, instead check whether the field
1166 // was encoded in packed form on the wire.
1167 if (was_packed_on_wire) {
1168 uint32 size;
1169 if (!input->ReadVarint32(&size)) return false;
1170 io::CodedInputStream::Limit limit = input->PushLimit(size);
1171
1172 switch (extension.type) {
1173 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
1174 case WireFormatLite::TYPE_##UPPERCASE: \
1175 while (input->BytesUntilLimit() > 0) { \
1176 CPP_LOWERCASE value; \
1177 if (!WireFormatLite::ReadPrimitive< \
1178 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1179 input, &value)) return false; \
1180 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
1181 extension.is_packed, value, \
1182 extension.descriptor); \
1183 } \
1184 break
1185
1186 HANDLE_TYPE( INT32, Int32, int32);
1187 HANDLE_TYPE( INT64, Int64, int64);
1188 HANDLE_TYPE( UINT32, UInt32, uint32);
1189 HANDLE_TYPE( UINT64, UInt64, uint64);
1190 HANDLE_TYPE( SINT32, Int32, int32);
1191 HANDLE_TYPE( SINT64, Int64, int64);
1192 HANDLE_TYPE( FIXED32, UInt32, uint32);
1193 HANDLE_TYPE( FIXED64, UInt64, uint64);
1194 HANDLE_TYPE(SFIXED32, Int32, int32);
1195 HANDLE_TYPE(SFIXED64, Int64, int64);
1196 HANDLE_TYPE( FLOAT, Float, float);
1197 HANDLE_TYPE( DOUBLE, Double, double);
1198 HANDLE_TYPE( BOOL, Bool, bool);
1199 #undef HANDLE_TYPE
1200
1201 case WireFormatLite::TYPE_ENUM:
1202 while (input->BytesUntilLimit() > 0) {
1203 int value;
1204 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1205 input, &value)) return false;
1206 if (extension.enum_validity_check.func(
1207 extension.enum_validity_check.arg, value)) {
1208 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1209 value, extension.descriptor);
1210 } else {
1211 // Invalid value. Treat as unknown.
1212 field_skipper->SkipUnknownEnum(number, value);
1213 }
1214 }
1215 break;
1216
1217 case WireFormatLite::TYPE_STRING:
1218 case WireFormatLite::TYPE_BYTES:
1219 case WireFormatLite::TYPE_GROUP:
1220 case WireFormatLite::TYPE_MESSAGE:
1221 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1222 break;
1223 }
1224
1225 input->PopLimit(limit);
1226 } else {
1227 switch (extension.type) {
1228 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
1229 case WireFormatLite::TYPE_##UPPERCASE: { \
1230 CPP_LOWERCASE value; \
1231 if (!WireFormatLite::ReadPrimitive< \
1232 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1233 input, &value)) return false; \
1234 if (extension.is_repeated) { \
1235 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
1236 extension.is_packed, value, \
1237 extension.descriptor); \
1238 } else { \
1239 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
1240 extension.descriptor); \
1241 } \
1242 } break
1243
1244 HANDLE_TYPE( INT32, Int32, int32);
1245 HANDLE_TYPE( INT64, Int64, int64);
1246 HANDLE_TYPE( UINT32, UInt32, uint32);
1247 HANDLE_TYPE( UINT64, UInt64, uint64);
1248 HANDLE_TYPE( SINT32, Int32, int32);
1249 HANDLE_TYPE( SINT64, Int64, int64);
1250 HANDLE_TYPE( FIXED32, UInt32, uint32);
1251 HANDLE_TYPE( FIXED64, UInt64, uint64);
1252 HANDLE_TYPE(SFIXED32, Int32, int32);
1253 HANDLE_TYPE(SFIXED64, Int64, int64);
1254 HANDLE_TYPE( FLOAT, Float, float);
1255 HANDLE_TYPE( DOUBLE, Double, double);
1256 HANDLE_TYPE( BOOL, Bool, bool);
1257 #undef HANDLE_TYPE
1258
1259 case WireFormatLite::TYPE_ENUM: {
1260 int value;
1261 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1262 input, &value)) return false;
1263
1264 if (!extension.enum_validity_check.func(
1265 extension.enum_validity_check.arg, value)) {
1266 // Invalid value. Treat as unknown.
1267 field_skipper->SkipUnknownEnum(number, value);
1268 } else if (extension.is_repeated) {
1269 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
1270 extension.descriptor);
1271 } else {
1272 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1273 extension.descriptor);
1274 }
1275 break;
1276 }
1277
1278 case WireFormatLite::TYPE_STRING: {
1279 string* value = extension.is_repeated ?
1280 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1281 MutableString(number, WireFormatLite::TYPE_STRING,
1282 extension.descriptor);
1283 if (!WireFormatLite::ReadString(input, value)) return false;
1284 break;
1285 }
1286
1287 case WireFormatLite::TYPE_BYTES: {
1288 string* value = extension.is_repeated ?
1289 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1290 MutableString(number, WireFormatLite::TYPE_BYTES,
1291 extension.descriptor);
1292 if (!WireFormatLite::ReadBytes(input, value)) return false;
1293 break;
1294 }
1295
1296 case WireFormatLite::TYPE_GROUP: {
1297 MessageLite* value = extension.is_repeated ?
1298 AddMessage(number, WireFormatLite::TYPE_GROUP,
1299 *extension.message_prototype, extension.descriptor) :
1300 MutableMessage(number, WireFormatLite::TYPE_GROUP,
1301 *extension.message_prototype, extension.descriptor);
1302 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1303 break;
1304 }
1305
1306 case WireFormatLite::TYPE_MESSAGE: {
1307 MessageLite* value = extension.is_repeated ?
1308 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1309 *extension.message_prototype, extension.descriptor) :
1310 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1311 *extension.message_prototype, extension.descriptor);
1312 if (!WireFormatLite::ReadMessage(input, value)) return false;
1313 break;
1314 }
1315 }
1316 }
1317
1318 return true;
1319 }
1320
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type)1321 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1322 const MessageLite* containing_type) {
1323 FieldSkipper skipper;
1324 GeneratedExtensionFinder finder(containing_type);
1325 return ParseField(tag, input, &finder, &skipper);
1326 }
1327
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type,io::CodedOutputStream * unknown_fields)1328 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1329 const MessageLite* containing_type,
1330 io::CodedOutputStream* unknown_fields) {
1331 CodedOutputStreamFieldSkipper skipper(unknown_fields);
1332 GeneratedExtensionFinder finder(containing_type);
1333 return ParseField(tag, input, &finder, &skipper);
1334 }
1335
1336 // Defined in extension_set_heavy.cc.
1337 // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1338 // const MessageLite* containing_type,
1339 // UnknownFieldSet* unknown_fields)
1340
1341 // Defined in extension_set_heavy.cc.
1342 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1343 // const MessageLite* containing_type,
1344 // UnknownFieldSet* unknown_fields);
1345
SerializeWithCachedSizes(int start_field_number,int end_field_number,io::CodedOutputStream * output) const1346 void ExtensionSet::SerializeWithCachedSizes(
1347 int start_field_number, int end_field_number,
1348 io::CodedOutputStream* output) const {
1349 ExtensionMap::const_iterator iter;
1350 for (iter = extensions_.lower_bound(start_field_number);
1351 iter != extensions_.end() && iter->first < end_field_number;
1352 ++iter) {
1353 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1354 }
1355 }
1356
ByteSize() const1357 int ExtensionSet::ByteSize() const {
1358 int total_size = 0;
1359
1360 for (ExtensionMap::const_iterator iter = extensions_.begin();
1361 iter != extensions_.end(); ++iter) {
1362 total_size += iter->second.ByteSize(iter->first);
1363 }
1364
1365 return total_size;
1366 }
1367
1368 // Defined in extension_set_heavy.cc.
1369 // int ExtensionSet::SpaceUsedExcludingSelf() const
1370
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1371 bool ExtensionSet::MaybeNewExtension(int number,
1372 const FieldDescriptor* descriptor,
1373 Extension** result) {
1374 pair<ExtensionMap::iterator, bool> insert_result =
1375 extensions_.insert(std::make_pair(number, Extension()));
1376 *result = &insert_result.first->second;
1377 (*result)->descriptor = descriptor;
1378 return insert_result.second;
1379 }
1380
1381 // ===================================================================
1382 // Methods of ExtensionSet::Extension
1383
Clear()1384 void ExtensionSet::Extension::Clear() {
1385 if (is_repeated) {
1386 switch (cpp_type(type)) {
1387 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1388 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1389 repeated_##LOWERCASE##_value->Clear(); \
1390 break
1391
1392 HANDLE_TYPE( INT32, int32);
1393 HANDLE_TYPE( INT64, int64);
1394 HANDLE_TYPE( UINT32, uint32);
1395 HANDLE_TYPE( UINT64, uint64);
1396 HANDLE_TYPE( FLOAT, float);
1397 HANDLE_TYPE( DOUBLE, double);
1398 HANDLE_TYPE( BOOL, bool);
1399 HANDLE_TYPE( ENUM, enum);
1400 HANDLE_TYPE( STRING, string);
1401 HANDLE_TYPE(MESSAGE, message);
1402 #undef HANDLE_TYPE
1403 }
1404 } else {
1405 if (!is_cleared) {
1406 switch (cpp_type(type)) {
1407 case WireFormatLite::CPPTYPE_STRING:
1408 string_value->clear();
1409 break;
1410 case WireFormatLite::CPPTYPE_MESSAGE:
1411 if (is_lazy) {
1412 lazymessage_value->Clear();
1413 } else {
1414 message_value->Clear();
1415 }
1416 break;
1417 default:
1418 // No need to do anything. Get*() will return the default value
1419 // as long as is_cleared is true and Set*() will overwrite the
1420 // previous value.
1421 break;
1422 }
1423
1424 is_cleared = true;
1425 }
1426 }
1427 }
1428
SerializeFieldWithCachedSizes(int number,io::CodedOutputStream * output) const1429 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1430 int number,
1431 io::CodedOutputStream* output) const {
1432 if (is_repeated) {
1433 if (is_packed) {
1434 if (cached_size == 0) return;
1435
1436 WireFormatLite::WriteTag(number,
1437 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1438 output->WriteVarint32(cached_size);
1439
1440 switch (real_type(type)) {
1441 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1442 case WireFormatLite::TYPE_##UPPERCASE: \
1443 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1444 WireFormatLite::Write##CAMELCASE##NoTag( \
1445 repeated_##LOWERCASE##_value->Get(i), output); \
1446 } \
1447 break
1448
1449 HANDLE_TYPE( INT32, Int32, int32);
1450 HANDLE_TYPE( INT64, Int64, int64);
1451 HANDLE_TYPE( UINT32, UInt32, uint32);
1452 HANDLE_TYPE( UINT64, UInt64, uint64);
1453 HANDLE_TYPE( SINT32, SInt32, int32);
1454 HANDLE_TYPE( SINT64, SInt64, int64);
1455 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1456 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1457 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1458 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1459 HANDLE_TYPE( FLOAT, Float, float);
1460 HANDLE_TYPE( DOUBLE, Double, double);
1461 HANDLE_TYPE( BOOL, Bool, bool);
1462 HANDLE_TYPE( ENUM, Enum, enum);
1463 #undef HANDLE_TYPE
1464
1465 case WireFormatLite::TYPE_STRING:
1466 case WireFormatLite::TYPE_BYTES:
1467 case WireFormatLite::TYPE_GROUP:
1468 case WireFormatLite::TYPE_MESSAGE:
1469 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1470 break;
1471 }
1472 } else {
1473 switch (real_type(type)) {
1474 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1475 case WireFormatLite::TYPE_##UPPERCASE: \
1476 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1477 WireFormatLite::Write##CAMELCASE(number, \
1478 repeated_##LOWERCASE##_value->Get(i), output); \
1479 } \
1480 break
1481
1482 HANDLE_TYPE( INT32, Int32, int32);
1483 HANDLE_TYPE( INT64, Int64, int64);
1484 HANDLE_TYPE( UINT32, UInt32, uint32);
1485 HANDLE_TYPE( UINT64, UInt64, uint64);
1486 HANDLE_TYPE( SINT32, SInt32, int32);
1487 HANDLE_TYPE( SINT64, SInt64, int64);
1488 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1489 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1490 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1491 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1492 HANDLE_TYPE( FLOAT, Float, float);
1493 HANDLE_TYPE( DOUBLE, Double, double);
1494 HANDLE_TYPE( BOOL, Bool, bool);
1495 HANDLE_TYPE( STRING, String, string);
1496 HANDLE_TYPE( BYTES, Bytes, string);
1497 HANDLE_TYPE( ENUM, Enum, enum);
1498 HANDLE_TYPE( GROUP, Group, message);
1499 HANDLE_TYPE( MESSAGE, Message, message);
1500 #undef HANDLE_TYPE
1501 }
1502 }
1503 } else if (!is_cleared) {
1504 switch (real_type(type)) {
1505 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
1506 case WireFormatLite::TYPE_##UPPERCASE: \
1507 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1508 break
1509
1510 HANDLE_TYPE( INT32, Int32, int32_value);
1511 HANDLE_TYPE( INT64, Int64, int64_value);
1512 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1513 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1514 HANDLE_TYPE( SINT32, SInt32, int32_value);
1515 HANDLE_TYPE( SINT64, SInt64, int64_value);
1516 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1517 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1518 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1519 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1520 HANDLE_TYPE( FLOAT, Float, float_value);
1521 HANDLE_TYPE( DOUBLE, Double, double_value);
1522 HANDLE_TYPE( BOOL, Bool, bool_value);
1523 HANDLE_TYPE( STRING, String, *string_value);
1524 HANDLE_TYPE( BYTES, Bytes, *string_value);
1525 HANDLE_TYPE( ENUM, Enum, enum_value);
1526 HANDLE_TYPE( GROUP, Group, *message_value);
1527 #undef HANDLE_TYPE
1528 case WireFormatLite::TYPE_MESSAGE:
1529 if (is_lazy) {
1530 lazymessage_value->WriteMessage(number, output);
1531 } else {
1532 WireFormatLite::WriteMessage(number, *message_value, output);
1533 }
1534 break;
1535 }
1536 }
1537 }
1538
ByteSize(int number) const1539 int ExtensionSet::Extension::ByteSize(int number) const {
1540 int result = 0;
1541
1542 if (is_repeated) {
1543 if (is_packed) {
1544 switch (real_type(type)) {
1545 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1546 case WireFormatLite::TYPE_##UPPERCASE: \
1547 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1548 result += WireFormatLite::CAMELCASE##Size( \
1549 repeated_##LOWERCASE##_value->Get(i)); \
1550 } \
1551 break
1552
1553 HANDLE_TYPE( INT32, Int32, int32);
1554 HANDLE_TYPE( INT64, Int64, int64);
1555 HANDLE_TYPE( UINT32, UInt32, uint32);
1556 HANDLE_TYPE( UINT64, UInt64, uint64);
1557 HANDLE_TYPE( SINT32, SInt32, int32);
1558 HANDLE_TYPE( SINT64, SInt64, int64);
1559 HANDLE_TYPE( ENUM, Enum, enum);
1560 #undef HANDLE_TYPE
1561
1562 // Stuff with fixed size.
1563 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1564 case WireFormatLite::TYPE_##UPPERCASE: \
1565 result += WireFormatLite::k##CAMELCASE##Size * \
1566 repeated_##LOWERCASE##_value->size(); \
1567 break
1568 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1569 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1570 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1571 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1572 HANDLE_TYPE( FLOAT, Float, float);
1573 HANDLE_TYPE( DOUBLE, Double, double);
1574 HANDLE_TYPE( BOOL, Bool, bool);
1575 #undef HANDLE_TYPE
1576
1577 case WireFormatLite::TYPE_STRING:
1578 case WireFormatLite::TYPE_BYTES:
1579 case WireFormatLite::TYPE_GROUP:
1580 case WireFormatLite::TYPE_MESSAGE:
1581 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1582 break;
1583 }
1584
1585 cached_size = result;
1586 if (result > 0) {
1587 result += io::CodedOutputStream::VarintSize32(result);
1588 result += io::CodedOutputStream::VarintSize32(
1589 WireFormatLite::MakeTag(number,
1590 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1591 }
1592 } else {
1593 int tag_size = WireFormatLite::TagSize(number, real_type(type));
1594
1595 switch (real_type(type)) {
1596 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1597 case WireFormatLite::TYPE_##UPPERCASE: \
1598 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1599 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1600 result += WireFormatLite::CAMELCASE##Size( \
1601 repeated_##LOWERCASE##_value->Get(i)); \
1602 } \
1603 break
1604
1605 HANDLE_TYPE( INT32, Int32, int32);
1606 HANDLE_TYPE( INT64, Int64, int64);
1607 HANDLE_TYPE( UINT32, UInt32, uint32);
1608 HANDLE_TYPE( UINT64, UInt64, uint64);
1609 HANDLE_TYPE( SINT32, SInt32, int32);
1610 HANDLE_TYPE( SINT64, SInt64, int64);
1611 HANDLE_TYPE( STRING, String, string);
1612 HANDLE_TYPE( BYTES, Bytes, string);
1613 HANDLE_TYPE( ENUM, Enum, enum);
1614 HANDLE_TYPE( GROUP, Group, message);
1615 HANDLE_TYPE( MESSAGE, Message, message);
1616 #undef HANDLE_TYPE
1617
1618 // Stuff with fixed size.
1619 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1620 case WireFormatLite::TYPE_##UPPERCASE: \
1621 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
1622 repeated_##LOWERCASE##_value->size(); \
1623 break
1624 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1625 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1626 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1627 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1628 HANDLE_TYPE( FLOAT, Float, float);
1629 HANDLE_TYPE( DOUBLE, Double, double);
1630 HANDLE_TYPE( BOOL, Bool, bool);
1631 #undef HANDLE_TYPE
1632 }
1633 }
1634 } else if (!is_cleared) {
1635 result += WireFormatLite::TagSize(number, real_type(type));
1636 switch (real_type(type)) {
1637 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1638 case WireFormatLite::TYPE_##UPPERCASE: \
1639 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1640 break
1641
1642 HANDLE_TYPE( INT32, Int32, int32_value);
1643 HANDLE_TYPE( INT64, Int64, int64_value);
1644 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1645 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1646 HANDLE_TYPE( SINT32, SInt32, int32_value);
1647 HANDLE_TYPE( SINT64, SInt64, int64_value);
1648 HANDLE_TYPE( STRING, String, *string_value);
1649 HANDLE_TYPE( BYTES, Bytes, *string_value);
1650 HANDLE_TYPE( ENUM, Enum, enum_value);
1651 HANDLE_TYPE( GROUP, Group, *message_value);
1652 #undef HANDLE_TYPE
1653 case WireFormatLite::TYPE_MESSAGE: {
1654 if (is_lazy) {
1655 int size = lazymessage_value->ByteSize();
1656 result += io::CodedOutputStream::VarintSize32(size) + size;
1657 } else {
1658 result += WireFormatLite::MessageSize(*message_value);
1659 }
1660 break;
1661 }
1662
1663 // Stuff with fixed size.
1664 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1665 case WireFormatLite::TYPE_##UPPERCASE: \
1666 result += WireFormatLite::k##CAMELCASE##Size; \
1667 break
1668 HANDLE_TYPE( FIXED32, Fixed32);
1669 HANDLE_TYPE( FIXED64, Fixed64);
1670 HANDLE_TYPE(SFIXED32, SFixed32);
1671 HANDLE_TYPE(SFIXED64, SFixed64);
1672 HANDLE_TYPE( FLOAT, Float);
1673 HANDLE_TYPE( DOUBLE, Double);
1674 HANDLE_TYPE( BOOL, Bool);
1675 #undef HANDLE_TYPE
1676 }
1677 }
1678
1679 return result;
1680 }
1681
GetSize() const1682 int ExtensionSet::Extension::GetSize() const {
1683 GOOGLE_DCHECK(is_repeated);
1684 switch (cpp_type(type)) {
1685 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1686 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1687 return repeated_##LOWERCASE##_value->size()
1688
1689 HANDLE_TYPE( INT32, int32);
1690 HANDLE_TYPE( INT64, int64);
1691 HANDLE_TYPE( UINT32, uint32);
1692 HANDLE_TYPE( UINT64, uint64);
1693 HANDLE_TYPE( FLOAT, float);
1694 HANDLE_TYPE( DOUBLE, double);
1695 HANDLE_TYPE( BOOL, bool);
1696 HANDLE_TYPE( ENUM, enum);
1697 HANDLE_TYPE( STRING, string);
1698 HANDLE_TYPE(MESSAGE, message);
1699 #undef HANDLE_TYPE
1700 }
1701
1702 GOOGLE_LOG(FATAL) << "Can't get here.";
1703 return 0;
1704 }
1705
1706 // This function deletes all allocated objects. This function should be only
1707 // called if the Extension was created with an arena.
Free()1708 void ExtensionSet::Extension::Free() {
1709 if (is_repeated) {
1710 switch (cpp_type(type)) {
1711 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1712 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1713 delete repeated_##LOWERCASE##_value; \
1714 break
1715
1716 HANDLE_TYPE( INT32, int32);
1717 HANDLE_TYPE( INT64, int64);
1718 HANDLE_TYPE( UINT32, uint32);
1719 HANDLE_TYPE( UINT64, uint64);
1720 HANDLE_TYPE( FLOAT, float);
1721 HANDLE_TYPE( DOUBLE, double);
1722 HANDLE_TYPE( BOOL, bool);
1723 HANDLE_TYPE( ENUM, enum);
1724 HANDLE_TYPE( STRING, string);
1725 HANDLE_TYPE(MESSAGE, message);
1726 #undef HANDLE_TYPE
1727 }
1728 } else {
1729 switch (cpp_type(type)) {
1730 case WireFormatLite::CPPTYPE_STRING:
1731 delete string_value;
1732 break;
1733 case WireFormatLite::CPPTYPE_MESSAGE:
1734 if (is_lazy) {
1735 delete lazymessage_value;
1736 } else {
1737 delete message_value;
1738 }
1739 break;
1740 default:
1741 break;
1742 }
1743 }
1744 }
1745
1746 // Defined in extension_set_heavy.cc.
1747 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1748
1749 // ==================================================================
1750 // Default repeated field instances for iterator-compatible accessors
1751
1752 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_primitive_generic_type_traits_once_init_);
1753 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_string_type_traits_once_init_);
1754 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_message_generic_type_traits_once_init_);
1755
InitializeDefaultRepeatedFields()1756 void RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields() {
1757 default_repeated_field_int32_ = new RepeatedField<int32>;
1758 default_repeated_field_int64_ = new RepeatedField<int64>;
1759 default_repeated_field_uint32_ = new RepeatedField<uint32>;
1760 default_repeated_field_uint64_ = new RepeatedField<uint64>;
1761 default_repeated_field_double_ = new RepeatedField<double>;
1762 default_repeated_field_float_ = new RepeatedField<float>;
1763 default_repeated_field_bool_ = new RepeatedField<bool>;
1764 OnShutdown(&DestroyDefaultRepeatedFields);
1765 }
1766
DestroyDefaultRepeatedFields()1767 void RepeatedPrimitiveGenericTypeTraits::DestroyDefaultRepeatedFields() {
1768 delete default_repeated_field_int32_;
1769 delete default_repeated_field_int64_;
1770 delete default_repeated_field_uint32_;
1771 delete default_repeated_field_uint64_;
1772 delete default_repeated_field_double_;
1773 delete default_repeated_field_float_;
1774 delete default_repeated_field_bool_;
1775 }
1776
InitializeDefaultRepeatedFields()1777 void RepeatedStringTypeTraits::InitializeDefaultRepeatedFields() {
1778 default_repeated_field_ = new RepeatedFieldType;
1779 OnShutdown(&DestroyDefaultRepeatedFields);
1780 }
1781
DestroyDefaultRepeatedFields()1782 void RepeatedStringTypeTraits::DestroyDefaultRepeatedFields() {
1783 delete default_repeated_field_;
1784 }
1785
InitializeDefaultRepeatedFields()1786 void RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields() {
1787 default_repeated_field_ = new RepeatedFieldType;
1788 OnShutdown(&DestroyDefaultRepeatedFields);
1789 }
1790
DestroyDefaultRepeatedFields()1791 void RepeatedMessageGenericTypeTraits::DestroyDefaultRepeatedFields() {
1792 delete default_repeated_field_;
1793 }
1794
1795 const RepeatedField<int32>*
1796 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ = NULL;
1797 const RepeatedField<int64>*
1798 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ = NULL;
1799 const RepeatedField<uint32>*
1800 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ = NULL;
1801 const RepeatedField<uint64>*
1802 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ = NULL;
1803 const RepeatedField<double>*
1804 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ = NULL;
1805 const RepeatedField<float>*
1806 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ = NULL;
1807 const RepeatedField<bool>*
1808 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ = NULL;
1809 const RepeatedStringTypeTraits::RepeatedFieldType*
1810 RepeatedStringTypeTraits::default_repeated_field_ = NULL;
1811 const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
1812 RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
1813
1814 } // namespace internal
1815 } // namespace protobuf
1816 } // namespace google
1817