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 internal::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
ExtensionSize(int number) const183 int ExtensionSet::ExtensionSize(int number) const {
184 map<int, Extension>::const_iterator iter = extensions_.find(number);
185 if (iter == extensions_.end()) return false;
186 return iter->second.GetSize();
187 }
188
ClearExtension(int number)189 void ExtensionSet::ClearExtension(int number) {
190 map<int, Extension>::iterator iter = extensions_.find(number);
191 if (iter == extensions_.end()) return;
192 iter->second.Clear();
193 }
194
195 // ===================================================================
196 // Field accessors
197
198 namespace {
199
200 enum Cardinality {
201 REPEATED,
202 OPTIONAL
203 };
204
205 } // namespace
206
207 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
208 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
209 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
210
211 // -------------------------------------------------------------------
212 // Primitives
213
214 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
215 \
216 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
217 LOWERCASE default_value) const { \
218 map<int, Extension>::const_iterator iter = extensions_.find(number); \
219 if (iter == extensions_.end() || iter->second.is_cleared) { \
220 return default_value; \
221 } else { \
222 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
223 return iter->second.LOWERCASE##_value; \
224 } \
225 } \
226 \
227 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
228 LOWERCASE value, \
229 const FieldDescriptor* descriptor) { \
230 Extension* extension; \
231 if (MaybeNewExtension(number, descriptor, &extension)) { \
232 extension->type = type; \
233 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
234 extension->is_repeated = false; \
235 } else { \
236 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
237 } \
238 extension->is_cleared = false; \
239 extension->LOWERCASE##_value = value; \
240 } \
241 \
242 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
243 map<int, Extension>::const_iterator iter = extensions_.find(number); \
244 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
245 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
246 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
247 } \
248 \
249 void ExtensionSet::SetRepeated##CAMELCASE( \
250 int number, int index, LOWERCASE value) { \
251 map<int, Extension>::iterator iter = extensions_.find(number); \
252 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
253 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
254 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
255 } \
256 \
257 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
258 bool packed, LOWERCASE value, \
259 const FieldDescriptor* descriptor) { \
260 Extension* extension; \
261 if (MaybeNewExtension(number, descriptor, &extension)) { \
262 extension->type = type; \
263 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
264 extension->is_repeated = true; \
265 extension->is_packed = packed; \
266 extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
267 } else { \
268 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
269 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
270 } \
271 extension->repeated_##LOWERCASE##_value->Add(value); \
272 }
273
PRIMITIVE_ACCESSORS(INT32,int32,Int32)274 PRIMITIVE_ACCESSORS( INT32, int32, Int32)
275 PRIMITIVE_ACCESSORS( INT64, int64, Int64)
276 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
277 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
278 PRIMITIVE_ACCESSORS( FLOAT, float, Float)
279 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
280 PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
281
282 #undef PRIMITIVE_ACCESSORS
283
284 // -------------------------------------------------------------------
285 // Enums
286
287 int ExtensionSet::GetEnum(int number, int default_value) const {
288 map<int, Extension>::const_iterator iter = extensions_.find(number);
289 if (iter == extensions_.end() || iter->second.is_cleared) {
290 // Not present. Return the default value.
291 return default_value;
292 } else {
293 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
294 return iter->second.enum_value;
295 }
296 }
297
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)298 void ExtensionSet::SetEnum(int number, FieldType type, int value,
299 const FieldDescriptor* descriptor) {
300 Extension* extension;
301 if (MaybeNewExtension(number, descriptor, &extension)) {
302 extension->type = type;
303 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
304 extension->is_repeated = false;
305 } else {
306 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
307 }
308 extension->is_cleared = false;
309 extension->enum_value = value;
310 }
311
GetRepeatedEnum(int number,int index) const312 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
313 map<int, Extension>::const_iterator iter = extensions_.find(number);
314 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
315 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
316 return iter->second.repeated_enum_value->Get(index);
317 }
318
SetRepeatedEnum(int number,int index,int value)319 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
320 map<int, Extension>::iterator iter = extensions_.find(number);
321 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
322 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
323 iter->second.repeated_enum_value->Set(index, value);
324 }
325
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)326 void ExtensionSet::AddEnum(int number, FieldType type,
327 bool packed, int value,
328 const FieldDescriptor* descriptor) {
329 Extension* extension;
330 if (MaybeNewExtension(number, descriptor, &extension)) {
331 extension->type = type;
332 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
333 extension->is_repeated = true;
334 extension->is_packed = packed;
335 extension->repeated_enum_value = new RepeatedField<int>();
336 } else {
337 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
338 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
339 }
340 extension->repeated_enum_value->Add(value);
341 }
342
343 // -------------------------------------------------------------------
344 // Strings
345
GetString(int number,const string & default_value) const346 const string& ExtensionSet::GetString(int number,
347 const string& default_value) const {
348 map<int, Extension>::const_iterator iter = extensions_.find(number);
349 if (iter == extensions_.end() || iter->second.is_cleared) {
350 // Not present. Return the default value.
351 return default_value;
352 } else {
353 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
354 return *iter->second.string_value;
355 }
356 }
357
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)358 string* ExtensionSet::MutableString(int number, FieldType type,
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_STRING);
364 extension->is_repeated = false;
365 extension->string_value = new string;
366 } else {
367 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
368 }
369 extension->is_cleared = false;
370 return extension->string_value;
371 }
372
GetRepeatedString(int number,int index) const373 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
374 map<int, Extension>::const_iterator iter = extensions_.find(number);
375 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
376 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
377 return iter->second.repeated_string_value->Get(index);
378 }
379
MutableRepeatedString(int number,int index)380 string* ExtensionSet::MutableRepeatedString(int number, int index) {
381 map<int, Extension>::iterator iter = extensions_.find(number);
382 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
383 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
384 return iter->second.repeated_string_value->Mutable(index);
385 }
386
AddString(int number,FieldType type,const FieldDescriptor * descriptor)387 string* ExtensionSet::AddString(int number, FieldType type,
388 const FieldDescriptor* descriptor) {
389 Extension* extension;
390 if (MaybeNewExtension(number, descriptor, &extension)) {
391 extension->type = type;
392 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
393 extension->is_repeated = true;
394 extension->is_packed = false;
395 extension->repeated_string_value = new RepeatedPtrField<string>();
396 } else {
397 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
398 }
399 return extension->repeated_string_value->Add();
400 }
401
402 // -------------------------------------------------------------------
403 // Messages
404
GetMessage(int number,const MessageLite & default_value) const405 const MessageLite& ExtensionSet::GetMessage(
406 int number, const MessageLite& default_value) const {
407 map<int, Extension>::const_iterator iter = extensions_.find(number);
408 if (iter == extensions_.end()) {
409 // Not present. Return the default value.
410 return default_value;
411 } else {
412 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
413 return *iter->second.message_value;
414 }
415 }
416
417 // Defined in extension_set_heavy.cc.
418 // const MessageLite& ExtensionSet::GetMessage(int number,
419 // const Descriptor* message_type,
420 // MessageFactory* factory) const
421
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)422 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
423 const MessageLite& prototype,
424 const FieldDescriptor* descriptor) {
425 Extension* extension;
426 if (MaybeNewExtension(number, descriptor, &extension)) {
427 extension->type = type;
428 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
429 extension->is_repeated = false;
430 extension->message_value = prototype.New();
431 } else {
432 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
433 }
434 extension->is_cleared = false;
435 return extension->message_value;
436 }
437
438 // Defined in extension_set_heavy.cc.
439 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
440 // const Descriptor* message_type,
441 // MessageFactory* factory)
442
GetRepeatedMessage(int number,int index) const443 const MessageLite& ExtensionSet::GetRepeatedMessage(
444 int number, int index) const {
445 map<int, Extension>::const_iterator iter = extensions_.find(number);
446 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
447 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
448 return iter->second.repeated_message_value->Get(index);
449 }
450
MutableRepeatedMessage(int number,int index)451 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
452 map<int, Extension>::iterator iter = extensions_.find(number);
453 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
454 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
455 return iter->second.repeated_message_value->Mutable(index);
456 }
457
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)458 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
459 const MessageLite& prototype,
460 const FieldDescriptor* descriptor) {
461 Extension* extension;
462 if (MaybeNewExtension(number, descriptor, &extension)) {
463 extension->type = type;
464 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
465 extension->is_repeated = true;
466 extension->repeated_message_value =
467 new RepeatedPtrField<MessageLite>();
468 } else {
469 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
470 }
471
472 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
473 // allocate an abstract object, so we have to be tricky.
474 MessageLite* result = extension->repeated_message_value
475 ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
476 if (result == NULL) {
477 result = prototype.New();
478 extension->repeated_message_value->AddAllocated(result);
479 }
480 return result;
481 }
482
483 // Defined in extension_set_heavy.cc.
484 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
485 // const Descriptor* message_type,
486 // MessageFactory* factory)
487
488 #undef GOOGLE_DCHECK_TYPE
489
RemoveLast(int number)490 void ExtensionSet::RemoveLast(int number) {
491 map<int, Extension>::iterator iter = extensions_.find(number);
492 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
493
494 Extension* extension = &iter->second;
495 GOOGLE_DCHECK(extension->is_repeated);
496
497 switch(cpp_type(extension->type)) {
498 case WireFormatLite::CPPTYPE_INT32:
499 extension->repeated_int32_value->RemoveLast();
500 break;
501 case WireFormatLite::CPPTYPE_INT64:
502 extension->repeated_int64_value->RemoveLast();
503 break;
504 case WireFormatLite::CPPTYPE_UINT32:
505 extension->repeated_uint32_value->RemoveLast();
506 break;
507 case WireFormatLite::CPPTYPE_UINT64:
508 extension->repeated_uint64_value->RemoveLast();
509 break;
510 case WireFormatLite::CPPTYPE_FLOAT:
511 extension->repeated_float_value->RemoveLast();
512 break;
513 case WireFormatLite::CPPTYPE_DOUBLE:
514 extension->repeated_double_value->RemoveLast();
515 break;
516 case WireFormatLite::CPPTYPE_BOOL:
517 extension->repeated_bool_value->RemoveLast();
518 break;
519 case WireFormatLite::CPPTYPE_ENUM:
520 extension->repeated_enum_value->RemoveLast();
521 break;
522 case WireFormatLite::CPPTYPE_STRING:
523 extension->repeated_string_value->RemoveLast();
524 break;
525 case WireFormatLite::CPPTYPE_MESSAGE:
526 extension->repeated_message_value->RemoveLast();
527 break;
528 }
529 }
530
SwapElements(int number,int index1,int index2)531 void ExtensionSet::SwapElements(int number, int index1, int index2) {
532 map<int, Extension>::iterator iter = extensions_.find(number);
533 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
534
535 Extension* extension = &iter->second;
536 GOOGLE_DCHECK(extension->is_repeated);
537
538 switch(cpp_type(extension->type)) {
539 case WireFormatLite::CPPTYPE_INT32:
540 extension->repeated_int32_value->SwapElements(index1, index2);
541 break;
542 case WireFormatLite::CPPTYPE_INT64:
543 extension->repeated_int64_value->SwapElements(index1, index2);
544 break;
545 case WireFormatLite::CPPTYPE_UINT32:
546 extension->repeated_uint32_value->SwapElements(index1, index2);
547 break;
548 case WireFormatLite::CPPTYPE_UINT64:
549 extension->repeated_uint64_value->SwapElements(index1, index2);
550 break;
551 case WireFormatLite::CPPTYPE_FLOAT:
552 extension->repeated_float_value->SwapElements(index1, index2);
553 break;
554 case WireFormatLite::CPPTYPE_DOUBLE:
555 extension->repeated_double_value->SwapElements(index1, index2);
556 break;
557 case WireFormatLite::CPPTYPE_BOOL:
558 extension->repeated_bool_value->SwapElements(index1, index2);
559 break;
560 case WireFormatLite::CPPTYPE_ENUM:
561 extension->repeated_enum_value->SwapElements(index1, index2);
562 break;
563 case WireFormatLite::CPPTYPE_STRING:
564 extension->repeated_string_value->SwapElements(index1, index2);
565 break;
566 case WireFormatLite::CPPTYPE_MESSAGE:
567 extension->repeated_message_value->SwapElements(index1, index2);
568 break;
569 }
570 }
571
572 // ===================================================================
573
Clear()574 void ExtensionSet::Clear() {
575 for (map<int, Extension>::iterator iter = extensions_.begin();
576 iter != extensions_.end(); ++iter) {
577 iter->second.Clear();
578 }
579 }
580
MergeFrom(const ExtensionSet & other)581 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
582 for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
583 iter != other.extensions_.end(); ++iter) {
584 const Extension& other_extension = iter->second;
585
586 if (other_extension.is_repeated) {
587 Extension* extension;
588 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
589 &extension);
590 if (is_new) {
591 // Extension did not already exist in set.
592 extension->type = other_extension.type;
593 extension->is_repeated = true;
594 } else {
595 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
596 GOOGLE_DCHECK(extension->is_repeated);
597 }
598
599 switch (cpp_type(other_extension.type)) {
600 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
601 case WireFormatLite::CPPTYPE_##UPPERCASE: \
602 if (is_new) { \
603 extension->repeated_##LOWERCASE##_value = \
604 new REPEATED_TYPE; \
605 } \
606 extension->repeated_##LOWERCASE##_value->MergeFrom( \
607 *other_extension.repeated_##LOWERCASE##_value); \
608 break;
609
610 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
611 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
612 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
613 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
614 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
615 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
616 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
617 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
618 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
619 #undef HANDLE_TYPE
620
621 case WireFormatLite::CPPTYPE_MESSAGE:
622 if (is_new) {
623 extension->repeated_message_value =
624 new RepeatedPtrField<MessageLite>();
625 }
626 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
627 // it would attempt to allocate new objects.
628 RepeatedPtrField<MessageLite>* other_repeated_message =
629 other_extension.repeated_message_value;
630 for (int i = 0; i < other_repeated_message->size(); i++) {
631 const MessageLite& other_message = other_repeated_message->Get(i);
632 MessageLite* target = extension->repeated_message_value
633 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
634 if (target == NULL) {
635 target = other_message.New();
636 extension->repeated_message_value->AddAllocated(target);
637 }
638 target->CheckTypeAndMergeFrom(other_message);
639 }
640 break;
641 }
642 } else {
643 if (!other_extension.is_cleared) {
644 switch (cpp_type(other_extension.type)) {
645 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
646 case WireFormatLite::CPPTYPE_##UPPERCASE: \
647 Set##CAMELCASE(iter->first, other_extension.type, \
648 other_extension.LOWERCASE##_value, \
649 other_extension.descriptor); \
650 break;
651
652 HANDLE_TYPE( INT32, int32, Int32);
653 HANDLE_TYPE( INT64, int64, Int64);
654 HANDLE_TYPE(UINT32, uint32, UInt32);
655 HANDLE_TYPE(UINT64, uint64, UInt64);
656 HANDLE_TYPE( FLOAT, float, Float);
657 HANDLE_TYPE(DOUBLE, double, Double);
658 HANDLE_TYPE( BOOL, bool, Bool);
659 HANDLE_TYPE( ENUM, enum, Enum);
660 #undef HANDLE_TYPE
661 case WireFormatLite::CPPTYPE_STRING:
662 SetString(iter->first, other_extension.type,
663 *other_extension.string_value,
664 other_extension.descriptor);
665 break;
666 case WireFormatLite::CPPTYPE_MESSAGE:
667 MutableMessage(iter->first, other_extension.type,
668 *other_extension.message_value,
669 other_extension.descriptor)
670 ->CheckTypeAndMergeFrom(*other_extension.message_value);
671 break;
672 }
673 }
674 }
675 }
676 }
677
Swap(ExtensionSet * x)678 void ExtensionSet::Swap(ExtensionSet* x) {
679 extensions_.swap(x->extensions_);
680 }
681
IsInitialized() const682 bool ExtensionSet::IsInitialized() const {
683 // Extensions are never required. However, we need to check that all
684 // embedded messages are initialized.
685 for (map<int, Extension>::const_iterator iter = extensions_.begin();
686 iter != extensions_.end(); ++iter) {
687 const Extension& extension = iter->second;
688 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
689 if (extension.is_repeated) {
690 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
691 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
692 return false;
693 }
694 }
695 } else {
696 if (!extension.is_cleared) {
697 if (!extension.message_value->IsInitialized()) return false;
698 }
699 }
700 }
701 }
702
703 return true;
704 }
705
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)706 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
707 ExtensionFinder* extension_finder,
708 FieldSkipper* field_skipper) {
709 int number = WireFormatLite::GetTagFieldNumber(tag);
710 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
711
712 ExtensionInfo extension;
713 bool is_unknown;
714 if (!extension_finder->Find(number, &extension)) {
715 is_unknown = true;
716 } else if (extension.is_packed) {
717 is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
718 } else {
719 WireFormatLite::WireType expected_wire_type =
720 WireFormatLite::WireTypeForFieldType(real_type(extension.type));
721 is_unknown = (wire_type != expected_wire_type);
722 }
723
724 if (is_unknown) {
725 field_skipper->SkipField(input, tag);
726 } else if (extension.is_packed) {
727 uint32 size;
728 if (!input->ReadVarint32(&size)) return false;
729 io::CodedInputStream::Limit limit = input->PushLimit(size);
730
731 switch (extension.type) {
732 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
733 case WireFormatLite::TYPE_##UPPERCASE: \
734 while (input->BytesUntilLimit() > 0) { \
735 CPP_LOWERCASE value; \
736 if (!WireFormatLite::ReadPrimitive< \
737 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
738 input, &value)) return false; \
739 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
740 true, value, extension.descriptor); \
741 } \
742 break
743
744 HANDLE_TYPE( INT32, Int32, int32);
745 HANDLE_TYPE( INT64, Int64, int64);
746 HANDLE_TYPE( UINT32, UInt32, uint32);
747 HANDLE_TYPE( UINT64, UInt64, uint64);
748 HANDLE_TYPE( SINT32, Int32, int32);
749 HANDLE_TYPE( SINT64, Int64, int64);
750 HANDLE_TYPE( FIXED32, UInt32, uint32);
751 HANDLE_TYPE( FIXED64, UInt64, uint64);
752 HANDLE_TYPE(SFIXED32, Int32, int32);
753 HANDLE_TYPE(SFIXED64, Int64, int64);
754 HANDLE_TYPE( FLOAT, Float, float);
755 HANDLE_TYPE( DOUBLE, Double, double);
756 HANDLE_TYPE( BOOL, Bool, bool);
757 #undef HANDLE_TYPE
758
759 case WireFormatLite::TYPE_ENUM:
760 while (input->BytesUntilLimit() > 0) {
761 int value;
762 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
763 input, &value)) return false;
764 if (extension.enum_validity_check.func(
765 extension.enum_validity_check.arg, value)) {
766 AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
767 extension.descriptor);
768 }
769 }
770 break;
771
772 case WireFormatLite::TYPE_STRING:
773 case WireFormatLite::TYPE_BYTES:
774 case WireFormatLite::TYPE_GROUP:
775 case WireFormatLite::TYPE_MESSAGE:
776 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
777 break;
778 }
779
780 input->PopLimit(limit);
781 } else {
782 switch (extension.type) {
783 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
784 case WireFormatLite::TYPE_##UPPERCASE: { \
785 CPP_LOWERCASE value; \
786 if (!WireFormatLite::ReadPrimitive< \
787 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
788 input, &value)) return false; \
789 if (extension.is_repeated) { \
790 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
791 false, value, extension.descriptor); \
792 } else { \
793 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
794 extension.descriptor); \
795 } \
796 } break
797
798 HANDLE_TYPE( INT32, Int32, int32);
799 HANDLE_TYPE( INT64, Int64, int64);
800 HANDLE_TYPE( UINT32, UInt32, uint32);
801 HANDLE_TYPE( UINT64, UInt64, uint64);
802 HANDLE_TYPE( SINT32, Int32, int32);
803 HANDLE_TYPE( SINT64, Int64, int64);
804 HANDLE_TYPE( FIXED32, UInt32, uint32);
805 HANDLE_TYPE( FIXED64, UInt64, uint64);
806 HANDLE_TYPE(SFIXED32, Int32, int32);
807 HANDLE_TYPE(SFIXED64, Int64, int64);
808 HANDLE_TYPE( FLOAT, Float, float);
809 HANDLE_TYPE( DOUBLE, Double, double);
810 HANDLE_TYPE( BOOL, Bool, bool);
811 #undef HANDLE_TYPE
812
813 case WireFormatLite::TYPE_ENUM: {
814 int value;
815 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
816 input, &value)) return false;
817
818 if (!extension.enum_validity_check.func(
819 extension.enum_validity_check.arg, value)) {
820 // Invalid value. Treat as unknown.
821 field_skipper->SkipUnknownEnum(number, value);
822 } else if (extension.is_repeated) {
823 AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
824 extension.descriptor);
825 } else {
826 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
827 extension.descriptor);
828 }
829 break;
830 }
831
832 case WireFormatLite::TYPE_STRING: {
833 string* value = extension.is_repeated ?
834 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
835 MutableString(number, WireFormatLite::TYPE_STRING,
836 extension.descriptor);
837 if (!WireFormatLite::ReadString(input, value)) return false;
838 break;
839 }
840
841 case WireFormatLite::TYPE_BYTES: {
842 string* value = extension.is_repeated ?
843 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
844 MutableString(number, WireFormatLite::TYPE_STRING,
845 extension.descriptor);
846 if (!WireFormatLite::ReadBytes(input, value)) return false;
847 break;
848 }
849
850 case WireFormatLite::TYPE_GROUP: {
851 MessageLite* value = extension.is_repeated ?
852 AddMessage(number, WireFormatLite::TYPE_GROUP,
853 *extension.message_prototype, extension.descriptor) :
854 MutableMessage(number, WireFormatLite::TYPE_GROUP,
855 *extension.message_prototype, extension.descriptor);
856 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
857 break;
858 }
859
860 case WireFormatLite::TYPE_MESSAGE: {
861 MessageLite* value = extension.is_repeated ?
862 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
863 *extension.message_prototype, extension.descriptor) :
864 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
865 *extension.message_prototype, extension.descriptor);
866 if (!WireFormatLite::ReadMessage(input, value)) return false;
867 break;
868 }
869 }
870 }
871
872 return true;
873 }
874
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type)875 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
876 const MessageLite* containing_type) {
877 FieldSkipper skipper;
878 GeneratedExtensionFinder finder(containing_type);
879 return ParseField(tag, input, &finder, &skipper);
880 }
881
882 // Defined in extension_set_heavy.cc.
883 // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
884 // const MessageLite* containing_type,
885 // UnknownFieldSet* unknown_fields)
886
ParseMessageSet(io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)887 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
888 ExtensionFinder* extension_finder,
889 FieldSkipper* field_skipper) {
890 while (true) {
891 uint32 tag = input->ReadTag();
892 switch (tag) {
893 case 0:
894 return true;
895 case WireFormatLite::kMessageSetItemStartTag:
896 if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
897 return false;
898 }
899 break;
900 default:
901 if (!ParseField(tag, input, extension_finder, field_skipper)) {
902 return false;
903 }
904 break;
905 }
906 }
907 }
908
ParseMessageSet(io::CodedInputStream * input,const MessageLite * containing_type)909 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
910 const MessageLite* containing_type) {
911 FieldSkipper skipper;
912 GeneratedExtensionFinder finder(containing_type);
913 return ParseMessageSet(input, &finder, &skipper);
914 }
915
916 // Defined in extension_set_heavy.cc.
917 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
918 // const MessageLite* containing_type,
919 // UnknownFieldSet* unknown_fields);
920
ParseMessageSetItem(io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)921 bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
922 ExtensionFinder* extension_finder,
923 FieldSkipper* field_skipper) {
924 // TODO(kenton): It would be nice to share code between this and
925 // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
926 // differences would be hard to factor out.
927
928 // This method parses a group which should contain two fields:
929 // required int32 type_id = 2;
930 // required data message = 3;
931
932 // Once we see a type_id, we'll construct a fake tag for this extension
933 // which is the tag it would have had under the proto2 extensions wire
934 // format.
935 uint32 fake_tag = 0;
936
937 // If we see message data before the type_id, we'll append it to this so
938 // we can parse it later. This will probably never happen in practice,
939 // as no MessageSet encoder I know of writes the message before the type ID.
940 // But, it's technically valid so we should allow it.
941 // TODO(kenton): Use a Cord instead? Do I care?
942 string message_data;
943
944 while (true) {
945 uint32 tag = input->ReadTag();
946 if (tag == 0) return false;
947
948 switch (tag) {
949 case WireFormatLite::kMessageSetTypeIdTag: {
950 uint32 type_id;
951 if (!input->ReadVarint32(&type_id)) return false;
952 fake_tag = WireFormatLite::MakeTag(type_id,
953 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
954
955 if (!message_data.empty()) {
956 // We saw some message data before the type_id. Have to parse it
957 // now.
958 io::CodedInputStream sub_input(
959 reinterpret_cast<const uint8*>(message_data.data()),
960 message_data.size());
961 if (!ParseField(fake_tag, &sub_input,
962 extension_finder, field_skipper)) {
963 return false;
964 }
965 message_data.clear();
966 }
967
968 break;
969 }
970
971 case WireFormatLite::kMessageSetMessageTag: {
972 if (fake_tag == 0) {
973 // We haven't seen a type_id yet. Append this data to message_data.
974 string temp;
975 uint32 length;
976 if (!input->ReadVarint32(&length)) return false;
977 if (!input->ReadString(&temp, length)) return false;
978 message_data.append(temp);
979 } else {
980 // Already saw type_id, so we can parse this directly.
981 if (!ParseField(fake_tag, input,
982 extension_finder, field_skipper)) {
983 return false;
984 }
985 }
986
987 break;
988 }
989
990 case WireFormatLite::kMessageSetItemEndTag: {
991 return true;
992 }
993
994 default: {
995 if (!field_skipper->SkipField(input, tag)) return false;
996 }
997 }
998 }
999 }
1000
SerializeWithCachedSizes(int start_field_number,int end_field_number,io::CodedOutputStream * output) const1001 void ExtensionSet::SerializeWithCachedSizes(
1002 int start_field_number, int end_field_number,
1003 io::CodedOutputStream* output) const {
1004 map<int, Extension>::const_iterator iter;
1005 for (iter = extensions_.lower_bound(start_field_number);
1006 iter != extensions_.end() && iter->first < end_field_number;
1007 ++iter) {
1008 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1009 }
1010 }
1011
SerializeMessageSetWithCachedSizes(io::CodedOutputStream * output) const1012 void ExtensionSet::SerializeMessageSetWithCachedSizes(
1013 io::CodedOutputStream* output) const {
1014 map<int, Extension>::const_iterator iter;
1015 for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
1016 iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
1017 }
1018 }
1019
ByteSize() const1020 int ExtensionSet::ByteSize() const {
1021 int total_size = 0;
1022
1023 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1024 iter != extensions_.end(); ++iter) {
1025 total_size += iter->second.ByteSize(iter->first);
1026 }
1027
1028 return total_size;
1029 }
1030
MessageSetByteSize() const1031 int ExtensionSet::MessageSetByteSize() const {
1032 int total_size = 0;
1033
1034 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1035 iter != extensions_.end(); ++iter) {
1036 total_size += iter->second.MessageSetItemByteSize(iter->first);
1037 }
1038
1039 return total_size;
1040 }
1041
1042 // Defined in extension_set_heavy.cc.
1043 // int ExtensionSet::SpaceUsedExcludingSelf() const
1044
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1045 bool ExtensionSet::MaybeNewExtension(int number,
1046 const FieldDescriptor* descriptor,
1047 Extension** result) {
1048 pair<map<int, Extension>::iterator, bool> insert_result =
1049 extensions_.insert(make_pair(number, Extension()));
1050 *result = &insert_result.first->second;
1051 (*result)->descriptor = descriptor;
1052 return insert_result.second;
1053 }
1054
1055 // ===================================================================
1056 // Methods of ExtensionSet::Extension
1057
Clear()1058 void ExtensionSet::Extension::Clear() {
1059 if (is_repeated) {
1060 switch (cpp_type(type)) {
1061 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1062 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1063 repeated_##LOWERCASE##_value->Clear(); \
1064 break
1065
1066 HANDLE_TYPE( INT32, int32);
1067 HANDLE_TYPE( INT64, int64);
1068 HANDLE_TYPE( UINT32, uint32);
1069 HANDLE_TYPE( UINT64, uint64);
1070 HANDLE_TYPE( FLOAT, float);
1071 HANDLE_TYPE( DOUBLE, double);
1072 HANDLE_TYPE( BOOL, bool);
1073 HANDLE_TYPE( ENUM, enum);
1074 HANDLE_TYPE( STRING, string);
1075 HANDLE_TYPE(MESSAGE, message);
1076 #undef HANDLE_TYPE
1077 }
1078 } else {
1079 if (!is_cleared) {
1080 switch (cpp_type(type)) {
1081 case WireFormatLite::CPPTYPE_STRING:
1082 string_value->clear();
1083 break;
1084 case WireFormatLite::CPPTYPE_MESSAGE:
1085 message_value->Clear();
1086 break;
1087 default:
1088 // No need to do anything. Get*() will return the default value
1089 // as long as is_cleared is true and Set*() will overwrite the
1090 // previous value.
1091 break;
1092 }
1093
1094 is_cleared = true;
1095 }
1096 }
1097 }
1098
SerializeFieldWithCachedSizes(int number,io::CodedOutputStream * output) const1099 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1100 int number,
1101 io::CodedOutputStream* output) const {
1102 if (is_repeated) {
1103 if (is_packed) {
1104 if (cached_size == 0) return;
1105
1106 WireFormatLite::WriteTag(number,
1107 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1108 output->WriteVarint32(cached_size);
1109
1110 switch (real_type(type)) {
1111 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1112 case WireFormatLite::TYPE_##UPPERCASE: \
1113 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1114 WireFormatLite::Write##CAMELCASE##NoTag( \
1115 repeated_##LOWERCASE##_value->Get(i), output); \
1116 } \
1117 break
1118
1119 HANDLE_TYPE( INT32, Int32, int32);
1120 HANDLE_TYPE( INT64, Int64, int64);
1121 HANDLE_TYPE( UINT32, UInt32, uint32);
1122 HANDLE_TYPE( UINT64, UInt64, uint64);
1123 HANDLE_TYPE( SINT32, SInt32, int32);
1124 HANDLE_TYPE( SINT64, SInt64, int64);
1125 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1126 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1127 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1128 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1129 HANDLE_TYPE( FLOAT, Float, float);
1130 HANDLE_TYPE( DOUBLE, Double, double);
1131 HANDLE_TYPE( BOOL, Bool, bool);
1132 HANDLE_TYPE( ENUM, Enum, enum);
1133 #undef HANDLE_TYPE
1134
1135 case WireFormatLite::TYPE_STRING:
1136 case WireFormatLite::TYPE_BYTES:
1137 case WireFormatLite::TYPE_GROUP:
1138 case WireFormatLite::TYPE_MESSAGE:
1139 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1140 break;
1141 }
1142 } else {
1143 switch (real_type(type)) {
1144 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1145 case WireFormatLite::TYPE_##UPPERCASE: \
1146 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1147 WireFormatLite::Write##CAMELCASE(number, \
1148 repeated_##LOWERCASE##_value->Get(i), output); \
1149 } \
1150 break
1151
1152 HANDLE_TYPE( INT32, Int32, int32);
1153 HANDLE_TYPE( INT64, Int64, int64);
1154 HANDLE_TYPE( UINT32, UInt32, uint32);
1155 HANDLE_TYPE( UINT64, UInt64, uint64);
1156 HANDLE_TYPE( SINT32, SInt32, int32);
1157 HANDLE_TYPE( SINT64, SInt64, int64);
1158 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1159 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1160 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1161 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1162 HANDLE_TYPE( FLOAT, Float, float);
1163 HANDLE_TYPE( DOUBLE, Double, double);
1164 HANDLE_TYPE( BOOL, Bool, bool);
1165 HANDLE_TYPE( STRING, String, string);
1166 HANDLE_TYPE( BYTES, Bytes, string);
1167 HANDLE_TYPE( ENUM, Enum, enum);
1168 HANDLE_TYPE( GROUP, Group, message);
1169 HANDLE_TYPE( MESSAGE, Message, message);
1170 #undef HANDLE_TYPE
1171 }
1172 }
1173 } else if (!is_cleared) {
1174 switch (real_type(type)) {
1175 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
1176 case WireFormatLite::TYPE_##UPPERCASE: \
1177 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1178 break
1179
1180 HANDLE_TYPE( INT32, Int32, int32_value);
1181 HANDLE_TYPE( INT64, Int64, int64_value);
1182 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1183 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1184 HANDLE_TYPE( SINT32, SInt32, int32_value);
1185 HANDLE_TYPE( SINT64, SInt64, int64_value);
1186 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1187 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1188 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1189 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1190 HANDLE_TYPE( FLOAT, Float, float_value);
1191 HANDLE_TYPE( DOUBLE, Double, double_value);
1192 HANDLE_TYPE( BOOL, Bool, bool_value);
1193 HANDLE_TYPE( STRING, String, *string_value);
1194 HANDLE_TYPE( BYTES, Bytes, *string_value);
1195 HANDLE_TYPE( ENUM, Enum, enum_value);
1196 HANDLE_TYPE( GROUP, Group, *message_value);
1197 HANDLE_TYPE( MESSAGE, Message, *message_value);
1198 #undef HANDLE_TYPE
1199 }
1200 }
1201 }
1202
SerializeMessageSetItemWithCachedSizes(int number,io::CodedOutputStream * output) const1203 void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
1204 int number,
1205 io::CodedOutputStream* output) const {
1206 if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1207 // Not a valid MessageSet extension, but serialize it the normal way.
1208 SerializeFieldWithCachedSizes(number, output);
1209 return;
1210 }
1211
1212 if (is_cleared) return;
1213
1214 // Start group.
1215 output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
1216
1217 // Write type ID.
1218 WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
1219 number,
1220 output);
1221 // Write message.
1222 WireFormatLite::WriteMessageMaybeToArray(
1223 WireFormatLite::kMessageSetMessageNumber,
1224 *message_value,
1225 output);
1226
1227 // End group.
1228 output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
1229 }
1230
ByteSize(int number) const1231 int ExtensionSet::Extension::ByteSize(int number) const {
1232 int result = 0;
1233
1234 if (is_repeated) {
1235 if (is_packed) {
1236 switch (real_type(type)) {
1237 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1238 case WireFormatLite::TYPE_##UPPERCASE: \
1239 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1240 result += WireFormatLite::CAMELCASE##Size( \
1241 repeated_##LOWERCASE##_value->Get(i)); \
1242 } \
1243 break
1244
1245 HANDLE_TYPE( INT32, Int32, int32);
1246 HANDLE_TYPE( INT64, Int64, int64);
1247 HANDLE_TYPE( UINT32, UInt32, uint32);
1248 HANDLE_TYPE( UINT64, UInt64, uint64);
1249 HANDLE_TYPE( SINT32, SInt32, int32);
1250 HANDLE_TYPE( SINT64, SInt64, int64);
1251 HANDLE_TYPE( ENUM, Enum, enum);
1252 #undef HANDLE_TYPE
1253
1254 // Stuff with fixed size.
1255 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1256 case WireFormatLite::TYPE_##UPPERCASE: \
1257 result += WireFormatLite::k##CAMELCASE##Size * \
1258 repeated_##LOWERCASE##_value->size(); \
1259 break
1260 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1261 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1262 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1263 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1264 HANDLE_TYPE( FLOAT, Float, float);
1265 HANDLE_TYPE( DOUBLE, Double, double);
1266 HANDLE_TYPE( BOOL, Bool, bool);
1267 #undef HANDLE_TYPE
1268
1269 case WireFormatLite::TYPE_STRING:
1270 case WireFormatLite::TYPE_BYTES:
1271 case WireFormatLite::TYPE_GROUP:
1272 case WireFormatLite::TYPE_MESSAGE:
1273 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1274 break;
1275 }
1276
1277 cached_size = result;
1278 if (result > 0) {
1279 result += io::CodedOutputStream::VarintSize32(result);
1280 result += io::CodedOutputStream::VarintSize32(
1281 WireFormatLite::MakeTag(number,
1282 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1283 }
1284 } else {
1285 int tag_size = WireFormatLite::TagSize(number, real_type(type));
1286
1287 switch (real_type(type)) {
1288 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1289 case WireFormatLite::TYPE_##UPPERCASE: \
1290 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1291 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1292 result += WireFormatLite::CAMELCASE##Size( \
1293 repeated_##LOWERCASE##_value->Get(i)); \
1294 } \
1295 break
1296
1297 HANDLE_TYPE( INT32, Int32, int32);
1298 HANDLE_TYPE( INT64, Int64, int64);
1299 HANDLE_TYPE( UINT32, UInt32, uint32);
1300 HANDLE_TYPE( UINT64, UInt64, uint64);
1301 HANDLE_TYPE( SINT32, SInt32, int32);
1302 HANDLE_TYPE( SINT64, SInt64, int64);
1303 HANDLE_TYPE( STRING, String, string);
1304 HANDLE_TYPE( BYTES, Bytes, string);
1305 HANDLE_TYPE( ENUM, Enum, enum);
1306 HANDLE_TYPE( GROUP, Group, message);
1307 HANDLE_TYPE( MESSAGE, Message, message);
1308 #undef HANDLE_TYPE
1309
1310 // Stuff with fixed size.
1311 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1312 case WireFormatLite::TYPE_##UPPERCASE: \
1313 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
1314 repeated_##LOWERCASE##_value->size(); \
1315 break
1316 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1317 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1318 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1319 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1320 HANDLE_TYPE( FLOAT, Float, float);
1321 HANDLE_TYPE( DOUBLE, Double, double);
1322 HANDLE_TYPE( BOOL, Bool, bool);
1323 #undef HANDLE_TYPE
1324 }
1325 }
1326 } else if (!is_cleared) {
1327 result += WireFormatLite::TagSize(number, real_type(type));
1328 switch (real_type(type)) {
1329 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1330 case WireFormatLite::TYPE_##UPPERCASE: \
1331 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1332 break
1333
1334 HANDLE_TYPE( INT32, Int32, int32_value);
1335 HANDLE_TYPE( INT64, Int64, int64_value);
1336 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1337 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1338 HANDLE_TYPE( SINT32, SInt32, int32_value);
1339 HANDLE_TYPE( SINT64, SInt64, int64_value);
1340 HANDLE_TYPE( STRING, String, *string_value);
1341 HANDLE_TYPE( BYTES, Bytes, *string_value);
1342 HANDLE_TYPE( ENUM, Enum, enum_value);
1343 HANDLE_TYPE( GROUP, Group, *message_value);
1344 HANDLE_TYPE( MESSAGE, Message, *message_value);
1345 #undef HANDLE_TYPE
1346
1347 // Stuff with fixed size.
1348 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1349 case WireFormatLite::TYPE_##UPPERCASE: \
1350 result += WireFormatLite::k##CAMELCASE##Size; \
1351 break
1352 HANDLE_TYPE( FIXED32, Fixed32);
1353 HANDLE_TYPE( FIXED64, Fixed64);
1354 HANDLE_TYPE(SFIXED32, SFixed32);
1355 HANDLE_TYPE(SFIXED64, SFixed64);
1356 HANDLE_TYPE( FLOAT, Float);
1357 HANDLE_TYPE( DOUBLE, Double);
1358 HANDLE_TYPE( BOOL, Bool);
1359 #undef HANDLE_TYPE
1360 }
1361 }
1362
1363 return result;
1364 }
1365
MessageSetItemByteSize(int number) const1366 int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
1367 if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1368 // Not a valid MessageSet extension, but compute the byte size for it the
1369 // normal way.
1370 return ByteSize(number);
1371 }
1372
1373 if (is_cleared) return 0;
1374
1375 int our_size = WireFormatLite::kMessageSetItemTagsSize;
1376
1377 // type_id
1378 our_size += io::CodedOutputStream::VarintSize32(number);
1379
1380 // message
1381 int message_size = message_value->ByteSize();
1382
1383 our_size += io::CodedOutputStream::VarintSize32(message_size);
1384 our_size += message_size;
1385
1386 return our_size;
1387 }
1388
GetSize() const1389 int ExtensionSet::Extension::GetSize() const {
1390 GOOGLE_DCHECK(is_repeated);
1391 switch (cpp_type(type)) {
1392 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1393 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1394 return repeated_##LOWERCASE##_value->size()
1395
1396 HANDLE_TYPE( INT32, int32);
1397 HANDLE_TYPE( INT64, int64);
1398 HANDLE_TYPE( UINT32, uint32);
1399 HANDLE_TYPE( UINT64, uint64);
1400 HANDLE_TYPE( FLOAT, float);
1401 HANDLE_TYPE( DOUBLE, double);
1402 HANDLE_TYPE( BOOL, bool);
1403 HANDLE_TYPE( ENUM, enum);
1404 HANDLE_TYPE( STRING, string);
1405 HANDLE_TYPE(MESSAGE, message);
1406 #undef HANDLE_TYPE
1407 }
1408
1409 GOOGLE_LOG(FATAL) << "Can't get here.";
1410 return 0;
1411 }
1412
Free()1413 void ExtensionSet::Extension::Free() {
1414 if (is_repeated) {
1415 switch (cpp_type(type)) {
1416 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1417 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1418 delete repeated_##LOWERCASE##_value; \
1419 break
1420
1421 HANDLE_TYPE( INT32, int32);
1422 HANDLE_TYPE( INT64, int64);
1423 HANDLE_TYPE( UINT32, uint32);
1424 HANDLE_TYPE( UINT64, uint64);
1425 HANDLE_TYPE( FLOAT, float);
1426 HANDLE_TYPE( DOUBLE, double);
1427 HANDLE_TYPE( BOOL, bool);
1428 HANDLE_TYPE( ENUM, enum);
1429 HANDLE_TYPE( STRING, string);
1430 HANDLE_TYPE(MESSAGE, message);
1431 #undef HANDLE_TYPE
1432 }
1433 } else {
1434 switch (cpp_type(type)) {
1435 case WireFormatLite::CPPTYPE_STRING:
1436 delete string_value;
1437 break;
1438 case WireFormatLite::CPPTYPE_MESSAGE:
1439 delete message_value;
1440 break;
1441 default:
1442 break;
1443 }
1444 }
1445 }
1446
1447 // Defined in extension_set_heavy.cc.
1448 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1449
1450 } // namespace internal
1451 } // namespace protobuf
1452 } // namespace google
1453