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