1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
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/io/zero_copy_stream_impl.h>
42 #include <google/protobuf/wire_format_lite_inl.h>
43 #include <google/protobuf/repeated_field.h>
44 #include <google/protobuf/stubs/map-util.h>
45
46 namespace google {
47 namespace protobuf {
48 namespace internal {
49
50 namespace {
51
real_type(FieldType type)52 inline WireFormatLite::FieldType real_type(FieldType type) {
53 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
54 return static_cast<WireFormatLite::FieldType>(type);
55 }
56
cpp_type(FieldType type)57 inline WireFormatLite::CppType cpp_type(FieldType type) {
58 return WireFormatLite::FieldTypeToCppType(real_type(type));
59 }
60
61 // Registry stuff.
62 typedef hash_map<pair<const MessageLite*, int>,
63 ExtensionInfo> ExtensionRegistry;
64 ExtensionRegistry* registry_ = NULL;
65 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
66
DeleteRegistry()67 void DeleteRegistry() {
68 delete registry_;
69 registry_ = NULL;
70 }
71
InitRegistry()72 void InitRegistry() {
73 registry_ = new ExtensionRegistry;
74 OnShutdown(&DeleteRegistry);
75 }
76
77 // This function is only called at startup, so there is no need for thread-
78 // safety.
Register(const MessageLite * containing_type,int number,ExtensionInfo info)79 void Register(const MessageLite* containing_type,
80 int number, ExtensionInfo info) {
81 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry);
82
83 if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
84 info)) {
85 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
86 << containing_type->GetTypeName()
87 << "\", field number " << number << ".";
88 }
89 }
90
FindRegisteredExtension(const MessageLite * containing_type,int number)91 const ExtensionInfo* FindRegisteredExtension(
92 const MessageLite* containing_type, int number) {
93 return (registry_ == NULL) ? NULL :
94 FindOrNull(*registry_, make_pair(containing_type, number));
95 }
96
97 } // namespace
98
~ExtensionFinder()99 ExtensionFinder::~ExtensionFinder() {}
100
Find(int number,ExtensionInfo * output)101 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
102 const ExtensionInfo* extension =
103 FindRegisteredExtension(containing_type_, number);
104 if (extension == NULL) {
105 return false;
106 } else {
107 *output = *extension;
108 return true;
109 }
110 }
111
RegisterExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed)112 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
113 int number, FieldType type,
114 bool is_repeated, bool is_packed) {
115 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
116 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
117 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
118 ExtensionInfo info(type, is_repeated, is_packed);
119 Register(containing_type, number, info);
120 }
121
CallNoArgValidityFunc(const void * arg,int number)122 static bool CallNoArgValidityFunc(const void* arg, int number) {
123 // Note: Must use C-style cast here rather than reinterpret_cast because
124 // the C++ standard at one point did not allow casts between function and
125 // data pointers and some compilers enforce this for C++-style casts. No
126 // compiler enforces it for C-style casts since lots of C-style code has
127 // relied on these kinds of casts for a long time, despite being
128 // technically undefined. See:
129 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
130 // Also note: Some compilers do not allow function pointers to be "const".
131 // Which makes sense, I suppose, because it's meaningless.
132 return ((EnumValidityFunc*)arg)(number);
133 }
134
RegisterEnumExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,EnumValidityFunc * is_valid)135 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
136 int number, FieldType type,
137 bool is_repeated, bool is_packed,
138 EnumValidityFunc* is_valid) {
139 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
140 ExtensionInfo info(type, is_repeated, is_packed);
141 info.enum_validity_check.func = CallNoArgValidityFunc;
142 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
143 info.enum_validity_check.arg = (void*)is_valid;
144 Register(containing_type, number, info);
145 }
146
RegisterMessageExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,const MessageLite * prototype)147 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
148 int number, FieldType type,
149 bool is_repeated, bool is_packed,
150 const MessageLite* prototype) {
151 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
152 type == WireFormatLite::TYPE_GROUP);
153 ExtensionInfo info(type, is_repeated, is_packed);
154 info.message_prototype = prototype;
155 Register(containing_type, number, info);
156 }
157
158
159 // ===================================================================
160 // Constructors and basic methods.
161
ExtensionSet()162 ExtensionSet::ExtensionSet() {}
163
~ExtensionSet()164 ExtensionSet::~ExtensionSet() {
165 for (map<int, Extension>::iterator iter = extensions_.begin();
166 iter != extensions_.end(); ++iter) {
167 iter->second.Free();
168 }
169 }
170
171 // Defined in extension_set_heavy.cc.
172 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
173 // const DescriptorPool* pool,
174 // vector<const FieldDescriptor*>* output) const
175
Has(int number) const176 bool ExtensionSet::Has(int number) const {
177 map<int, Extension>::const_iterator iter = extensions_.find(number);
178 if (iter == extensions_.end()) return false;
179 GOOGLE_DCHECK(!iter->second.is_repeated);
180 return !iter->second.is_cleared;
181 }
182
NumExtensions() const183 int ExtensionSet::NumExtensions() const {
184 int result = 0;
185 for (map<int, Extension>::const_iterator iter = extensions_.begin();
186 iter != extensions_.end(); ++iter) {
187 if (!iter->second.is_cleared) {
188 ++result;
189 }
190 }
191 return result;
192 }
193
ExtensionSize(int number) const194 int ExtensionSet::ExtensionSize(int number) const {
195 map<int, Extension>::const_iterator iter = extensions_.find(number);
196 if (iter == extensions_.end()) return false;
197 return iter->second.GetSize();
198 }
199
ExtensionType(int number) const200 FieldType ExtensionSet::ExtensionType(int number) const {
201 map<int, Extension>::const_iterator iter = extensions_.find(number);
202 if (iter == extensions_.end()) {
203 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
204 return 0;
205 }
206 if (iter->second.is_cleared) {
207 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
208 }
209 return iter->second.type;
210 }
211
ClearExtension(int number)212 void ExtensionSet::ClearExtension(int number) {
213 map<int, Extension>::iterator iter = extensions_.find(number);
214 if (iter == extensions_.end()) return;
215 iter->second.Clear();
216 }
217
218 // ===================================================================
219 // Field accessors
220
221 namespace {
222
223 enum Cardinality {
224 REPEATED,
225 OPTIONAL
226 };
227
228 } // namespace
229
230 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
231 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
232 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
233
234 // -------------------------------------------------------------------
235 // Primitives
236
237 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
238 \
239 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
240 LOWERCASE default_value) const { \
241 map<int, Extension>::const_iterator iter = extensions_.find(number); \
242 if (iter == extensions_.end() || iter->second.is_cleared) { \
243 return default_value; \
244 } else { \
245 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
246 return iter->second.LOWERCASE##_value; \
247 } \
248 } \
249 \
250 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
251 LOWERCASE value, \
252 const FieldDescriptor* descriptor) { \
253 Extension* extension; \
254 if (MaybeNewExtension(number, descriptor, &extension)) { \
255 extension->type = type; \
256 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
257 extension->is_repeated = false; \
258 } else { \
259 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
260 } \
261 extension->is_cleared = false; \
262 extension->LOWERCASE##_value = value; \
263 } \
264 \
265 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
266 map<int, Extension>::const_iterator iter = extensions_.find(number); \
267 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
268 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
269 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
270 } \
271 \
272 void ExtensionSet::SetRepeated##CAMELCASE( \
273 int number, int index, LOWERCASE value) { \
274 map<int, Extension>::iterator iter = extensions_.find(number); \
275 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
276 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
277 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
278 } \
279 \
280 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
281 bool packed, LOWERCASE value, \
282 const FieldDescriptor* descriptor) { \
283 Extension* extension; \
284 if (MaybeNewExtension(number, descriptor, &extension)) { \
285 extension->type = type; \
286 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
287 extension->is_repeated = true; \
288 extension->is_packed = packed; \
289 extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
290 } else { \
291 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
292 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
293 } \
294 extension->repeated_##LOWERCASE##_value->Add(value); \
295 }
296
PRIMITIVE_ACCESSORS(INT32,int32,Int32)297 PRIMITIVE_ACCESSORS( INT32, int32, Int32)
298 PRIMITIVE_ACCESSORS( INT64, int64, Int64)
299 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
300 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
301 PRIMITIVE_ACCESSORS( FLOAT, float, Float)
302 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
303 PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
304
305 #undef PRIMITIVE_ACCESSORS
306
307 void* ExtensionSet::MutableRawRepeatedField(int number) {
308 // We assume that all the RepeatedField<>* pointers have the same
309 // size and alignment within the anonymous union in Extension.
310 map<int, Extension>::const_iterator iter = extensions_.find(number);
311 GOOGLE_CHECK(iter != extensions_.end()) << "no extension numbered " << number;
312 return iter->second.repeated_int32_value;
313 }
314
315 // -------------------------------------------------------------------
316 // Enums
317
GetEnum(int number,int default_value) const318 int ExtensionSet::GetEnum(int number, int default_value) const {
319 map<int, Extension>::const_iterator iter = extensions_.find(number);
320 if (iter == extensions_.end() || iter->second.is_cleared) {
321 // Not present. Return the default value.
322 return default_value;
323 } else {
324 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
325 return iter->second.enum_value;
326 }
327 }
328
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)329 void ExtensionSet::SetEnum(int number, FieldType type, int value,
330 const FieldDescriptor* descriptor) {
331 Extension* extension;
332 if (MaybeNewExtension(number, descriptor, &extension)) {
333 extension->type = type;
334 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
335 extension->is_repeated = false;
336 } else {
337 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
338 }
339 extension->is_cleared = false;
340 extension->enum_value = value;
341 }
342
GetRepeatedEnum(int number,int index) const343 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
344 map<int, Extension>::const_iterator iter = extensions_.find(number);
345 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
346 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
347 return iter->second.repeated_enum_value->Get(index);
348 }
349
SetRepeatedEnum(int number,int index,int value)350 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
351 map<int, Extension>::iterator iter = extensions_.find(number);
352 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
353 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
354 iter->second.repeated_enum_value->Set(index, value);
355 }
356
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)357 void ExtensionSet::AddEnum(int number, FieldType type,
358 bool packed, int value,
359 const FieldDescriptor* descriptor) {
360 Extension* extension;
361 if (MaybeNewExtension(number, descriptor, &extension)) {
362 extension->type = type;
363 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
364 extension->is_repeated = true;
365 extension->is_packed = packed;
366 extension->repeated_enum_value = new RepeatedField<int>();
367 } else {
368 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
369 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
370 }
371 extension->repeated_enum_value->Add(value);
372 }
373
374 // -------------------------------------------------------------------
375 // Strings
376
GetString(int number,const string & default_value) const377 const string& ExtensionSet::GetString(int number,
378 const string& default_value) const {
379 map<int, Extension>::const_iterator iter = extensions_.find(number);
380 if (iter == extensions_.end() || iter->second.is_cleared) {
381 // Not present. Return the default value.
382 return default_value;
383 } else {
384 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
385 return *iter->second.string_value;
386 }
387 }
388
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)389 string* ExtensionSet::MutableString(int number, FieldType type,
390 const FieldDescriptor* descriptor) {
391 Extension* extension;
392 if (MaybeNewExtension(number, descriptor, &extension)) {
393 extension->type = type;
394 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
395 extension->is_repeated = false;
396 extension->string_value = new string;
397 } else {
398 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
399 }
400 extension->is_cleared = false;
401 return extension->string_value;
402 }
403
GetRepeatedString(int number,int index) const404 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
405 map<int, Extension>::const_iterator iter = extensions_.find(number);
406 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
407 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
408 return iter->second.repeated_string_value->Get(index);
409 }
410
MutableRepeatedString(int number,int index)411 string* ExtensionSet::MutableRepeatedString(int number, int index) {
412 map<int, Extension>::iterator iter = extensions_.find(number);
413 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
414 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
415 return iter->second.repeated_string_value->Mutable(index);
416 }
417
AddString(int number,FieldType type,const FieldDescriptor * descriptor)418 string* ExtensionSet::AddString(int number, FieldType type,
419 const FieldDescriptor* descriptor) {
420 Extension* extension;
421 if (MaybeNewExtension(number, descriptor, &extension)) {
422 extension->type = type;
423 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
424 extension->is_repeated = true;
425 extension->is_packed = false;
426 extension->repeated_string_value = new RepeatedPtrField<string>();
427 } else {
428 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
429 }
430 return extension->repeated_string_value->Add();
431 }
432
433 // -------------------------------------------------------------------
434 // Messages
435
GetMessage(int number,const MessageLite & default_value) const436 const MessageLite& ExtensionSet::GetMessage(
437 int number, const MessageLite& default_value) const {
438 map<int, Extension>::const_iterator iter = extensions_.find(number);
439 if (iter == extensions_.end()) {
440 // Not present. Return the default value.
441 return default_value;
442 } else {
443 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
444 if (iter->second.is_lazy) {
445 return iter->second.lazymessage_value->GetMessage(default_value);
446 } else {
447 return *iter->second.message_value;
448 }
449 }
450 }
451
452 // Defined in extension_set_heavy.cc.
453 // const MessageLite& ExtensionSet::GetMessage(int number,
454 // const Descriptor* message_type,
455 // MessageFactory* factory) const
456
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)457 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
458 const MessageLite& prototype,
459 const FieldDescriptor* descriptor) {
460 Extension* extension;
461 if (MaybeNewExtension(number, descriptor, &extension)) {
462 extension->type = type;
463 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
464 extension->is_repeated = false;
465 extension->is_lazy = false;
466 extension->message_value = prototype.New();
467 extension->is_cleared = false;
468 return extension->message_value;
469 } else {
470 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
471 extension->is_cleared = false;
472 if (extension->is_lazy) {
473 return extension->lazymessage_value->MutableMessage(prototype);
474 } else {
475 return extension->message_value;
476 }
477 }
478 }
479
480 // Defined in extension_set_heavy.cc.
481 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
482 // const Descriptor* message_type,
483 // MessageFactory* factory)
484
SetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)485 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
486 const FieldDescriptor* descriptor,
487 MessageLite* message) {
488 if (message == NULL) {
489 ClearExtension(number);
490 return;
491 }
492 Extension* extension;
493 if (MaybeNewExtension(number, descriptor, &extension)) {
494 extension->type = type;
495 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
496 extension->is_repeated = false;
497 extension->is_lazy = false;
498 extension->message_value = message;
499 } else {
500 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
501 if (extension->is_lazy) {
502 extension->lazymessage_value->SetAllocatedMessage(message);
503 } else {
504 delete extension->message_value;
505 extension->message_value = message;
506 }
507 }
508 extension->is_cleared = false;
509 }
510
ReleaseMessage(int number,const MessageLite & prototype)511 MessageLite* ExtensionSet::ReleaseMessage(int number,
512 const MessageLite& prototype) {
513 map<int, Extension>::iterator iter = extensions_.find(number);
514 if (iter == extensions_.end()) {
515 // Not present. Return NULL.
516 return NULL;
517 } else {
518 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
519 MessageLite* ret = NULL;
520 if (iter->second.is_lazy) {
521 ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
522 delete iter->second.lazymessage_value;
523 } else {
524 ret = iter->second.message_value;
525 }
526 extensions_.erase(number);
527 return ret;
528 }
529 }
530
531 // Defined in extension_set_heavy.cc.
532 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
533 // MessageFactory* factory);
534
GetRepeatedMessage(int number,int index) const535 const MessageLite& ExtensionSet::GetRepeatedMessage(
536 int number, int index) const {
537 map<int, Extension>::const_iterator iter = extensions_.find(number);
538 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
539 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
540 return iter->second.repeated_message_value->Get(index);
541 }
542
MutableRepeatedMessage(int number,int index)543 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
544 map<int, Extension>::iterator iter = extensions_.find(number);
545 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
546 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
547 return iter->second.repeated_message_value->Mutable(index);
548 }
549
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)550 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
551 const MessageLite& prototype,
552 const FieldDescriptor* descriptor) {
553 Extension* extension;
554 if (MaybeNewExtension(number, descriptor, &extension)) {
555 extension->type = type;
556 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
557 extension->is_repeated = true;
558 extension->repeated_message_value =
559 new RepeatedPtrField<MessageLite>();
560 } else {
561 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
562 }
563
564 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
565 // allocate an abstract object, so we have to be tricky.
566 MessageLite* result = extension->repeated_message_value
567 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
568 if (result == NULL) {
569 result = prototype.New();
570 extension->repeated_message_value->AddAllocated(result);
571 }
572 return result;
573 }
574
575 // Defined in extension_set_heavy.cc.
576 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
577 // const Descriptor* message_type,
578 // MessageFactory* factory)
579
580 #undef GOOGLE_DCHECK_TYPE
581
RemoveLast(int number)582 void ExtensionSet::RemoveLast(int number) {
583 map<int, Extension>::iterator iter = extensions_.find(number);
584 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
585
586 Extension* extension = &iter->second;
587 GOOGLE_DCHECK(extension->is_repeated);
588
589 switch(cpp_type(extension->type)) {
590 case WireFormatLite::CPPTYPE_INT32:
591 extension->repeated_int32_value->RemoveLast();
592 break;
593 case WireFormatLite::CPPTYPE_INT64:
594 extension->repeated_int64_value->RemoveLast();
595 break;
596 case WireFormatLite::CPPTYPE_UINT32:
597 extension->repeated_uint32_value->RemoveLast();
598 break;
599 case WireFormatLite::CPPTYPE_UINT64:
600 extension->repeated_uint64_value->RemoveLast();
601 break;
602 case WireFormatLite::CPPTYPE_FLOAT:
603 extension->repeated_float_value->RemoveLast();
604 break;
605 case WireFormatLite::CPPTYPE_DOUBLE:
606 extension->repeated_double_value->RemoveLast();
607 break;
608 case WireFormatLite::CPPTYPE_BOOL:
609 extension->repeated_bool_value->RemoveLast();
610 break;
611 case WireFormatLite::CPPTYPE_ENUM:
612 extension->repeated_enum_value->RemoveLast();
613 break;
614 case WireFormatLite::CPPTYPE_STRING:
615 extension->repeated_string_value->RemoveLast();
616 break;
617 case WireFormatLite::CPPTYPE_MESSAGE:
618 extension->repeated_message_value->RemoveLast();
619 break;
620 }
621 }
622
ReleaseLast(int number)623 MessageLite* ExtensionSet::ReleaseLast(int number) {
624 map<int, Extension>::iterator iter = extensions_.find(number);
625 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
626
627 Extension* extension = &iter->second;
628 GOOGLE_DCHECK(extension->is_repeated);
629 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
630 return extension->repeated_message_value->ReleaseLast();
631 }
632
SwapElements(int number,int index1,int index2)633 void ExtensionSet::SwapElements(int number, int index1, int index2) {
634 map<int, Extension>::iterator iter = extensions_.find(number);
635 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
636
637 Extension* extension = &iter->second;
638 GOOGLE_DCHECK(extension->is_repeated);
639
640 switch(cpp_type(extension->type)) {
641 case WireFormatLite::CPPTYPE_INT32:
642 extension->repeated_int32_value->SwapElements(index1, index2);
643 break;
644 case WireFormatLite::CPPTYPE_INT64:
645 extension->repeated_int64_value->SwapElements(index1, index2);
646 break;
647 case WireFormatLite::CPPTYPE_UINT32:
648 extension->repeated_uint32_value->SwapElements(index1, index2);
649 break;
650 case WireFormatLite::CPPTYPE_UINT64:
651 extension->repeated_uint64_value->SwapElements(index1, index2);
652 break;
653 case WireFormatLite::CPPTYPE_FLOAT:
654 extension->repeated_float_value->SwapElements(index1, index2);
655 break;
656 case WireFormatLite::CPPTYPE_DOUBLE:
657 extension->repeated_double_value->SwapElements(index1, index2);
658 break;
659 case WireFormatLite::CPPTYPE_BOOL:
660 extension->repeated_bool_value->SwapElements(index1, index2);
661 break;
662 case WireFormatLite::CPPTYPE_ENUM:
663 extension->repeated_enum_value->SwapElements(index1, index2);
664 break;
665 case WireFormatLite::CPPTYPE_STRING:
666 extension->repeated_string_value->SwapElements(index1, index2);
667 break;
668 case WireFormatLite::CPPTYPE_MESSAGE:
669 extension->repeated_message_value->SwapElements(index1, index2);
670 break;
671 }
672 }
673
674 // ===================================================================
675
Clear()676 void ExtensionSet::Clear() {
677 for (map<int, Extension>::iterator iter = extensions_.begin();
678 iter != extensions_.end(); ++iter) {
679 iter->second.Clear();
680 }
681 }
682
MergeFrom(const ExtensionSet & other)683 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
684 for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
685 iter != other.extensions_.end(); ++iter) {
686 const Extension& other_extension = iter->second;
687
688 if (other_extension.is_repeated) {
689 Extension* extension;
690 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
691 &extension);
692 if (is_new) {
693 // Extension did not already exist in set.
694 extension->type = other_extension.type;
695 extension->is_packed = other_extension.is_packed;
696 extension->is_repeated = true;
697 } else {
698 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
699 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
700 GOOGLE_DCHECK(extension->is_repeated);
701 }
702
703 switch (cpp_type(other_extension.type)) {
704 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
705 case WireFormatLite::CPPTYPE_##UPPERCASE: \
706 if (is_new) { \
707 extension->repeated_##LOWERCASE##_value = \
708 new REPEATED_TYPE; \
709 } \
710 extension->repeated_##LOWERCASE##_value->MergeFrom( \
711 *other_extension.repeated_##LOWERCASE##_value); \
712 break;
713
714 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
715 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
716 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
717 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
718 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
719 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
720 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
721 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
722 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
723 #undef HANDLE_TYPE
724
725 case WireFormatLite::CPPTYPE_MESSAGE:
726 if (is_new) {
727 extension->repeated_message_value =
728 new RepeatedPtrField<MessageLite>();
729 }
730 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
731 // it would attempt to allocate new objects.
732 RepeatedPtrField<MessageLite>* other_repeated_message =
733 other_extension.repeated_message_value;
734 for (int i = 0; i < other_repeated_message->size(); i++) {
735 const MessageLite& other_message = other_repeated_message->Get(i);
736 MessageLite* target = extension->repeated_message_value
737 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
738 if (target == NULL) {
739 target = other_message.New();
740 extension->repeated_message_value->AddAllocated(target);
741 }
742 target->CheckTypeAndMergeFrom(other_message);
743 }
744 break;
745 }
746 } else {
747 if (!other_extension.is_cleared) {
748 switch (cpp_type(other_extension.type)) {
749 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
750 case WireFormatLite::CPPTYPE_##UPPERCASE: \
751 Set##CAMELCASE(iter->first, other_extension.type, \
752 other_extension.LOWERCASE##_value, \
753 other_extension.descriptor); \
754 break;
755
756 HANDLE_TYPE( INT32, int32, Int32);
757 HANDLE_TYPE( INT64, int64, Int64);
758 HANDLE_TYPE(UINT32, uint32, UInt32);
759 HANDLE_TYPE(UINT64, uint64, UInt64);
760 HANDLE_TYPE( FLOAT, float, Float);
761 HANDLE_TYPE(DOUBLE, double, Double);
762 HANDLE_TYPE( BOOL, bool, Bool);
763 HANDLE_TYPE( ENUM, enum, Enum);
764 #undef HANDLE_TYPE
765 case WireFormatLite::CPPTYPE_STRING:
766 SetString(iter->first, other_extension.type,
767 *other_extension.string_value,
768 other_extension.descriptor);
769 break;
770 case WireFormatLite::CPPTYPE_MESSAGE: {
771 Extension* extension;
772 bool is_new = MaybeNewExtension(iter->first,
773 other_extension.descriptor,
774 &extension);
775 if (is_new) {
776 extension->type = other_extension.type;
777 extension->is_packed = other_extension.is_packed;
778 extension->is_repeated = false;
779 if (other_extension.is_lazy) {
780 extension->is_lazy = true;
781 extension->lazymessage_value =
782 other_extension.lazymessage_value->New();
783 extension->lazymessage_value->MergeFrom(
784 *other_extension.lazymessage_value);
785 } else {
786 extension->is_lazy = false;
787 extension->message_value =
788 other_extension.message_value->New();
789 extension->message_value->CheckTypeAndMergeFrom(
790 *other_extension.message_value);
791 }
792 } else {
793 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
794 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
795 GOOGLE_DCHECK(!extension->is_repeated);
796 if (other_extension.is_lazy) {
797 if (extension->is_lazy) {
798 extension->lazymessage_value->MergeFrom(
799 *other_extension.lazymessage_value);
800 } else {
801 extension->message_value->CheckTypeAndMergeFrom(
802 other_extension.lazymessage_value->GetMessage(
803 *extension->message_value));
804 }
805 } else {
806 if (extension->is_lazy) {
807 extension->lazymessage_value->MutableMessage(
808 *other_extension.message_value)->CheckTypeAndMergeFrom(
809 *other_extension.message_value);
810 } else {
811 extension->message_value->CheckTypeAndMergeFrom(
812 *other_extension.message_value);
813 }
814 }
815 }
816 extension->is_cleared = false;
817 break;
818 }
819 }
820 }
821 }
822 }
823 }
824
Swap(ExtensionSet * x)825 void ExtensionSet::Swap(ExtensionSet* x) {
826 extensions_.swap(x->extensions_);
827 }
828
IsInitialized() const829 bool ExtensionSet::IsInitialized() const {
830 // Extensions are never required. However, we need to check that all
831 // embedded messages are initialized.
832 for (map<int, Extension>::const_iterator iter = extensions_.begin();
833 iter != extensions_.end(); ++iter) {
834 const Extension& extension = iter->second;
835 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
836 if (extension.is_repeated) {
837 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
838 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
839 return false;
840 }
841 }
842 } else {
843 if (!extension.is_cleared) {
844 if (extension.is_lazy) {
845 if (!extension.lazymessage_value->IsInitialized()) return false;
846 } else {
847 if (!extension.message_value->IsInitialized()) return false;
848 }
849 }
850 }
851 }
852 }
853
854 return true;
855 }
856
FindExtensionInfoFromTag(uint32 tag,ExtensionFinder * extension_finder,int * field_number,ExtensionInfo * extension)857 bool ExtensionSet::FindExtensionInfoFromTag(
858 uint32 tag, ExtensionFinder* extension_finder,
859 int* field_number, ExtensionInfo* extension) {
860 *field_number = WireFormatLite::GetTagFieldNumber(tag);
861 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
862
863 bool is_unknown;
864 if (!extension_finder->Find(*field_number, extension)) {
865 is_unknown = true;
866 } else if (extension->is_packed) {
867 is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
868 } else {
869 WireFormatLite::WireType expected_wire_type =
870 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
871 is_unknown = (wire_type != expected_wire_type);
872 }
873 return !is_unknown;
874 }
875
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)876 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
877 ExtensionFinder* extension_finder,
878 FieldSkipper* field_skipper) {
879 int number;
880 ExtensionInfo extension;
881 if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) {
882 return field_skipper->SkipField(input, tag);
883 } else {
884 return ParseFieldWithExtensionInfo(number, extension, input, field_skipper);
885 }
886 }
887
ParseFieldWithExtensionInfo(int number,const ExtensionInfo & extension,io::CodedInputStream * input,FieldSkipper * field_skipper)888 bool ExtensionSet::ParseFieldWithExtensionInfo(
889 int number, const ExtensionInfo& extension,
890 io::CodedInputStream* input,
891 FieldSkipper* field_skipper) {
892 if (extension.is_packed) {
893 uint32 size;
894 if (!input->ReadVarint32(&size)) return false;
895 io::CodedInputStream::Limit limit = input->PushLimit(size);
896
897 switch (extension.type) {
898 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
899 case WireFormatLite::TYPE_##UPPERCASE: \
900 while (input->BytesUntilLimit() > 0) { \
901 CPP_LOWERCASE value; \
902 if (!WireFormatLite::ReadPrimitive< \
903 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
904 input, &value)) return false; \
905 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
906 true, value, extension.descriptor); \
907 } \
908 break
909
910 HANDLE_TYPE( INT32, Int32, int32);
911 HANDLE_TYPE( INT64, Int64, int64);
912 HANDLE_TYPE( UINT32, UInt32, uint32);
913 HANDLE_TYPE( UINT64, UInt64, uint64);
914 HANDLE_TYPE( SINT32, Int32, int32);
915 HANDLE_TYPE( SINT64, Int64, int64);
916 HANDLE_TYPE( FIXED32, UInt32, uint32);
917 HANDLE_TYPE( FIXED64, UInt64, uint64);
918 HANDLE_TYPE(SFIXED32, Int32, int32);
919 HANDLE_TYPE(SFIXED64, Int64, int64);
920 HANDLE_TYPE( FLOAT, Float, float);
921 HANDLE_TYPE( DOUBLE, Double, double);
922 HANDLE_TYPE( BOOL, Bool, bool);
923 #undef HANDLE_TYPE
924
925 case WireFormatLite::TYPE_ENUM:
926 while (input->BytesUntilLimit() > 0) {
927 int value;
928 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
929 input, &value)) return false;
930 if (extension.enum_validity_check.func(
931 extension.enum_validity_check.arg, value)) {
932 AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
933 extension.descriptor);
934 }
935 }
936 break;
937
938 case WireFormatLite::TYPE_STRING:
939 case WireFormatLite::TYPE_BYTES:
940 case WireFormatLite::TYPE_GROUP:
941 case WireFormatLite::TYPE_MESSAGE:
942 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
943 break;
944 }
945
946 input->PopLimit(limit);
947 } else {
948 switch (extension.type) {
949 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
950 case WireFormatLite::TYPE_##UPPERCASE: { \
951 CPP_LOWERCASE value; \
952 if (!WireFormatLite::ReadPrimitive< \
953 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
954 input, &value)) return false; \
955 if (extension.is_repeated) { \
956 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
957 false, value, extension.descriptor); \
958 } else { \
959 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
960 extension.descriptor); \
961 } \
962 } break
963
964 HANDLE_TYPE( INT32, Int32, int32);
965 HANDLE_TYPE( INT64, Int64, int64);
966 HANDLE_TYPE( UINT32, UInt32, uint32);
967 HANDLE_TYPE( UINT64, UInt64, uint64);
968 HANDLE_TYPE( SINT32, Int32, int32);
969 HANDLE_TYPE( SINT64, Int64, int64);
970 HANDLE_TYPE( FIXED32, UInt32, uint32);
971 HANDLE_TYPE( FIXED64, UInt64, uint64);
972 HANDLE_TYPE(SFIXED32, Int32, int32);
973 HANDLE_TYPE(SFIXED64, Int64, int64);
974 HANDLE_TYPE( FLOAT, Float, float);
975 HANDLE_TYPE( DOUBLE, Double, double);
976 HANDLE_TYPE( BOOL, Bool, bool);
977 #undef HANDLE_TYPE
978
979 case WireFormatLite::TYPE_ENUM: {
980 int value;
981 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
982 input, &value)) return false;
983
984 if (!extension.enum_validity_check.func(
985 extension.enum_validity_check.arg, value)) {
986 // Invalid value. Treat as unknown.
987 field_skipper->SkipUnknownEnum(number, value);
988 } else if (extension.is_repeated) {
989 AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
990 extension.descriptor);
991 } else {
992 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
993 extension.descriptor);
994 }
995 break;
996 }
997
998 case WireFormatLite::TYPE_STRING: {
999 string* value = extension.is_repeated ?
1000 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1001 MutableString(number, WireFormatLite::TYPE_STRING,
1002 extension.descriptor);
1003 if (!WireFormatLite::ReadString(input, value)) return false;
1004 break;
1005 }
1006
1007 case WireFormatLite::TYPE_BYTES: {
1008 string* value = extension.is_repeated ?
1009 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1010 MutableString(number, WireFormatLite::TYPE_BYTES,
1011 extension.descriptor);
1012 if (!WireFormatLite::ReadBytes(input, value)) return false;
1013 break;
1014 }
1015
1016 case WireFormatLite::TYPE_GROUP: {
1017 MessageLite* value = extension.is_repeated ?
1018 AddMessage(number, WireFormatLite::TYPE_GROUP,
1019 *extension.message_prototype, extension.descriptor) :
1020 MutableMessage(number, WireFormatLite::TYPE_GROUP,
1021 *extension.message_prototype, extension.descriptor);
1022 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1023 break;
1024 }
1025
1026 case WireFormatLite::TYPE_MESSAGE: {
1027 MessageLite* value = extension.is_repeated ?
1028 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1029 *extension.message_prototype, extension.descriptor) :
1030 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1031 *extension.message_prototype, extension.descriptor);
1032 if (!WireFormatLite::ReadMessage(input, value)) return false;
1033 break;
1034 }
1035 }
1036 }
1037
1038 return true;
1039 }
1040
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type,UnknownFieldSet * unknown_fields)1041 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1042 const MessageLite* containing_type,
1043 UnknownFieldSet* unknown_fields) {
1044 FieldSkipper skipper(unknown_fields);
1045 GeneratedExtensionFinder finder(containing_type);
1046 return ParseField(tag, input, &finder, &skipper);
1047 }
1048
1049 // Defined in extension_set_heavy.cc.
1050 // bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
1051 // const Message* containing_type,
1052 // UnknownFieldSet* unknown_fields)
1053
1054 // Defined in extension_set_heavy.cc.
1055 // bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
1056 // const Message* containing_type,
1057 // UnknownFieldSet* unknown_fields);
1058
SerializeWithCachedSizes(int start_field_number,int end_field_number,io::CodedOutputStream * output) const1059 void ExtensionSet::SerializeWithCachedSizes(
1060 int start_field_number, int end_field_number,
1061 io::CodedOutputStream* output) const {
1062 map<int, Extension>::const_iterator iter;
1063 for (iter = extensions_.lower_bound(start_field_number);
1064 iter != extensions_.end() && iter->first < end_field_number;
1065 ++iter) {
1066 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1067 }
1068 }
1069
ByteSize() const1070 int ExtensionSet::ByteSize() const {
1071 int total_size = 0;
1072
1073 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1074 iter != extensions_.end(); ++iter) {
1075 total_size += iter->second.ByteSize(iter->first);
1076 }
1077
1078 return total_size;
1079 }
1080
1081 // Defined in extension_set_heavy.cc.
1082 // int ExtensionSet::SpaceUsedExcludingSelf() const
1083
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1084 bool ExtensionSet::MaybeNewExtension(int number,
1085 const FieldDescriptor* descriptor,
1086 Extension** result) {
1087 pair<map<int, Extension>::iterator, bool> insert_result =
1088 extensions_.insert(make_pair(number, Extension()));
1089 *result = &insert_result.first->second;
1090 (*result)->descriptor = descriptor;
1091 return insert_result.second;
1092 }
1093
1094 // ===================================================================
1095 // Methods of ExtensionSet::Extension
1096
Clear()1097 void ExtensionSet::Extension::Clear() {
1098 if (is_repeated) {
1099 switch (cpp_type(type)) {
1100 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1101 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1102 repeated_##LOWERCASE##_value->Clear(); \
1103 break
1104
1105 HANDLE_TYPE( INT32, int32);
1106 HANDLE_TYPE( INT64, int64);
1107 HANDLE_TYPE( UINT32, uint32);
1108 HANDLE_TYPE( UINT64, uint64);
1109 HANDLE_TYPE( FLOAT, float);
1110 HANDLE_TYPE( DOUBLE, double);
1111 HANDLE_TYPE( BOOL, bool);
1112 HANDLE_TYPE( ENUM, enum);
1113 HANDLE_TYPE( STRING, string);
1114 HANDLE_TYPE(MESSAGE, message);
1115 #undef HANDLE_TYPE
1116 }
1117 } else {
1118 if (!is_cleared) {
1119 switch (cpp_type(type)) {
1120 case WireFormatLite::CPPTYPE_STRING:
1121 string_value->clear();
1122 break;
1123 case WireFormatLite::CPPTYPE_MESSAGE:
1124 if (is_lazy) {
1125 lazymessage_value->Clear();
1126 } else {
1127 message_value->Clear();
1128 }
1129 break;
1130 default:
1131 // No need to do anything. Get*() will return the default value
1132 // as long as is_cleared is true and Set*() will overwrite the
1133 // previous value.
1134 break;
1135 }
1136
1137 is_cleared = true;
1138 }
1139 }
1140 }
1141
SerializeFieldWithCachedSizes(int number,io::CodedOutputStream * output) const1142 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1143 int number,
1144 io::CodedOutputStream* output) const {
1145 if (is_repeated) {
1146 if (is_packed) {
1147 if (cached_size == 0) return;
1148
1149 WireFormatLite::WriteTag(number,
1150 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1151 output->WriteVarint32(cached_size);
1152
1153 switch (real_type(type)) {
1154 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1155 case WireFormatLite::TYPE_##UPPERCASE: \
1156 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1157 WireFormatLite::Write##CAMELCASE##NoTag( \
1158 repeated_##LOWERCASE##_value->Get(i), output); \
1159 } \
1160 break
1161
1162 HANDLE_TYPE( INT32, Int32, int32);
1163 HANDLE_TYPE( INT64, Int64, int64);
1164 HANDLE_TYPE( UINT32, UInt32, uint32);
1165 HANDLE_TYPE( UINT64, UInt64, uint64);
1166 HANDLE_TYPE( SINT32, SInt32, int32);
1167 HANDLE_TYPE( SINT64, SInt64, int64);
1168 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1169 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1170 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1171 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1172 HANDLE_TYPE( FLOAT, Float, float);
1173 HANDLE_TYPE( DOUBLE, Double, double);
1174 HANDLE_TYPE( BOOL, Bool, bool);
1175 HANDLE_TYPE( ENUM, Enum, enum);
1176 #undef HANDLE_TYPE
1177
1178 case WireFormatLite::TYPE_STRING:
1179 case WireFormatLite::TYPE_BYTES:
1180 case WireFormatLite::TYPE_GROUP:
1181 case WireFormatLite::TYPE_MESSAGE:
1182 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1183 break;
1184 }
1185 } else {
1186 switch (real_type(type)) {
1187 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1188 case WireFormatLite::TYPE_##UPPERCASE: \
1189 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1190 WireFormatLite::Write##CAMELCASE(number, \
1191 repeated_##LOWERCASE##_value->Get(i), output); \
1192 } \
1193 break
1194
1195 HANDLE_TYPE( INT32, Int32, int32);
1196 HANDLE_TYPE( INT64, Int64, int64);
1197 HANDLE_TYPE( UINT32, UInt32, uint32);
1198 HANDLE_TYPE( UINT64, UInt64, uint64);
1199 HANDLE_TYPE( SINT32, SInt32, int32);
1200 HANDLE_TYPE( SINT64, SInt64, int64);
1201 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1202 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1203 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1204 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1205 HANDLE_TYPE( FLOAT, Float, float);
1206 HANDLE_TYPE( DOUBLE, Double, double);
1207 HANDLE_TYPE( BOOL, Bool, bool);
1208 HANDLE_TYPE( STRING, String, string);
1209 HANDLE_TYPE( BYTES, Bytes, string);
1210 HANDLE_TYPE( ENUM, Enum, enum);
1211 HANDLE_TYPE( GROUP, Group, message);
1212 HANDLE_TYPE( MESSAGE, Message, message);
1213 #undef HANDLE_TYPE
1214 }
1215 }
1216 } else if (!is_cleared) {
1217 switch (real_type(type)) {
1218 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
1219 case WireFormatLite::TYPE_##UPPERCASE: \
1220 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1221 break
1222
1223 HANDLE_TYPE( INT32, Int32, int32_value);
1224 HANDLE_TYPE( INT64, Int64, int64_value);
1225 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1226 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1227 HANDLE_TYPE( SINT32, SInt32, int32_value);
1228 HANDLE_TYPE( SINT64, SInt64, int64_value);
1229 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1230 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1231 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1232 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1233 HANDLE_TYPE( FLOAT, Float, float_value);
1234 HANDLE_TYPE( DOUBLE, Double, double_value);
1235 HANDLE_TYPE( BOOL, Bool, bool_value);
1236 HANDLE_TYPE( STRING, String, *string_value);
1237 HANDLE_TYPE( BYTES, Bytes, *string_value);
1238 HANDLE_TYPE( ENUM, Enum, enum_value);
1239 HANDLE_TYPE( GROUP, Group, *message_value);
1240 #undef HANDLE_TYPE
1241 case WireFormatLite::TYPE_MESSAGE:
1242 if (is_lazy) {
1243 lazymessage_value->WriteMessage(number, output);
1244 } else {
1245 WireFormatLite::WriteMessage(number, *message_value, output);
1246 }
1247 break;
1248 }
1249 }
1250 }
1251
ByteSize(int number) const1252 int ExtensionSet::Extension::ByteSize(int number) const {
1253 int result = 0;
1254
1255 if (is_repeated) {
1256 if (is_packed) {
1257 switch (real_type(type)) {
1258 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1259 case WireFormatLite::TYPE_##UPPERCASE: \
1260 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1261 result += WireFormatLite::CAMELCASE##Size( \
1262 repeated_##LOWERCASE##_value->Get(i)); \
1263 } \
1264 break
1265
1266 HANDLE_TYPE( INT32, Int32, int32);
1267 HANDLE_TYPE( INT64, Int64, int64);
1268 HANDLE_TYPE( UINT32, UInt32, uint32);
1269 HANDLE_TYPE( UINT64, UInt64, uint64);
1270 HANDLE_TYPE( SINT32, SInt32, int32);
1271 HANDLE_TYPE( SINT64, SInt64, int64);
1272 HANDLE_TYPE( ENUM, Enum, enum);
1273 #undef HANDLE_TYPE
1274
1275 // Stuff with fixed size.
1276 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1277 case WireFormatLite::TYPE_##UPPERCASE: \
1278 result += WireFormatLite::k##CAMELCASE##Size * \
1279 repeated_##LOWERCASE##_value->size(); \
1280 break
1281 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1282 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1283 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1284 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1285 HANDLE_TYPE( FLOAT, Float, float);
1286 HANDLE_TYPE( DOUBLE, Double, double);
1287 HANDLE_TYPE( BOOL, Bool, bool);
1288 #undef HANDLE_TYPE
1289
1290 case WireFormatLite::TYPE_STRING:
1291 case WireFormatLite::TYPE_BYTES:
1292 case WireFormatLite::TYPE_GROUP:
1293 case WireFormatLite::TYPE_MESSAGE:
1294 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1295 break;
1296 }
1297
1298 cached_size = result;
1299 if (result > 0) {
1300 result += io::CodedOutputStream::VarintSize32(result);
1301 result += io::CodedOutputStream::VarintSize32(
1302 WireFormatLite::MakeTag(number,
1303 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1304 }
1305 } else {
1306 int tag_size = WireFormatLite::TagSize(number, real_type(type));
1307
1308 switch (real_type(type)) {
1309 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1310 case WireFormatLite::TYPE_##UPPERCASE: \
1311 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1312 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1313 result += WireFormatLite::CAMELCASE##Size( \
1314 repeated_##LOWERCASE##_value->Get(i)); \
1315 } \
1316 break
1317
1318 HANDLE_TYPE( INT32, Int32, int32);
1319 HANDLE_TYPE( INT64, Int64, int64);
1320 HANDLE_TYPE( UINT32, UInt32, uint32);
1321 HANDLE_TYPE( UINT64, UInt64, uint64);
1322 HANDLE_TYPE( SINT32, SInt32, int32);
1323 HANDLE_TYPE( SINT64, SInt64, int64);
1324 HANDLE_TYPE( STRING, String, string);
1325 HANDLE_TYPE( BYTES, Bytes, string);
1326 HANDLE_TYPE( ENUM, Enum, enum);
1327 HANDLE_TYPE( GROUP, Group, message);
1328 HANDLE_TYPE( MESSAGE, Message, message);
1329 #undef HANDLE_TYPE
1330
1331 // Stuff with fixed size.
1332 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1333 case WireFormatLite::TYPE_##UPPERCASE: \
1334 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
1335 repeated_##LOWERCASE##_value->size(); \
1336 break
1337 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1338 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1339 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1340 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1341 HANDLE_TYPE( FLOAT, Float, float);
1342 HANDLE_TYPE( DOUBLE, Double, double);
1343 HANDLE_TYPE( BOOL, Bool, bool);
1344 #undef HANDLE_TYPE
1345 }
1346 }
1347 } else if (!is_cleared) {
1348 result += WireFormatLite::TagSize(number, real_type(type));
1349 switch (real_type(type)) {
1350 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1351 case WireFormatLite::TYPE_##UPPERCASE: \
1352 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1353 break
1354
1355 HANDLE_TYPE( INT32, Int32, int32_value);
1356 HANDLE_TYPE( INT64, Int64, int64_value);
1357 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1358 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1359 HANDLE_TYPE( SINT32, SInt32, int32_value);
1360 HANDLE_TYPE( SINT64, SInt64, int64_value);
1361 HANDLE_TYPE( STRING, String, *string_value);
1362 HANDLE_TYPE( BYTES, Bytes, *string_value);
1363 HANDLE_TYPE( ENUM, Enum, enum_value);
1364 HANDLE_TYPE( GROUP, Group, *message_value);
1365 #undef HANDLE_TYPE
1366 case WireFormatLite::TYPE_MESSAGE: {
1367 if (is_lazy) {
1368 int size = lazymessage_value->ByteSize();
1369 result += io::CodedOutputStream::VarintSize32(size) + size;
1370 } else {
1371 result += WireFormatLite::MessageSize(*message_value);
1372 }
1373 break;
1374 }
1375
1376 // Stuff with fixed size.
1377 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1378 case WireFormatLite::TYPE_##UPPERCASE: \
1379 result += WireFormatLite::k##CAMELCASE##Size; \
1380 break
1381 HANDLE_TYPE( FIXED32, Fixed32);
1382 HANDLE_TYPE( FIXED64, Fixed64);
1383 HANDLE_TYPE(SFIXED32, SFixed32);
1384 HANDLE_TYPE(SFIXED64, SFixed64);
1385 HANDLE_TYPE( FLOAT, Float);
1386 HANDLE_TYPE( DOUBLE, Double);
1387 HANDLE_TYPE( BOOL, Bool);
1388 #undef HANDLE_TYPE
1389 }
1390 }
1391
1392 return result;
1393 }
1394
GetSize() const1395 int ExtensionSet::Extension::GetSize() const {
1396 GOOGLE_DCHECK(is_repeated);
1397 switch (cpp_type(type)) {
1398 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1399 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1400 return repeated_##LOWERCASE##_value->size()
1401
1402 HANDLE_TYPE( INT32, int32);
1403 HANDLE_TYPE( INT64, int64);
1404 HANDLE_TYPE( UINT32, uint32);
1405 HANDLE_TYPE( UINT64, uint64);
1406 HANDLE_TYPE( FLOAT, float);
1407 HANDLE_TYPE( DOUBLE, double);
1408 HANDLE_TYPE( BOOL, bool);
1409 HANDLE_TYPE( ENUM, enum);
1410 HANDLE_TYPE( STRING, string);
1411 HANDLE_TYPE(MESSAGE, message);
1412 #undef HANDLE_TYPE
1413 }
1414
1415 GOOGLE_LOG(FATAL) << "Can't get here.";
1416 return 0;
1417 }
1418
Free()1419 void ExtensionSet::Extension::Free() {
1420 if (is_repeated) {
1421 switch (cpp_type(type)) {
1422 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1423 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1424 delete repeated_##LOWERCASE##_value; \
1425 break
1426
1427 HANDLE_TYPE( INT32, int32);
1428 HANDLE_TYPE( INT64, int64);
1429 HANDLE_TYPE( UINT32, uint32);
1430 HANDLE_TYPE( UINT64, uint64);
1431 HANDLE_TYPE( FLOAT, float);
1432 HANDLE_TYPE( DOUBLE, double);
1433 HANDLE_TYPE( BOOL, bool);
1434 HANDLE_TYPE( ENUM, enum);
1435 HANDLE_TYPE( STRING, string);
1436 HANDLE_TYPE(MESSAGE, message);
1437 #undef HANDLE_TYPE
1438 }
1439 } else {
1440 switch (cpp_type(type)) {
1441 case WireFormatLite::CPPTYPE_STRING:
1442 delete string_value;
1443 break;
1444 case WireFormatLite::CPPTYPE_MESSAGE:
1445 if (is_lazy) {
1446 delete lazymessage_value;
1447 } else {
1448 delete message_value;
1449 }
1450 break;
1451 default:
1452 break;
1453 }
1454 }
1455 }
1456
1457 // Defined in extension_set_heavy.cc.
1458 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1459
1460 } // namespace internal
1461 } // namespace protobuf
1462 } // namespace google
1463