blob: f4786392bcb46bb76c7d77ab1ea8f2f82f8991ef [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00004//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
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>
kenton@google.comd37d46d2009-04-25 02:53:47 +000036#include <google/protobuf/stubs/common.h>
37#include <google/protobuf/stubs/once.h>
temporal40ee5512008-07-10 02:12:20 +000038#include <google/protobuf/extension_set.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000039#include <google/protobuf/message_lite.h>
temporal40ee5512008-07-10 02:12:20 +000040#include <google/protobuf/io/coded_stream.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000041#include <google/protobuf/wire_format_lite_inl.h>
temporal40ee5512008-07-10 02:12:20 +000042#include <google/protobuf/repeated_field.h>
jieluo@google.com4de8f552014-07-18 00:47:59 +000043#include <google/protobuf/stubs/map_util.h>
temporal40ee5512008-07-10 02:12:20 +000044
45namespace google {
46namespace protobuf {
47namespace internal {
48
kenton@google.comd37d46d2009-04-25 02:53:47 +000049namespace {
temporal40ee5512008-07-10 02:12:20 +000050
kenton@google.com80b1d622009-07-29 01:13:20 +000051inline WireFormatLite::FieldType real_type(FieldType type) {
52 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
53 return static_cast<WireFormatLite::FieldType>(type);
temporal40ee5512008-07-10 02:12:20 +000054}
55
kenton@google.com80b1d622009-07-29 01:13:20 +000056inline WireFormatLite::CppType cpp_type(FieldType type) {
57 return WireFormatLite::FieldTypeToCppType(real_type(type));
kenton@google.comd37d46d2009-04-25 02:53:47 +000058}
59
jieluo@google.com4de8f552014-07-18 00:47:59 +000060inline bool is_packable(WireFormatLite::WireType type) {
61 switch (type) {
62 case WireFormatLite::WIRETYPE_VARINT:
63 case WireFormatLite::WIRETYPE_FIXED64:
64 case WireFormatLite::WIRETYPE_FIXED32:
65 return true;
66 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
67 case WireFormatLite::WIRETYPE_START_GROUP:
68 case WireFormatLite::WIRETYPE_END_GROUP:
69 return false;
70
71 // Do not add a default statement. Let the compiler complain when someone
72 // adds a new wire type.
73 }
74}
75
kenton@google.comd37d46d2009-04-25 02:53:47 +000076// Registry stuff.
kenton@google.com80b1d622009-07-29 01:13:20 +000077typedef hash_map<pair<const MessageLite*, int>,
78 ExtensionInfo> ExtensionRegistry;
kenton@google.comd37d46d2009-04-25 02:53:47 +000079ExtensionRegistry* registry_ = NULL;
temporalbdbb8632009-12-18 08:21:00 +000080GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
kenton@google.com63e646b2009-05-06 19:27:03 +000081
82void DeleteRegistry() {
83 delete registry_;
84 registry_ = NULL;
85}
86
87void InitRegistry() {
88 registry_ = new ExtensionRegistry;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000089 OnShutdown(&DeleteRegistry);
kenton@google.com63e646b2009-05-06 19:27:03 +000090}
kenton@google.comd37d46d2009-04-25 02:53:47 +000091
92// This function is only called at startup, so there is no need for thread-
93// safety.
kenton@google.com80b1d622009-07-29 01:13:20 +000094void Register(const MessageLite* containing_type,
95 int number, ExtensionInfo info) {
96 ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
kenton@google.comd37d46d2009-04-25 02:53:47 +000097
98 if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
99 info)) {
100 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
kenton@google.com80b1d622009-07-29 01:13:20 +0000101 << containing_type->GetTypeName()
kenton@google.comd37d46d2009-04-25 02:53:47 +0000102 << "\", field number " << number << ".";
103 }
104}
105
106const ExtensionInfo* FindRegisteredExtension(
kenton@google.com80b1d622009-07-29 01:13:20 +0000107 const MessageLite* containing_type, int number) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000108 return (registry_ == NULL) ? NULL :
109 FindOrNull(*registry_, make_pair(containing_type, number));
110}
111
112} // namespace
113
kenton@google.comfccb1462009-12-18 02:11:36 +0000114ExtensionFinder::~ExtensionFinder() {}
115
116bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
117 const ExtensionInfo* extension =
118 FindRegisteredExtension(containing_type_, number);
119 if (extension == NULL) {
120 return false;
121 } else {
122 *output = *extension;
123 return true;
124 }
125}
126
kenton@google.com80b1d622009-07-29 01:13:20 +0000127void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000128 int number, FieldType type,
129 bool is_repeated, bool is_packed) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000130 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
131 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
132 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000133 ExtensionInfo info(type, is_repeated, is_packed);
134 Register(containing_type, number, info);
135}
136
kenton@google.comfccb1462009-12-18 02:11:36 +0000137static bool CallNoArgValidityFunc(const void* arg, int number) {
kenton@google.com91218af2009-12-18 07:20:43 +0000138 // Note: Must use C-style cast here rather than reinterpret_cast because
139 // the C++ standard at one point did not allow casts between function and
140 // data pointers and some compilers enforce this for C++-style casts. No
141 // compiler enforces it for C-style casts since lots of C-style code has
142 // relied on these kinds of casts for a long time, despite being
143 // technically undefined. See:
144 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
kenton@google.comf2a73292009-12-21 19:44:57 +0000145 // Also note: Some compilers do not allow function pointers to be "const".
146 // Which makes sense, I suppose, because it's meaningless.
147 return ((EnumValidityFunc*)arg)(number);
kenton@google.comfccb1462009-12-18 02:11:36 +0000148}
149
kenton@google.com80b1d622009-07-29 01:13:20 +0000150void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000151 int number, FieldType type,
152 bool is_repeated, bool is_packed,
153 EnumValidityFunc* is_valid) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000154 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000155 ExtensionInfo info(type, is_repeated, is_packed);
kenton@google.comf9c59782009-12-22 18:04:23 +0000156 info.enum_validity_check.func = CallNoArgValidityFunc;
kenton@google.com91218af2009-12-18 07:20:43 +0000157 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
kenton@google.comf9c59782009-12-22 18:04:23 +0000158 info.enum_validity_check.arg = (void*)is_valid;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000159 Register(containing_type, number, info);
160}
161
kenton@google.com80b1d622009-07-29 01:13:20 +0000162void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000163 int number, FieldType type,
164 bool is_repeated, bool is_packed,
kenton@google.com80b1d622009-07-29 01:13:20 +0000165 const MessageLite* prototype) {
166 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
167 type == WireFormatLite::TYPE_GROUP);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000168 ExtensionInfo info(type, is_repeated, is_packed);
169 info.message_prototype = prototype;
170 Register(containing_type, number, info);
temporal40ee5512008-07-10 02:12:20 +0000171}
172
kenton@google.com80b1d622009-07-29 01:13:20 +0000173
temporal40ee5512008-07-10 02:12:20 +0000174// ===================================================================
175// Constructors and basic methods.
176
kenton@google.comd37d46d2009-04-25 02:53:47 +0000177ExtensionSet::ExtensionSet() {}
temporal40ee5512008-07-10 02:12:20 +0000178
179ExtensionSet::~ExtensionSet() {
180 for (map<int, Extension>::iterator iter = extensions_.begin();
181 iter != extensions_.end(); ++iter) {
182 iter->second.Free();
183 }
184}
185
kenton@google.com80b1d622009-07-29 01:13:20 +0000186// Defined in extension_set_heavy.cc.
187// void ExtensionSet::AppendToList(const Descriptor* containing_type,
188// const DescriptorPool* pool,
189// vector<const FieldDescriptor*>* output) const
temporal40ee5512008-07-10 02:12:20 +0000190
191bool ExtensionSet::Has(int number) const {
192 map<int, Extension>::const_iterator iter = extensions_.find(number);
193 if (iter == extensions_.end()) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000194 GOOGLE_DCHECK(!iter->second.is_repeated);
temporal40ee5512008-07-10 02:12:20 +0000195 return !iter->second.is_cleared;
196}
197
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000198int ExtensionSet::NumExtensions() const {
199 int result = 0;
200 for (map<int, Extension>::const_iterator iter = extensions_.begin();
201 iter != extensions_.end(); ++iter) {
202 if (!iter->second.is_cleared) {
203 ++result;
204 }
205 }
206 return result;
207}
208
temporal40ee5512008-07-10 02:12:20 +0000209int ExtensionSet::ExtensionSize(int number) const {
210 map<int, Extension>::const_iterator iter = extensions_.find(number);
211 if (iter == extensions_.end()) return false;
212 return iter->second.GetSize();
213}
214
liujisi@google.com33165fe2010-11-02 13:14:58 +0000215FieldType ExtensionSet::ExtensionType(int number) const {
216 map<int, Extension>::const_iterator iter = extensions_.find(number);
217 if (iter == extensions_.end()) {
218 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
219 return 0;
220 }
221 if (iter->second.is_cleared) {
222 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
223 }
224 return iter->second.type;
225}
226
temporal40ee5512008-07-10 02:12:20 +0000227void ExtensionSet::ClearExtension(int number) {
228 map<int, Extension>::iterator iter = extensions_.find(number);
229 if (iter == extensions_.end()) return;
230 iter->second.Clear();
231}
232
233// ===================================================================
234// Field accessors
235
kenton@google.com80b1d622009-07-29 01:13:20 +0000236namespace {
237
238enum Cardinality {
239 REPEATED,
240 OPTIONAL
241};
242
243} // namespace
244
245#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
246 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
247 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
temporal40ee5512008-07-10 02:12:20 +0000248
249// -------------------------------------------------------------------
250// Primitives
251
252#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
253 \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000254LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
255 LOWERCASE default_value) const { \
temporal40ee5512008-07-10 02:12:20 +0000256 map<int, Extension>::const_iterator iter = extensions_.find(number); \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000257 if (iter == extensions_.end() || iter->second.is_cleared) { \
258 return default_value; \
temporal40ee5512008-07-10 02:12:20 +0000259 } else { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000260 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000261 return iter->second.LOWERCASE##_value; \
262 } \
263} \
264 \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000265void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
kenton@google.comfccb1462009-12-18 02:11:36 +0000266 LOWERCASE value, \
267 const FieldDescriptor* descriptor) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000268 Extension* extension; \
kenton@google.comfccb1462009-12-18 02:11:36 +0000269 if (MaybeNewExtension(number, descriptor, &extension)) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000270 extension->type = type; \
kenton@google.com80b1d622009-07-29 01:13:20 +0000271 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000272 extension->is_repeated = false; \
temporal40ee5512008-07-10 02:12:20 +0000273 } else { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000274 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000275 } \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000276 extension->is_cleared = false; \
temporal40ee5512008-07-10 02:12:20 +0000277 extension->LOWERCASE##_value = value; \
278} \
279 \
280LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
281 map<int, Extension>::const_iterator iter = extensions_.find(number); \
282 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000283 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000284 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
285} \
286 \
287void ExtensionSet::SetRepeated##CAMELCASE( \
288 int number, int index, LOWERCASE value) { \
289 map<int, Extension>::iterator iter = extensions_.find(number); \
290 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000291 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000292 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
293} \
294 \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000295void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
kenton@google.comfccb1462009-12-18 02:11:36 +0000296 bool packed, LOWERCASE value, \
297 const FieldDescriptor* descriptor) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000298 Extension* extension; \
kenton@google.comfccb1462009-12-18 02:11:36 +0000299 if (MaybeNewExtension(number, descriptor, &extension)) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000300 extension->type = type; \
kenton@google.com80b1d622009-07-29 01:13:20 +0000301 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000302 extension->is_repeated = true; \
303 extension->is_packed = packed; \
temporal40ee5512008-07-10 02:12:20 +0000304 extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
temporal40ee5512008-07-10 02:12:20 +0000305 } else { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000306 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
307 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
temporal40ee5512008-07-10 02:12:20 +0000308 } \
309 extension->repeated_##LOWERCASE##_value->Add(value); \
310}
311
312PRIMITIVE_ACCESSORS( INT32, int32, Int32)
313PRIMITIVE_ACCESSORS( INT64, int64, Int64)
314PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
315PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
316PRIMITIVE_ACCESSORS( FLOAT, float, Float)
317PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
318PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
319
320#undef PRIMITIVE_ACCESSORS
321
jieluo@google.com4de8f552014-07-18 00:47:59 +0000322const void* ExtensionSet::GetRawRepeatedField(int number,
323 const void* default_value) const {
324 map<int, Extension>::const_iterator iter = extensions_.find(number);
325 if (iter == extensions_.end()) {
326 return default_value;
327 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000328 // We assume that all the RepeatedField<>* pointers have the same
329 // size and alignment within the anonymous union in Extension.
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000330 return iter->second.repeated_int32_value;
331}
332
jieluo@google.com4de8f552014-07-18 00:47:59 +0000333void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
334 bool packed,
335 const FieldDescriptor* desc) {
336 Extension* extension;
337
338 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
339 // extension.
340 if (MaybeNewExtension(number, desc, &extension)) {
341 extension->is_repeated = true;
342 extension->type = field_type;
343 extension->is_packed = packed;
344
345 switch (WireFormatLite::FieldTypeToCppType(
346 static_cast<WireFormatLite::FieldType>(field_type))) {
347 case WireFormatLite::CPPTYPE_INT32:
348 extension->repeated_int32_value = new RepeatedField<int32>();
349 break;
350 case WireFormatLite::CPPTYPE_INT64:
351 extension->repeated_int64_value = new RepeatedField<int64>();
352 break;
353 case WireFormatLite::CPPTYPE_UINT32:
354 extension->repeated_uint32_value = new RepeatedField<uint32>();
355 break;
356 case WireFormatLite::CPPTYPE_UINT64:
357 extension->repeated_uint64_value = new RepeatedField<uint64>();
358 break;
359 case WireFormatLite::CPPTYPE_DOUBLE:
360 extension->repeated_double_value = new RepeatedField<double>();
361 break;
362 case WireFormatLite::CPPTYPE_FLOAT:
363 extension->repeated_float_value = new RepeatedField<float>();
364 break;
365 case WireFormatLite::CPPTYPE_BOOL:
366 extension->repeated_bool_value = new RepeatedField<bool>();
367 break;
368 case WireFormatLite::CPPTYPE_ENUM:
369 extension->repeated_enum_value = new RepeatedField<int>();
370 break;
371 case WireFormatLite::CPPTYPE_STRING:
372 extension->repeated_string_value = new RepeatedPtrField< ::std::string>();
373 break;
374 case WireFormatLite::CPPTYPE_MESSAGE:
375 extension->repeated_message_value = new RepeatedPtrField<MessageLite>();
376 break;
377 }
378 }
379
380 // We assume that all the RepeatedField<>* pointers have the same
381 // size and alignment within the anonymous union in Extension.
382 return extension->repeated_int32_value;
383}
384
385// Compatible version using old call signature. Does not create extensions when
386// the don't already exist; instead, just GOOGLE_CHECK-fails.
387void* ExtensionSet::MutableRawRepeatedField(int number) {
388 map<int, Extension>::iterator iter = extensions_.find(number);
389 GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
390 // We assume that all the RepeatedField<>* pointers have the same
391 // size and alignment within the anonymous union in Extension.
392 return iter->second.repeated_int32_value;
393}
394
395
temporal40ee5512008-07-10 02:12:20 +0000396// -------------------------------------------------------------------
397// Enums
398
kenton@google.comd37d46d2009-04-25 02:53:47 +0000399int ExtensionSet::GetEnum(int number, int default_value) const {
temporal40ee5512008-07-10 02:12:20 +0000400 map<int, Extension>::const_iterator iter = extensions_.find(number);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000401 if (iter == extensions_.end() || iter->second.is_cleared) {
temporal40ee5512008-07-10 02:12:20 +0000402 // Not present. Return the default value.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000403 return default_value;
temporal40ee5512008-07-10 02:12:20 +0000404 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000405 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000406 return iter->second.enum_value;
407 }
408}
409
kenton@google.comfccb1462009-12-18 02:11:36 +0000410void ExtensionSet::SetEnum(int number, FieldType type, int value,
411 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000412 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000413 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000414 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000415 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000416 extension->is_repeated = false;
temporal40ee5512008-07-10 02:12:20 +0000417 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000418 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000419 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000420 extension->is_cleared = false;
temporal40ee5512008-07-10 02:12:20 +0000421 extension->enum_value = value;
422}
423
424int ExtensionSet::GetRepeatedEnum(int number, int index) const {
425 map<int, Extension>::const_iterator iter = extensions_.find(number);
426 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000427 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000428 return iter->second.repeated_enum_value->Get(index);
429}
430
431void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
432 map<int, Extension>::iterator iter = extensions_.find(number);
433 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000434 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000435 iter->second.repeated_enum_value->Set(index, value);
436}
437
kenton@google.comd37d46d2009-04-25 02:53:47 +0000438void ExtensionSet::AddEnum(int number, FieldType type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000439 bool packed, int value,
440 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000441 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000442 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000443 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000444 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000445 extension->is_repeated = true;
446 extension->is_packed = packed;
temporal40ee5512008-07-10 02:12:20 +0000447 extension->repeated_enum_value = new RepeatedField<int>();
temporal40ee5512008-07-10 02:12:20 +0000448 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000449 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
450 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
temporal40ee5512008-07-10 02:12:20 +0000451 }
temporal40ee5512008-07-10 02:12:20 +0000452 extension->repeated_enum_value->Add(value);
453}
454
455// -------------------------------------------------------------------
456// Strings
457
kenton@google.comd37d46d2009-04-25 02:53:47 +0000458const string& ExtensionSet::GetString(int number,
459 const string& default_value) const {
temporal40ee5512008-07-10 02:12:20 +0000460 map<int, Extension>::const_iterator iter = extensions_.find(number);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000461 if (iter == extensions_.end() || iter->second.is_cleared) {
temporal40ee5512008-07-10 02:12:20 +0000462 // Not present. Return the default value.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000463 return default_value;
temporal40ee5512008-07-10 02:12:20 +0000464 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000465 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
temporal40ee5512008-07-10 02:12:20 +0000466 return *iter->second.string_value;
467 }
468}
469
kenton@google.comfccb1462009-12-18 02:11:36 +0000470string* ExtensionSet::MutableString(int number, FieldType type,
471 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000472 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000473 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000474 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000475 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000476 extension->is_repeated = false;
temporal40ee5512008-07-10 02:12:20 +0000477 extension->string_value = new string;
478 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000479 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
temporal40ee5512008-07-10 02:12:20 +0000480 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000481 extension->is_cleared = false;
temporal40ee5512008-07-10 02:12:20 +0000482 return extension->string_value;
483}
484
485const string& ExtensionSet::GetRepeatedString(int number, int index) const {
486 map<int, Extension>::const_iterator iter = extensions_.find(number);
487 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000488 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
temporal40ee5512008-07-10 02:12:20 +0000489 return iter->second.repeated_string_value->Get(index);
490}
491
492string* ExtensionSet::MutableRepeatedString(int number, int index) {
493 map<int, Extension>::iterator iter = extensions_.find(number);
494 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000495 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
temporal40ee5512008-07-10 02:12:20 +0000496 return iter->second.repeated_string_value->Mutable(index);
497}
498
kenton@google.comfccb1462009-12-18 02:11:36 +0000499string* ExtensionSet::AddString(int number, FieldType type,
500 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000501 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000502 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000503 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000504 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000505 extension->is_repeated = true;
506 extension->is_packed = false;
temporal40ee5512008-07-10 02:12:20 +0000507 extension->repeated_string_value = new RepeatedPtrField<string>();
temporal40ee5512008-07-10 02:12:20 +0000508 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000509 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
temporal40ee5512008-07-10 02:12:20 +0000510 }
511 return extension->repeated_string_value->Add();
512}
513
514// -------------------------------------------------------------------
515// Messages
516
kenton@google.com80b1d622009-07-29 01:13:20 +0000517const MessageLite& ExtensionSet::GetMessage(
518 int number, const MessageLite& default_value) const {
temporal40ee5512008-07-10 02:12:20 +0000519 map<int, Extension>::const_iterator iter = extensions_.find(number);
520 if (iter == extensions_.end()) {
521 // Not present. Return the default value.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000522 return default_value;
temporal40ee5512008-07-10 02:12:20 +0000523 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000524 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000525 if (iter->second.is_lazy) {
526 return iter->second.lazymessage_value->GetMessage(default_value);
527 } else {
528 return *iter->second.message_value;
529 }
temporal40ee5512008-07-10 02:12:20 +0000530 }
531}
532
kenton@google.com80b1d622009-07-29 01:13:20 +0000533// Defined in extension_set_heavy.cc.
534// const MessageLite& ExtensionSet::GetMessage(int number,
535// const Descriptor* message_type,
536// MessageFactory* factory) const
kenton@google.comd37d46d2009-04-25 02:53:47 +0000537
kenton@google.com80b1d622009-07-29 01:13:20 +0000538MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000539 const MessageLite& prototype,
540 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000541 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000542 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000543 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000544 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000545 extension->is_repeated = false;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000546 extension->is_lazy = false;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000547 extension->message_value = prototype.New();
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000548 extension->is_cleared = false;
549 return extension->message_value;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000550 } else {
551 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000552 extension->is_cleared = false;
553 if (extension->is_lazy) {
554 return extension->lazymessage_value->MutableMessage(prototype);
555 } else {
556 return extension->message_value;
557 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000558 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000559}
560
kenton@google.com80b1d622009-07-29 01:13:20 +0000561// Defined in extension_set_heavy.cc.
562// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
563// const Descriptor* message_type,
564// MessageFactory* factory)
temporal40ee5512008-07-10 02:12:20 +0000565
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000566void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
567 const FieldDescriptor* descriptor,
568 MessageLite* message) {
569 if (message == NULL) {
570 ClearExtension(number);
571 return;
572 }
573 Extension* extension;
574 if (MaybeNewExtension(number, descriptor, &extension)) {
575 extension->type = type;
576 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
577 extension->is_repeated = false;
578 extension->is_lazy = false;
579 extension->message_value = message;
580 } else {
581 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
582 if (extension->is_lazy) {
583 extension->lazymessage_value->SetAllocatedMessage(message);
584 } else {
585 delete extension->message_value;
586 extension->message_value = message;
587 }
588 }
589 extension->is_cleared = false;
590}
591
592MessageLite* ExtensionSet::ReleaseMessage(int number,
593 const MessageLite& prototype) {
594 map<int, Extension>::iterator iter = extensions_.find(number);
595 if (iter == extensions_.end()) {
596 // Not present. Return NULL.
597 return NULL;
598 } else {
599 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
600 MessageLite* ret = NULL;
601 if (iter->second.is_lazy) {
602 ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
603 delete iter->second.lazymessage_value;
604 } else {
605 ret = iter->second.message_value;
606 }
607 extensions_.erase(number);
608 return ret;
609 }
610}
611
612// Defined in extension_set_heavy.cc.
613// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
614// MessageFactory* factory);
615
kenton@google.com80b1d622009-07-29 01:13:20 +0000616const MessageLite& ExtensionSet::GetRepeatedMessage(
617 int number, int index) const {
temporal40ee5512008-07-10 02:12:20 +0000618 map<int, Extension>::const_iterator iter = extensions_.find(number);
619 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000620 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
temporal40ee5512008-07-10 02:12:20 +0000621 return iter->second.repeated_message_value->Get(index);
622}
623
kenton@google.com80b1d622009-07-29 01:13:20 +0000624MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
temporal40ee5512008-07-10 02:12:20 +0000625 map<int, Extension>::iterator iter = extensions_.find(number);
626 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000627 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
temporal40ee5512008-07-10 02:12:20 +0000628 return iter->second.repeated_message_value->Mutable(index);
629}
630
kenton@google.com80b1d622009-07-29 01:13:20 +0000631MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000632 const MessageLite& prototype,
633 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000634 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000635 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000636 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000637 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000638 extension->is_repeated = true;
temporal40ee5512008-07-10 02:12:20 +0000639 extension->repeated_message_value =
kenton@google.com80b1d622009-07-29 01:13:20 +0000640 new RepeatedPtrField<MessageLite>();
temporal40ee5512008-07-10 02:12:20 +0000641 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000642 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
643 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000644
645 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
646 // allocate an abstract object, so we have to be tricky.
647 MessageLite* result = extension->repeated_message_value
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000648 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
kenton@google.com80b1d622009-07-29 01:13:20 +0000649 if (result == NULL) {
650 result = prototype.New();
651 extension->repeated_message_value->AddAllocated(result);
652 }
653 return result;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000654}
655
kenton@google.com80b1d622009-07-29 01:13:20 +0000656// Defined in extension_set_heavy.cc.
657// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
658// const Descriptor* message_type,
659// MessageFactory* factory)
temporal40ee5512008-07-10 02:12:20 +0000660
661#undef GOOGLE_DCHECK_TYPE
662
kenton@google.comceb561d2009-06-25 19:05:36 +0000663void ExtensionSet::RemoveLast(int number) {
664 map<int, Extension>::iterator iter = extensions_.find(number);
665 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
666
667 Extension* extension = &iter->second;
668 GOOGLE_DCHECK(extension->is_repeated);
669
670 switch(cpp_type(extension->type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000671 case WireFormatLite::CPPTYPE_INT32:
672 extension->repeated_int32_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000673 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000674 case WireFormatLite::CPPTYPE_INT64:
675 extension->repeated_int64_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000676 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000677 case WireFormatLite::CPPTYPE_UINT32:
678 extension->repeated_uint32_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000679 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000680 case WireFormatLite::CPPTYPE_UINT64:
681 extension->repeated_uint64_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000682 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000683 case WireFormatLite::CPPTYPE_FLOAT:
684 extension->repeated_float_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000685 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000686 case WireFormatLite::CPPTYPE_DOUBLE:
687 extension->repeated_double_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000688 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000689 case WireFormatLite::CPPTYPE_BOOL:
690 extension->repeated_bool_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000691 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000692 case WireFormatLite::CPPTYPE_ENUM:
693 extension->repeated_enum_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000694 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000695 case WireFormatLite::CPPTYPE_STRING:
696 extension->repeated_string_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000697 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000698 case WireFormatLite::CPPTYPE_MESSAGE:
699 extension->repeated_message_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000700 break;
701 }
702}
703
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000704MessageLite* ExtensionSet::ReleaseLast(int number) {
705 map<int, Extension>::iterator iter = extensions_.find(number);
706 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
707
708 Extension* extension = &iter->second;
709 GOOGLE_DCHECK(extension->is_repeated);
710 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
711 return extension->repeated_message_value->ReleaseLast();
712}
713
kenton@google.comceb561d2009-06-25 19:05:36 +0000714void ExtensionSet::SwapElements(int number, int index1, int index2) {
715 map<int, Extension>::iterator iter = extensions_.find(number);
716 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
717
718 Extension* extension = &iter->second;
719 GOOGLE_DCHECK(extension->is_repeated);
720
721 switch(cpp_type(extension->type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000722 case WireFormatLite::CPPTYPE_INT32:
kenton@google.comceb561d2009-06-25 19:05:36 +0000723 extension->repeated_int32_value->SwapElements(index1, index2);
724 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000725 case WireFormatLite::CPPTYPE_INT64:
726 extension->repeated_int64_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000727 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000728 case WireFormatLite::CPPTYPE_UINT32:
kenton@google.comceb561d2009-06-25 19:05:36 +0000729 extension->repeated_uint32_value->SwapElements(index1, index2);
730 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000731 case WireFormatLite::CPPTYPE_UINT64:
kenton@google.comceb561d2009-06-25 19:05:36 +0000732 extension->repeated_uint64_value->SwapElements(index1, index2);
733 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000734 case WireFormatLite::CPPTYPE_FLOAT:
735 extension->repeated_float_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000736 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000737 case WireFormatLite::CPPTYPE_DOUBLE:
738 extension->repeated_double_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000739 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000740 case WireFormatLite::CPPTYPE_BOOL:
741 extension->repeated_bool_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000742 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000743 case WireFormatLite::CPPTYPE_ENUM:
744 extension->repeated_enum_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000745 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000746 case WireFormatLite::CPPTYPE_STRING:
747 extension->repeated_string_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000748 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000749 case WireFormatLite::CPPTYPE_MESSAGE:
750 extension->repeated_message_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000751 break;
752 }
753}
754
temporal40ee5512008-07-10 02:12:20 +0000755// ===================================================================
756
757void ExtensionSet::Clear() {
758 for (map<int, Extension>::iterator iter = extensions_.begin();
759 iter != extensions_.end(); ++iter) {
760 iter->second.Clear();
761 }
762}
763
temporal40ee5512008-07-10 02:12:20 +0000764void ExtensionSet::MergeFrom(const ExtensionSet& other) {
temporal40ee5512008-07-10 02:12:20 +0000765 for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
766 iter != other.extensions_.end(); ++iter) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000767 const Extension& other_extension = iter->second;
768
769 if (other_extension.is_repeated) {
770 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000771 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
772 &extension);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000773 if (is_new) {
774 // Extension did not already exist in set.
775 extension->type = other_extension.type;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000776 extension->is_packed = other_extension.is_packed;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000777 extension->is_repeated = true;
778 } else {
779 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000780 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000781 GOOGLE_DCHECK(extension->is_repeated);
782 }
783
784 switch (cpp_type(other_extension.type)) {
temporal40ee5512008-07-10 02:12:20 +0000785#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
kenton@google.com80b1d622009-07-29 01:13:20 +0000786 case WireFormatLite::CPPTYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000787 if (is_new) { \
temporal40ee5512008-07-10 02:12:20 +0000788 extension->repeated_##LOWERCASE##_value = \
789 new REPEATED_TYPE; \
790 } \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000791 extension->repeated_##LOWERCASE##_value->MergeFrom( \
792 *other_extension.repeated_##LOWERCASE##_value); \
temporal40ee5512008-07-10 02:12:20 +0000793 break;
794
795 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
796 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
797 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
798 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
799 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
800 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
801 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
802 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
803 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
804#undef HANDLE_TYPE
805
kenton@google.com80b1d622009-07-29 01:13:20 +0000806 case WireFormatLite::CPPTYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +0000807 if (is_new) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000808 extension->repeated_message_value =
809 new RepeatedPtrField<MessageLite>();
temporal40ee5512008-07-10 02:12:20 +0000810 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000811 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
812 // it would attempt to allocate new objects.
813 RepeatedPtrField<MessageLite>* other_repeated_message =
814 other_extension.repeated_message_value;
815 for (int i = 0; i < other_repeated_message->size(); i++) {
816 const MessageLite& other_message = other_repeated_message->Get(i);
817 MessageLite* target = extension->repeated_message_value
818 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
819 if (target == NULL) {
820 target = other_message.New();
821 extension->repeated_message_value->AddAllocated(target);
822 }
823 target->CheckTypeAndMergeFrom(other_message);
824 }
temporal40ee5512008-07-10 02:12:20 +0000825 break;
826 }
827 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000828 if (!other_extension.is_cleared) {
829 switch (cpp_type(other_extension.type)) {
830#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +0000831 case WireFormatLite::CPPTYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000832 Set##CAMELCASE(iter->first, other_extension.type, \
kenton@google.comfccb1462009-12-18 02:11:36 +0000833 other_extension.LOWERCASE##_value, \
834 other_extension.descriptor); \
temporal40ee5512008-07-10 02:12:20 +0000835 break;
836
837 HANDLE_TYPE( INT32, int32, Int32);
838 HANDLE_TYPE( INT64, int64, Int64);
839 HANDLE_TYPE(UINT32, uint32, UInt32);
840 HANDLE_TYPE(UINT64, uint64, UInt64);
841 HANDLE_TYPE( FLOAT, float, Float);
842 HANDLE_TYPE(DOUBLE, double, Double);
843 HANDLE_TYPE( BOOL, bool, Bool);
844 HANDLE_TYPE( ENUM, enum, Enum);
845#undef HANDLE_TYPE
kenton@google.com80b1d622009-07-29 01:13:20 +0000846 case WireFormatLite::CPPTYPE_STRING:
kenton@google.comd37d46d2009-04-25 02:53:47 +0000847 SetString(iter->first, other_extension.type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000848 *other_extension.string_value,
849 other_extension.descriptor);
temporal40ee5512008-07-10 02:12:20 +0000850 break;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000851 case WireFormatLite::CPPTYPE_MESSAGE: {
852 Extension* extension;
853 bool is_new = MaybeNewExtension(iter->first,
854 other_extension.descriptor,
855 &extension);
856 if (is_new) {
857 extension->type = other_extension.type;
858 extension->is_packed = other_extension.is_packed;
859 extension->is_repeated = false;
860 if (other_extension.is_lazy) {
861 extension->is_lazy = true;
862 extension->lazymessage_value =
863 other_extension.lazymessage_value->New();
864 extension->lazymessage_value->MergeFrom(
865 *other_extension.lazymessage_value);
866 } else {
867 extension->is_lazy = false;
868 extension->message_value =
869 other_extension.message_value->New();
870 extension->message_value->CheckTypeAndMergeFrom(
871 *other_extension.message_value);
872 }
873 } else {
874 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
875 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
876 GOOGLE_DCHECK(!extension->is_repeated);
877 if (other_extension.is_lazy) {
878 if (extension->is_lazy) {
879 extension->lazymessage_value->MergeFrom(
880 *other_extension.lazymessage_value);
881 } else {
882 extension->message_value->CheckTypeAndMergeFrom(
883 other_extension.lazymessage_value->GetMessage(
884 *extension->message_value));
885 }
886 } else {
887 if (extension->is_lazy) {
888 extension->lazymessage_value->MutableMessage(
889 *other_extension.message_value)->CheckTypeAndMergeFrom(
890 *other_extension.message_value);
891 } else {
892 extension->message_value->CheckTypeAndMergeFrom(
893 *other_extension.message_value);
894 }
895 }
896 }
897 extension->is_cleared = false;
temporal40ee5512008-07-10 02:12:20 +0000898 break;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000899 }
temporal40ee5512008-07-10 02:12:20 +0000900 }
901 }
902 }
903 }
904}
905
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000906void ExtensionSet::Swap(ExtensionSet* x) {
907 extensions_.swap(x->extensions_);
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000908}
909
jieluo@google.com4de8f552014-07-18 00:47:59 +0000910void ExtensionSet::SwapExtension(ExtensionSet* other,
911 int number) {
912 if (this == other) return;
913 map<int, Extension>::iterator this_iter = extensions_.find(number);
914 map<int, Extension>::iterator other_iter = other->extensions_.find(number);
915
916 if (this_iter == extensions_.end() &&
917 other_iter == other->extensions_.end()) {
918 return;
919 }
920
921 if (this_iter != extensions_.end() &&
922 other_iter != other->extensions_.end()) {
923 std::swap(this_iter->second, other_iter->second);
924 return;
925 }
926
927 if (this_iter == extensions_.end()) {
928 extensions_.insert(make_pair(number, other_iter->second));
929 other->extensions_.erase(number);
930 return;
931 }
932
933 if (other_iter == other->extensions_.end()) {
934 other->extensions_.insert(make_pair(number, this_iter->second));
935 extensions_.erase(number);
936 return;
937 }
938}
939
temporal40ee5512008-07-10 02:12:20 +0000940bool ExtensionSet::IsInitialized() const {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000941 // Extensions are never required. However, we need to check that all
temporal40ee5512008-07-10 02:12:20 +0000942 // embedded messages are initialized.
943 for (map<int, Extension>::const_iterator iter = extensions_.begin();
944 iter != extensions_.end(); ++iter) {
945 const Extension& extension = iter->second;
kenton@google.com80b1d622009-07-29 01:13:20 +0000946 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000947 if (extension.is_repeated) {
temporal40ee5512008-07-10 02:12:20 +0000948 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
949 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
950 return false;
951 }
952 }
953 } else {
954 if (!extension.is_cleared) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000955 if (extension.is_lazy) {
956 if (!extension.lazymessage_value->IsInitialized()) return false;
957 } else {
958 if (!extension.message_value->IsInitialized()) return false;
959 }
temporal40ee5512008-07-10 02:12:20 +0000960 }
961 }
962 }
963 }
964
965 return true;
966}
967
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000968bool ExtensionSet::FindExtensionInfoFromTag(
jieluo@google.com4de8f552014-07-18 00:47:59 +0000969 uint32 tag, ExtensionFinder* extension_finder, int* field_number,
970 ExtensionInfo* extension, bool* was_packed_on_wire) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000971 *field_number = WireFormatLite::GetTagFieldNumber(tag);
kenton@google.com80b1d622009-07-29 01:13:20 +0000972 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000973 return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
974 extension_finder, extension,
975 was_packed_on_wire);
976}
temporal40ee5512008-07-10 02:12:20 +0000977
jieluo@google.com4de8f552014-07-18 00:47:59 +0000978bool ExtensionSet::FindExtensionInfoFromFieldNumber(
979 int wire_type, int field_number, ExtensionFinder* extension_finder,
980 ExtensionInfo* extension, bool* was_packed_on_wire) {
981 if (!extension_finder->Find(field_number, extension)) {
982 return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000983 }
jieluo@google.com4de8f552014-07-18 00:47:59 +0000984
985 WireFormatLite::WireType expected_wire_type =
986 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
987
988 // Check if this is a packed field.
989 *was_packed_on_wire = false;
990 if (extension->is_repeated &&
991 wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
992 is_packable(expected_wire_type)) {
993 *was_packed_on_wire = true;
994 return true;
995 }
996 // Otherwise the wire type must match.
997 return expected_wire_type == wire_type;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000998}
kenton@google.comd37d46d2009-04-25 02:53:47 +0000999
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001000bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1001 ExtensionFinder* extension_finder,
1002 FieldSkipper* field_skipper) {
1003 int number;
jieluo@google.com4de8f552014-07-18 00:47:59 +00001004 bool was_packed_on_wire;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001005 ExtensionInfo extension;
jieluo@google.com4de8f552014-07-18 00:47:59 +00001006 if (!FindExtensionInfoFromTag(
1007 tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001008 return field_skipper->SkipField(input, tag);
1009 } else {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001010 return ParseFieldWithExtensionInfo(
1011 number, was_packed_on_wire, extension, input, field_skipper);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001012 }
1013}
1014
1015bool ExtensionSet::ParseFieldWithExtensionInfo(
jieluo@google.com4de8f552014-07-18 00:47:59 +00001016 int number, bool was_packed_on_wire, const ExtensionInfo& extension,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001017 io::CodedInputStream* input,
1018 FieldSkipper* field_skipper) {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001019 // Explicitly not read extension.is_packed, instead check whether the field
1020 // was encoded in packed form on the wire.
1021 if (was_packed_on_wire) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001022 uint32 size;
1023 if (!input->ReadVarint32(&size)) return false;
1024 io::CodedInputStream::Limit limit = input->PushLimit(size);
1025
kenton@google.comfccb1462009-12-18 02:11:36 +00001026 switch (extension.type) {
1027#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001028 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001029 while (input->BytesUntilLimit() > 0) { \
1030 CPP_LOWERCASE value; \
kenton@google.comfccb1462009-12-18 02:11:36 +00001031 if (!WireFormatLite::ReadPrimitive< \
1032 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1033 input, &value)) return false; \
kenton@google.com80b1d622009-07-29 01:13:20 +00001034 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
jieluo@google.com4de8f552014-07-18 00:47:59 +00001035 extension.is_packed, value, \
1036 extension.descriptor); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001037 } \
1038 break
1039
kenton@google.comfccb1462009-12-18 02:11:36 +00001040 HANDLE_TYPE( INT32, Int32, int32);
1041 HANDLE_TYPE( INT64, Int64, int64);
1042 HANDLE_TYPE( UINT32, UInt32, uint32);
1043 HANDLE_TYPE( UINT64, UInt64, uint64);
1044 HANDLE_TYPE( SINT32, Int32, int32);
1045 HANDLE_TYPE( SINT64, Int64, int64);
1046 HANDLE_TYPE( FIXED32, UInt32, uint32);
1047 HANDLE_TYPE( FIXED64, UInt64, uint64);
1048 HANDLE_TYPE(SFIXED32, Int32, int32);
1049 HANDLE_TYPE(SFIXED64, Int64, int64);
1050 HANDLE_TYPE( FLOAT, Float, float);
1051 HANDLE_TYPE( DOUBLE, Double, double);
1052 HANDLE_TYPE( BOOL, Bool, bool);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001053#undef HANDLE_TYPE
1054
kenton@google.com80b1d622009-07-29 01:13:20 +00001055 case WireFormatLite::TYPE_ENUM:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001056 while (input->BytesUntilLimit() > 0) {
1057 int value;
kenton@google.comfccb1462009-12-18 02:11:36 +00001058 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1059 input, &value)) return false;
kenton@google.comf9c59782009-12-22 18:04:23 +00001060 if (extension.enum_validity_check.func(
1061 extension.enum_validity_check.arg, value)) {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001062 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1063 value, extension.descriptor);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001064 }
1065 }
1066 break;
1067
kenton@google.com80b1d622009-07-29 01:13:20 +00001068 case WireFormatLite::TYPE_STRING:
1069 case WireFormatLite::TYPE_BYTES:
1070 case WireFormatLite::TYPE_GROUP:
1071 case WireFormatLite::TYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001072 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1073 break;
1074 }
1075
1076 input->PopLimit(limit);
1077 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001078 switch (extension.type) {
1079#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001080 case WireFormatLite::TYPE_##UPPERCASE: { \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001081 CPP_LOWERCASE value; \
kenton@google.comfccb1462009-12-18 02:11:36 +00001082 if (!WireFormatLite::ReadPrimitive< \
1083 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1084 input, &value)) return false; \
jieluo@google.com4de8f552014-07-18 00:47:59 +00001085 if (extension.is_repeated) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001086 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
jieluo@google.com4de8f552014-07-18 00:47:59 +00001087 extension.is_packed, value, \
1088 extension.descriptor); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001089 } else { \
kenton@google.comfccb1462009-12-18 02:11:36 +00001090 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
1091 extension.descriptor); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001092 } \
1093 } break
1094
kenton@google.comfccb1462009-12-18 02:11:36 +00001095 HANDLE_TYPE( INT32, Int32, int32);
1096 HANDLE_TYPE( INT64, Int64, int64);
1097 HANDLE_TYPE( UINT32, UInt32, uint32);
1098 HANDLE_TYPE( UINT64, UInt64, uint64);
1099 HANDLE_TYPE( SINT32, Int32, int32);
1100 HANDLE_TYPE( SINT64, Int64, int64);
1101 HANDLE_TYPE( FIXED32, UInt32, uint32);
1102 HANDLE_TYPE( FIXED64, UInt64, uint64);
1103 HANDLE_TYPE(SFIXED32, Int32, int32);
1104 HANDLE_TYPE(SFIXED64, Int64, int64);
1105 HANDLE_TYPE( FLOAT, Float, float);
1106 HANDLE_TYPE( DOUBLE, Double, double);
1107 HANDLE_TYPE( BOOL, Bool, bool);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001108#undef HANDLE_TYPE
1109
kenton@google.com80b1d622009-07-29 01:13:20 +00001110 case WireFormatLite::TYPE_ENUM: {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001111 int value;
kenton@google.comfccb1462009-12-18 02:11:36 +00001112 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1113 input, &value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001114
kenton@google.comf9c59782009-12-22 18:04:23 +00001115 if (!extension.enum_validity_check.func(
1116 extension.enum_validity_check.arg, value)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001117 // Invalid value. Treat as unknown.
kenton@google.com80b1d622009-07-29 01:13:20 +00001118 field_skipper->SkipUnknownEnum(number, value);
kenton@google.comfccb1462009-12-18 02:11:36 +00001119 } else if (extension.is_repeated) {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001120 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
kenton@google.comfccb1462009-12-18 02:11:36 +00001121 extension.descriptor);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001122 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001123 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1124 extension.descriptor);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001125 }
1126 break;
1127 }
1128
kenton@google.com80b1d622009-07-29 01:13:20 +00001129 case WireFormatLite::TYPE_STRING: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001130 string* value = extension.is_repeated ?
1131 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1132 MutableString(number, WireFormatLite::TYPE_STRING,
1133 extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001134 if (!WireFormatLite::ReadString(input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001135 break;
1136 }
1137
kenton@google.com80b1d622009-07-29 01:13:20 +00001138 case WireFormatLite::TYPE_BYTES: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001139 string* value = extension.is_repeated ?
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001140 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1141 MutableString(number, WireFormatLite::TYPE_BYTES,
kenton@google.comfccb1462009-12-18 02:11:36 +00001142 extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001143 if (!WireFormatLite::ReadBytes(input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001144 break;
1145 }
1146
kenton@google.com80b1d622009-07-29 01:13:20 +00001147 case WireFormatLite::TYPE_GROUP: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001148 MessageLite* value = extension.is_repeated ?
kenton@google.com80b1d622009-07-29 01:13:20 +00001149 AddMessage(number, WireFormatLite::TYPE_GROUP,
kenton@google.comfccb1462009-12-18 02:11:36 +00001150 *extension.message_prototype, extension.descriptor) :
kenton@google.com80b1d622009-07-29 01:13:20 +00001151 MutableMessage(number, WireFormatLite::TYPE_GROUP,
kenton@google.comfccb1462009-12-18 02:11:36 +00001152 *extension.message_prototype, extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001153 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001154 break;
1155 }
1156
kenton@google.com80b1d622009-07-29 01:13:20 +00001157 case WireFormatLite::TYPE_MESSAGE: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001158 MessageLite* value = extension.is_repeated ?
kenton@google.com80b1d622009-07-29 01:13:20 +00001159 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
kenton@google.comfccb1462009-12-18 02:11:36 +00001160 *extension.message_prototype, extension.descriptor) :
kenton@google.com80b1d622009-07-29 01:13:20 +00001161 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
kenton@google.comfccb1462009-12-18 02:11:36 +00001162 *extension.message_prototype, extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001163 if (!WireFormatLite::ReadMessage(input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001164 break;
1165 }
temporal40ee5512008-07-10 02:12:20 +00001166 }
1167 }
1168
1169 return true;
1170}
1171
kenton@google.com80b1d622009-07-29 01:13:20 +00001172bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1173 const MessageLite* containing_type) {
1174 FieldSkipper skipper;
kenton@google.comfccb1462009-12-18 02:11:36 +00001175 GeneratedExtensionFinder finder(containing_type);
1176 return ParseField(tag, input, &finder, &skipper);
kenton@google.com80b1d622009-07-29 01:13:20 +00001177}
1178
jieluo@google.com4de8f552014-07-18 00:47:59 +00001179bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1180 const MessageLite* containing_type,
1181 io::CodedOutputStream* unknown_fields) {
1182 CodedOutputStreamFieldSkipper skipper(unknown_fields);
1183 GeneratedExtensionFinder finder(containing_type);
1184 return ParseField(tag, input, &finder, &skipper);
1185}
1186
kenton@google.com80b1d622009-07-29 01:13:20 +00001187// Defined in extension_set_heavy.cc.
1188// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1189// const MessageLite* containing_type,
1190// UnknownFieldSet* unknown_fields)
1191
kenton@google.com80b1d622009-07-29 01:13:20 +00001192// Defined in extension_set_heavy.cc.
1193// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1194// const MessageLite* containing_type,
1195// UnknownFieldSet* unknown_fields);
1196
kenton@google.comd37d46d2009-04-25 02:53:47 +00001197void ExtensionSet::SerializeWithCachedSizes(
1198 int start_field_number, int end_field_number,
1199 io::CodedOutputStream* output) const {
1200 map<int, Extension>::const_iterator iter;
1201 for (iter = extensions_.lower_bound(start_field_number);
1202 iter != extensions_.end() && iter->first < end_field_number;
1203 ++iter) {
1204 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1205 }
1206}
1207
kenton@google.comd37d46d2009-04-25 02:53:47 +00001208int ExtensionSet::ByteSize() const {
temporal40ee5512008-07-10 02:12:20 +00001209 int total_size = 0;
1210
1211 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1212 iter != extensions_.end(); ++iter) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001213 total_size += iter->second.ByteSize(iter->first);
temporal40ee5512008-07-10 02:12:20 +00001214 }
1215
1216 return total_size;
1217}
1218
kenton@google.com80b1d622009-07-29 01:13:20 +00001219// Defined in extension_set_heavy.cc.
1220// int ExtensionSet::SpaceUsedExcludingSelf() const
1221
kenton@google.comfccb1462009-12-18 02:11:36 +00001222bool ExtensionSet::MaybeNewExtension(int number,
1223 const FieldDescriptor* descriptor,
1224 Extension** result) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001225 pair<map<int, Extension>::iterator, bool> insert_result =
1226 extensions_.insert(make_pair(number, Extension()));
1227 *result = &insert_result.first->second;
kenton@google.comfccb1462009-12-18 02:11:36 +00001228 (*result)->descriptor = descriptor;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001229 return insert_result.second;
1230}
1231
temporal40ee5512008-07-10 02:12:20 +00001232// ===================================================================
1233// Methods of ExtensionSet::Extension
1234
1235void ExtensionSet::Extension::Clear() {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001236 if (is_repeated) {
1237 switch (cpp_type(type)) {
temporal40ee5512008-07-10 02:12:20 +00001238#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001239 case WireFormatLite::CPPTYPE_##UPPERCASE: \
temporal40ee5512008-07-10 02:12:20 +00001240 repeated_##LOWERCASE##_value->Clear(); \
1241 break
1242
1243 HANDLE_TYPE( INT32, int32);
1244 HANDLE_TYPE( INT64, int64);
1245 HANDLE_TYPE( UINT32, uint32);
1246 HANDLE_TYPE( UINT64, uint64);
1247 HANDLE_TYPE( FLOAT, float);
1248 HANDLE_TYPE( DOUBLE, double);
1249 HANDLE_TYPE( BOOL, bool);
1250 HANDLE_TYPE( ENUM, enum);
1251 HANDLE_TYPE( STRING, string);
1252 HANDLE_TYPE(MESSAGE, message);
1253#undef HANDLE_TYPE
1254 }
1255 } else {
1256 if (!is_cleared) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001257 switch (cpp_type(type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001258 case WireFormatLite::CPPTYPE_STRING:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001259 string_value->clear();
temporal40ee5512008-07-10 02:12:20 +00001260 break;
kenton@google.com80b1d622009-07-29 01:13:20 +00001261 case WireFormatLite::CPPTYPE_MESSAGE:
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001262 if (is_lazy) {
1263 lazymessage_value->Clear();
1264 } else {
1265 message_value->Clear();
1266 }
temporal40ee5512008-07-10 02:12:20 +00001267 break;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001268 default:
1269 // No need to do anything. Get*() will return the default value
1270 // as long as is_cleared is true and Set*() will overwrite the
1271 // previous value.
1272 break;
temporal40ee5512008-07-10 02:12:20 +00001273 }
1274
1275 is_cleared = true;
1276 }
1277 }
1278}
1279
kenton@google.comd37d46d2009-04-25 02:53:47 +00001280void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1281 int number,
temporal40ee5512008-07-10 02:12:20 +00001282 io::CodedOutputStream* output) const {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001283 if (is_repeated) {
1284 if (is_packed) {
1285 if (cached_size == 0) return;
1286
kenton@google.com80b1d622009-07-29 01:13:20 +00001287 WireFormatLite::WriteTag(number,
1288 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001289 output->WriteVarint32(cached_size);
1290
1291 switch (real_type(type)) {
1292#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001293 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001294 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001295 WireFormatLite::Write##CAMELCASE##NoTag( \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001296 repeated_##LOWERCASE##_value->Get(i), output); \
1297 } \
1298 break
1299
1300 HANDLE_TYPE( INT32, Int32, int32);
1301 HANDLE_TYPE( INT64, Int64, int64);
1302 HANDLE_TYPE( UINT32, UInt32, uint32);
1303 HANDLE_TYPE( UINT64, UInt64, uint64);
1304 HANDLE_TYPE( SINT32, SInt32, int32);
1305 HANDLE_TYPE( SINT64, SInt64, int64);
1306 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1307 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1308 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1309 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1310 HANDLE_TYPE( FLOAT, Float, float);
1311 HANDLE_TYPE( DOUBLE, Double, double);
1312 HANDLE_TYPE( BOOL, Bool, bool);
1313 HANDLE_TYPE( ENUM, Enum, enum);
1314#undef HANDLE_TYPE
1315
kenton@google.com80b1d622009-07-29 01:13:20 +00001316 case WireFormatLite::TYPE_STRING:
1317 case WireFormatLite::TYPE_BYTES:
1318 case WireFormatLite::TYPE_GROUP:
1319 case WireFormatLite::TYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001320 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1321 break;
1322 }
1323 } else {
1324 switch (real_type(type)) {
1325#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001326 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001327 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001328 WireFormatLite::Write##CAMELCASE(number, \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001329 repeated_##LOWERCASE##_value->Get(i), output); \
1330 } \
1331 break
1332
1333 HANDLE_TYPE( INT32, Int32, int32);
1334 HANDLE_TYPE( INT64, Int64, int64);
1335 HANDLE_TYPE( UINT32, UInt32, uint32);
1336 HANDLE_TYPE( UINT64, UInt64, uint64);
1337 HANDLE_TYPE( SINT32, SInt32, int32);
1338 HANDLE_TYPE( SINT64, SInt64, int64);
1339 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1340 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1341 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1342 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1343 HANDLE_TYPE( FLOAT, Float, float);
1344 HANDLE_TYPE( DOUBLE, Double, double);
1345 HANDLE_TYPE( BOOL, Bool, bool);
1346 HANDLE_TYPE( STRING, String, string);
1347 HANDLE_TYPE( BYTES, Bytes, string);
1348 HANDLE_TYPE( ENUM, Enum, enum);
1349 HANDLE_TYPE( GROUP, Group, message);
1350 HANDLE_TYPE( MESSAGE, Message, message);
1351#undef HANDLE_TYPE
1352 }
1353 }
1354 } else if (!is_cleared) {
1355 switch (real_type(type)) {
1356#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001357 case WireFormatLite::TYPE_##UPPERCASE: \
1358 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001359 break
1360
1361 HANDLE_TYPE( INT32, Int32, int32_value);
1362 HANDLE_TYPE( INT64, Int64, int64_value);
1363 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1364 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1365 HANDLE_TYPE( SINT32, SInt32, int32_value);
1366 HANDLE_TYPE( SINT64, SInt64, int64_value);
1367 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1368 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1369 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1370 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1371 HANDLE_TYPE( FLOAT, Float, float_value);
1372 HANDLE_TYPE( DOUBLE, Double, double_value);
1373 HANDLE_TYPE( BOOL, Bool, bool_value);
1374 HANDLE_TYPE( STRING, String, *string_value);
1375 HANDLE_TYPE( BYTES, Bytes, *string_value);
1376 HANDLE_TYPE( ENUM, Enum, enum_value);
1377 HANDLE_TYPE( GROUP, Group, *message_value);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001378#undef HANDLE_TYPE
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001379 case WireFormatLite::TYPE_MESSAGE:
1380 if (is_lazy) {
1381 lazymessage_value->WriteMessage(number, output);
1382 } else {
1383 WireFormatLite::WriteMessage(number, *message_value, output);
1384 }
1385 break;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001386 }
temporal40ee5512008-07-10 02:12:20 +00001387 }
1388}
1389
kenton@google.comd37d46d2009-04-25 02:53:47 +00001390int ExtensionSet::Extension::ByteSize(int number) const {
1391 int result = 0;
1392
1393 if (is_repeated) {
1394 if (is_packed) {
1395 switch (real_type(type)) {
1396#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001397 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001398 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001399 result += WireFormatLite::CAMELCASE##Size( \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001400 repeated_##LOWERCASE##_value->Get(i)); \
1401 } \
1402 break
1403
1404 HANDLE_TYPE( INT32, Int32, int32);
1405 HANDLE_TYPE( INT64, Int64, int64);
1406 HANDLE_TYPE( UINT32, UInt32, uint32);
1407 HANDLE_TYPE( UINT64, UInt64, uint64);
1408 HANDLE_TYPE( SINT32, SInt32, int32);
1409 HANDLE_TYPE( SINT64, SInt64, int64);
1410 HANDLE_TYPE( ENUM, Enum, enum);
1411#undef HANDLE_TYPE
1412
1413 // Stuff with fixed size.
1414#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001415 case WireFormatLite::TYPE_##UPPERCASE: \
1416 result += WireFormatLite::k##CAMELCASE##Size * \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001417 repeated_##LOWERCASE##_value->size(); \
1418 break
1419 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1420 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1421 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1422 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1423 HANDLE_TYPE( FLOAT, Float, float);
1424 HANDLE_TYPE( DOUBLE, Double, double);
1425 HANDLE_TYPE( BOOL, Bool, bool);
1426#undef HANDLE_TYPE
1427
kenton@google.com80b1d622009-07-29 01:13:20 +00001428 case WireFormatLite::TYPE_STRING:
1429 case WireFormatLite::TYPE_BYTES:
1430 case WireFormatLite::TYPE_GROUP:
1431 case WireFormatLite::TYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001432 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1433 break;
1434 }
1435
1436 cached_size = result;
1437 if (result > 0) {
1438 result += io::CodedOutputStream::VarintSize32(result);
1439 result += io::CodedOutputStream::VarintSize32(
kenton@google.com80b1d622009-07-29 01:13:20 +00001440 WireFormatLite::MakeTag(number,
1441 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001442 }
1443 } else {
kenton@google.com80b1d622009-07-29 01:13:20 +00001444 int tag_size = WireFormatLite::TagSize(number, real_type(type));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001445
1446 switch (real_type(type)) {
1447#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001448 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001449 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1450 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001451 result += WireFormatLite::CAMELCASE##Size( \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001452 repeated_##LOWERCASE##_value->Get(i)); \
1453 } \
1454 break
1455
1456 HANDLE_TYPE( INT32, Int32, int32);
1457 HANDLE_TYPE( INT64, Int64, int64);
1458 HANDLE_TYPE( UINT32, UInt32, uint32);
1459 HANDLE_TYPE( UINT64, UInt64, uint64);
1460 HANDLE_TYPE( SINT32, SInt32, int32);
1461 HANDLE_TYPE( SINT64, SInt64, int64);
1462 HANDLE_TYPE( STRING, String, string);
1463 HANDLE_TYPE( BYTES, Bytes, string);
1464 HANDLE_TYPE( ENUM, Enum, enum);
1465 HANDLE_TYPE( GROUP, Group, message);
1466 HANDLE_TYPE( MESSAGE, Message, message);
1467#undef HANDLE_TYPE
1468
1469 // Stuff with fixed size.
1470#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001471 case WireFormatLite::TYPE_##UPPERCASE: \
1472 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001473 repeated_##LOWERCASE##_value->size(); \
1474 break
1475 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1476 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1477 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1478 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1479 HANDLE_TYPE( FLOAT, Float, float);
1480 HANDLE_TYPE( DOUBLE, Double, double);
1481 HANDLE_TYPE( BOOL, Bool, bool);
1482#undef HANDLE_TYPE
1483 }
1484 }
1485 } else if (!is_cleared) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001486 result += WireFormatLite::TagSize(number, real_type(type));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001487 switch (real_type(type)) {
1488#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001489 case WireFormatLite::TYPE_##UPPERCASE: \
1490 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001491 break
1492
1493 HANDLE_TYPE( INT32, Int32, int32_value);
1494 HANDLE_TYPE( INT64, Int64, int64_value);
1495 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1496 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1497 HANDLE_TYPE( SINT32, SInt32, int32_value);
1498 HANDLE_TYPE( SINT64, SInt64, int64_value);
1499 HANDLE_TYPE( STRING, String, *string_value);
1500 HANDLE_TYPE( BYTES, Bytes, *string_value);
1501 HANDLE_TYPE( ENUM, Enum, enum_value);
1502 HANDLE_TYPE( GROUP, Group, *message_value);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001503#undef HANDLE_TYPE
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001504 case WireFormatLite::TYPE_MESSAGE: {
1505 if (is_lazy) {
1506 int size = lazymessage_value->ByteSize();
1507 result += io::CodedOutputStream::VarintSize32(size) + size;
1508 } else {
1509 result += WireFormatLite::MessageSize(*message_value);
1510 }
1511 break;
1512 }
kenton@google.comd37d46d2009-04-25 02:53:47 +00001513
1514 // Stuff with fixed size.
1515#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001516 case WireFormatLite::TYPE_##UPPERCASE: \
1517 result += WireFormatLite::k##CAMELCASE##Size; \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001518 break
1519 HANDLE_TYPE( FIXED32, Fixed32);
1520 HANDLE_TYPE( FIXED64, Fixed64);
1521 HANDLE_TYPE(SFIXED32, SFixed32);
1522 HANDLE_TYPE(SFIXED64, SFixed64);
1523 HANDLE_TYPE( FLOAT, Float);
1524 HANDLE_TYPE( DOUBLE, Double);
1525 HANDLE_TYPE( BOOL, Bool);
1526#undef HANDLE_TYPE
1527 }
temporal40ee5512008-07-10 02:12:20 +00001528 }
kenton@google.comd37d46d2009-04-25 02:53:47 +00001529
1530 return result;
temporal40ee5512008-07-10 02:12:20 +00001531}
1532
1533int ExtensionSet::Extension::GetSize() const {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001534 GOOGLE_DCHECK(is_repeated);
1535 switch (cpp_type(type)) {
temporal40ee5512008-07-10 02:12:20 +00001536#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001537 case WireFormatLite::CPPTYPE_##UPPERCASE: \
temporal40ee5512008-07-10 02:12:20 +00001538 return repeated_##LOWERCASE##_value->size()
1539
1540 HANDLE_TYPE( INT32, int32);
1541 HANDLE_TYPE( INT64, int64);
1542 HANDLE_TYPE( UINT32, uint32);
1543 HANDLE_TYPE( UINT64, uint64);
1544 HANDLE_TYPE( FLOAT, float);
1545 HANDLE_TYPE( DOUBLE, double);
1546 HANDLE_TYPE( BOOL, bool);
1547 HANDLE_TYPE( ENUM, enum);
1548 HANDLE_TYPE( STRING, string);
1549 HANDLE_TYPE(MESSAGE, message);
1550#undef HANDLE_TYPE
1551 }
1552
1553 GOOGLE_LOG(FATAL) << "Can't get here.";
1554 return 0;
1555}
1556
1557void ExtensionSet::Extension::Free() {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001558 if (is_repeated) {
1559 switch (cpp_type(type)) {
temporal40ee5512008-07-10 02:12:20 +00001560#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001561 case WireFormatLite::CPPTYPE_##UPPERCASE: \
temporal40ee5512008-07-10 02:12:20 +00001562 delete repeated_##LOWERCASE##_value; \
1563 break
1564
1565 HANDLE_TYPE( INT32, int32);
1566 HANDLE_TYPE( INT64, int64);
1567 HANDLE_TYPE( UINT32, uint32);
1568 HANDLE_TYPE( UINT64, uint64);
1569 HANDLE_TYPE( FLOAT, float);
1570 HANDLE_TYPE( DOUBLE, double);
1571 HANDLE_TYPE( BOOL, bool);
1572 HANDLE_TYPE( ENUM, enum);
1573 HANDLE_TYPE( STRING, string);
1574 HANDLE_TYPE(MESSAGE, message);
1575#undef HANDLE_TYPE
1576 }
1577 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001578 switch (cpp_type(type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001579 case WireFormatLite::CPPTYPE_STRING:
temporal40ee5512008-07-10 02:12:20 +00001580 delete string_value;
1581 break;
kenton@google.com80b1d622009-07-29 01:13:20 +00001582 case WireFormatLite::CPPTYPE_MESSAGE:
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001583 if (is_lazy) {
1584 delete lazymessage_value;
1585 } else {
1586 delete message_value;
1587 }
temporal40ee5512008-07-10 02:12:20 +00001588 break;
1589 default:
1590 break;
1591 }
1592 }
1593}
1594
kenton@google.com80b1d622009-07-29 01:13:20 +00001595// Defined in extension_set_heavy.cc.
1596// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001597
jieluo@google.com4de8f552014-07-18 00:47:59 +00001598// ==================================================================
1599// Default repeated field instances for iterator-compatible accessors
1600
1601const RepeatedStringTypeTraits::RepeatedFieldType*
1602RepeatedStringTypeTraits::default_repeated_field_ = NULL;
1603
1604const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
1605RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
1606
1607#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \
1608 const RepeatedField<TYPE>* \
1609 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
1610
1611PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
1612PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
1613PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
1614PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
1615PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
1616PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
1617PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
1618
1619#undef PROTOBUF_DEFINE_DEFAULT_REPEATED
1620
1621struct StaticDefaultRepeatedFieldsInitializer {
1622 StaticDefaultRepeatedFieldsInitializer() {
1623 InitializeDefaultRepeatedFields();
1624 }
Antoni Busztae83ba132014-10-08 11:21:04 +02001625 ~StaticDefaultRepeatedFieldsInitializer() {
1626 DestroyDefaultRepeatedFields();
1627 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001628} static_repeated_fields_initializer;
1629
1630void InitializeDefaultRepeatedFields() {
1631 RepeatedStringTypeTraits::default_repeated_field_ =
1632 new RepeatedStringTypeTraits::RepeatedFieldType;
1633 RepeatedMessageGenericTypeTraits::default_repeated_field_ =
1634 new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
1635 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
1636 new RepeatedField<int32>;
1637 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
1638 new RepeatedField<int64>;
1639 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
1640 new RepeatedField<uint32>;
1641 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
1642 new RepeatedField<uint64>;
1643 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
1644 new RepeatedField<double>;
1645 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
1646 new RepeatedField<float>;
1647 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
1648 new RepeatedField<bool>;
1649}
1650
Antoni Busztae83ba132014-10-08 11:21:04 +02001651void DestroyDefaultRepeatedFields() {
1652 delete RepeatedStringTypeTraits::default_repeated_field_;
1653 delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
1654 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
1655 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
1656 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
1657 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
1658 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
1659 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
1660 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
1661}
1662
temporal40ee5512008-07-10 02:12:20 +00001663} // namespace internal
1664} // namespace protobuf
1665} // namespace google