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