blob: 03b38dd0117de9137daf3e2c6514d43fd2dd94e7 [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 }
Feng Xiao9173ba22014-12-02 15:28:11 -080074 GOOGLE_LOG(FATAL) << "can't reach here.";
75 return false;
jieluo@google.com4de8f552014-07-18 00:47:59 +000076}
77
kenton@google.comd37d46d2009-04-25 02:53:47 +000078// Registry stuff.
kenton@google.com80b1d622009-07-29 01:13:20 +000079typedef hash_map<pair<const MessageLite*, int>,
80 ExtensionInfo> ExtensionRegistry;
kenton@google.comd37d46d2009-04-25 02:53:47 +000081ExtensionRegistry* registry_ = NULL;
temporalbdbb8632009-12-18 08:21:00 +000082GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
kenton@google.com63e646b2009-05-06 19:27:03 +000083
84void DeleteRegistry() {
85 delete registry_;
86 registry_ = NULL;
87}
88
89void InitRegistry() {
90 registry_ = new ExtensionRegistry;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000091 OnShutdown(&DeleteRegistry);
kenton@google.com63e646b2009-05-06 19:27:03 +000092}
kenton@google.comd37d46d2009-04-25 02:53:47 +000093
94// This function is only called at startup, so there is no need for thread-
95// safety.
kenton@google.com80b1d622009-07-29 01:13:20 +000096void Register(const MessageLite* containing_type,
97 int number, ExtensionInfo info) {
98 ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
kenton@google.comd37d46d2009-04-25 02:53:47 +000099
Jisi Liu885b6122015-02-28 14:51:22 -0800100 if (!InsertIfNotPresent(registry_, std::make_pair(containing_type, number),
kenton@google.comd37d46d2009-04-25 02:53:47 +0000101 info)) {
102 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
kenton@google.com80b1d622009-07-29 01:13:20 +0000103 << containing_type->GetTypeName()
kenton@google.comd37d46d2009-04-25 02:53:47 +0000104 << "\", field number " << number << ".";
105 }
106}
107
108const ExtensionInfo* FindRegisteredExtension(
kenton@google.com80b1d622009-07-29 01:13:20 +0000109 const MessageLite* containing_type, int number) {
Jisi Liu885b6122015-02-28 14:51:22 -0800110 return (registry_ == NULL)
111 ? NULL
112 : FindOrNull(*registry_, std::make_pair(containing_type, number));
kenton@google.comd37d46d2009-04-25 02:53:47 +0000113}
114
115} // namespace
116
kenton@google.comfccb1462009-12-18 02:11:36 +0000117ExtensionFinder::~ExtensionFinder() {}
118
119bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
120 const ExtensionInfo* extension =
121 FindRegisteredExtension(containing_type_, number);
122 if (extension == NULL) {
123 return false;
124 } else {
125 *output = *extension;
126 return true;
127 }
128}
129
kenton@google.com80b1d622009-07-29 01:13:20 +0000130void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000131 int number, FieldType type,
132 bool is_repeated, bool is_packed) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000133 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
134 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
135 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000136 ExtensionInfo info(type, is_repeated, is_packed);
137 Register(containing_type, number, info);
138}
139
kenton@google.comfccb1462009-12-18 02:11:36 +0000140static bool CallNoArgValidityFunc(const void* arg, int number) {
kenton@google.com91218af2009-12-18 07:20:43 +0000141 // 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
kenton@google.comf2a73292009-12-21 19:44:57 +0000148 // Also note: Some compilers do not allow function pointers to be "const".
149 // Which makes sense, I suppose, because it's meaningless.
150 return ((EnumValidityFunc*)arg)(number);
kenton@google.comfccb1462009-12-18 02:11:36 +0000151}
152
kenton@google.com80b1d622009-07-29 01:13:20 +0000153void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000154 int number, FieldType type,
155 bool is_repeated, bool is_packed,
156 EnumValidityFunc* is_valid) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000157 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000158 ExtensionInfo info(type, is_repeated, is_packed);
kenton@google.comf9c59782009-12-22 18:04:23 +0000159 info.enum_validity_check.func = CallNoArgValidityFunc;
kenton@google.com91218af2009-12-18 07:20:43 +0000160 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
kenton@google.comf9c59782009-12-22 18:04:23 +0000161 info.enum_validity_check.arg = (void*)is_valid;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000162 Register(containing_type, number, info);
163}
164
kenton@google.com80b1d622009-07-29 01:13:20 +0000165void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000166 int number, FieldType type,
167 bool is_repeated, bool is_packed,
kenton@google.com80b1d622009-07-29 01:13:20 +0000168 const MessageLite* prototype) {
169 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
170 type == WireFormatLite::TYPE_GROUP);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000171 ExtensionInfo info(type, is_repeated, is_packed);
172 info.message_prototype = prototype;
173 Register(containing_type, number, info);
temporal40ee5512008-07-10 02:12:20 +0000174}
175
kenton@google.com80b1d622009-07-29 01:13:20 +0000176
temporal40ee5512008-07-10 02:12:20 +0000177// ===================================================================
178// Constructors and basic methods.
179
Feng Xiao6ef984a2014-11-10 17:34:54 -0800180ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena) : arena_(arena) {
181 if (arena_ != NULL) {
182 arena_->OwnDestructor(&extensions_);
183 }
184}
185
186ExtensionSet::ExtensionSet() : arena_(NULL) {}
temporal40ee5512008-07-10 02:12:20 +0000187
188ExtensionSet::~ExtensionSet() {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800189 // Deletes all allocated extensions.
190 if (arena_ == NULL) {
191 for (map<int, Extension>::iterator iter = extensions_.begin();
192 iter != extensions_.end(); ++iter) {
193 iter->second.Free();
194 }
temporal40ee5512008-07-10 02:12:20 +0000195 }
196}
197
kenton@google.com80b1d622009-07-29 01:13:20 +0000198// Defined in extension_set_heavy.cc.
199// void ExtensionSet::AppendToList(const Descriptor* containing_type,
200// const DescriptorPool* pool,
201// vector<const FieldDescriptor*>* output) const
temporal40ee5512008-07-10 02:12:20 +0000202
203bool ExtensionSet::Has(int number) const {
204 map<int, Extension>::const_iterator iter = extensions_.find(number);
205 if (iter == extensions_.end()) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000206 GOOGLE_DCHECK(!iter->second.is_repeated);
temporal40ee5512008-07-10 02:12:20 +0000207 return !iter->second.is_cleared;
208}
209
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000210int ExtensionSet::NumExtensions() const {
211 int result = 0;
212 for (map<int, Extension>::const_iterator iter = extensions_.begin();
213 iter != extensions_.end(); ++iter) {
214 if (!iter->second.is_cleared) {
215 ++result;
216 }
217 }
218 return result;
219}
220
temporal40ee5512008-07-10 02:12:20 +0000221int ExtensionSet::ExtensionSize(int number) const {
222 map<int, Extension>::const_iterator iter = extensions_.find(number);
223 if (iter == extensions_.end()) return false;
224 return iter->second.GetSize();
225}
226
liujisi@google.com33165fe2010-11-02 13:14:58 +0000227FieldType ExtensionSet::ExtensionType(int number) const {
228 map<int, Extension>::const_iterator iter = extensions_.find(number);
229 if (iter == extensions_.end()) {
230 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
231 return 0;
232 }
233 if (iter->second.is_cleared) {
234 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
235 }
236 return iter->second.type;
237}
238
temporal40ee5512008-07-10 02:12:20 +0000239void ExtensionSet::ClearExtension(int number) {
240 map<int, Extension>::iterator iter = extensions_.find(number);
241 if (iter == extensions_.end()) return;
242 iter->second.Clear();
243}
244
245// ===================================================================
246// Field accessors
247
kenton@google.com80b1d622009-07-29 01:13:20 +0000248namespace {
249
250enum 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)
temporal40ee5512008-07-10 02:12:20 +0000260
261// -------------------------------------------------------------------
262// Primitives
263
264#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
265 \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000266LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
267 LOWERCASE default_value) const { \
temporal40ee5512008-07-10 02:12:20 +0000268 map<int, Extension>::const_iterator iter = extensions_.find(number); \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000269 if (iter == extensions_.end() || iter->second.is_cleared) { \
270 return default_value; \
temporal40ee5512008-07-10 02:12:20 +0000271 } else { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000272 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000273 return iter->second.LOWERCASE##_value; \
274 } \
275} \
276 \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000277void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
kenton@google.comfccb1462009-12-18 02:11:36 +0000278 LOWERCASE value, \
279 const FieldDescriptor* descriptor) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000280 Extension* extension; \
kenton@google.comfccb1462009-12-18 02:11:36 +0000281 if (MaybeNewExtension(number, descriptor, &extension)) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000282 extension->type = type; \
kenton@google.com80b1d622009-07-29 01:13:20 +0000283 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000284 extension->is_repeated = false; \
temporal40ee5512008-07-10 02:12:20 +0000285 } else { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000286 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000287 } \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000288 extension->is_cleared = false; \
temporal40ee5512008-07-10 02:12:20 +0000289 extension->LOWERCASE##_value = value; \
290} \
291 \
292LOWERCASE 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)."; \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000295 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000296 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
297} \
298 \
299void 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)."; \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000303 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
temporal40ee5512008-07-10 02:12:20 +0000304 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
305} \
306 \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000307void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
kenton@google.comfccb1462009-12-18 02:11:36 +0000308 bool packed, LOWERCASE value, \
309 const FieldDescriptor* descriptor) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000310 Extension* extension; \
kenton@google.comfccb1462009-12-18 02:11:36 +0000311 if (MaybeNewExtension(number, descriptor, &extension)) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000312 extension->type = type; \
kenton@google.com80b1d622009-07-29 01:13:20 +0000313 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000314 extension->is_repeated = true; \
315 extension->is_packed = packed; \
Feng Xiao6ef984a2014-11-10 17:34:54 -0800316 extension->repeated_##LOWERCASE##_value = \
317 Arena::Create<RepeatedField<LOWERCASE> >(arena_, arena_); \
temporal40ee5512008-07-10 02:12:20 +0000318 } else { \
kenton@google.comd37d46d2009-04-25 02:53:47 +0000319 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
320 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
temporal40ee5512008-07-10 02:12:20 +0000321 } \
322 extension->repeated_##LOWERCASE##_value->Add(value); \
323}
324
325PRIMITIVE_ACCESSORS( INT32, int32, Int32)
326PRIMITIVE_ACCESSORS( INT64, int64, Int64)
327PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
328PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
329PRIMITIVE_ACCESSORS( FLOAT, float, Float)
330PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
331PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
332
333#undef PRIMITIVE_ACCESSORS
334
jieluo@google.com4de8f552014-07-18 00:47:59 +0000335const void* ExtensionSet::GetRawRepeatedField(int number,
336 const void* default_value) const {
337 map<int, Extension>::const_iterator iter = extensions_.find(number);
338 if (iter == extensions_.end()) {
339 return default_value;
340 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000341 // We assume that all the RepeatedField<>* pointers have the same
342 // size and alignment within the anonymous union in Extension.
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000343 return iter->second.repeated_int32_value;
344}
345
jieluo@google.com4de8f552014-07-18 00:47:59 +0000346void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
347 bool packed,
348 const FieldDescriptor* desc) {
349 Extension* extension;
350
351 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
352 // extension.
353 if (MaybeNewExtension(number, desc, &extension)) {
354 extension->is_repeated = true;
355 extension->type = field_type;
356 extension->is_packed = packed;
357
358 switch (WireFormatLite::FieldTypeToCppType(
359 static_cast<WireFormatLite::FieldType>(field_type))) {
360 case WireFormatLite::CPPTYPE_INT32:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800361 extension->repeated_int32_value =
362 Arena::Create<RepeatedField<int32> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000363 break;
364 case WireFormatLite::CPPTYPE_INT64:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800365 extension->repeated_int64_value =
366 Arena::Create<RepeatedField<int64> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000367 break;
368 case WireFormatLite::CPPTYPE_UINT32:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800369 extension->repeated_uint32_value =
370 Arena::Create<RepeatedField<uint32> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000371 break;
372 case WireFormatLite::CPPTYPE_UINT64:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800373 extension->repeated_uint64_value =
374 Arena::Create<RepeatedField<uint64> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000375 break;
376 case WireFormatLite::CPPTYPE_DOUBLE:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800377 extension->repeated_double_value =
378 Arena::Create<RepeatedField<double> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000379 break;
380 case WireFormatLite::CPPTYPE_FLOAT:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800381 extension->repeated_float_value =
382 Arena::Create<RepeatedField<float> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000383 break;
384 case WireFormatLite::CPPTYPE_BOOL:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800385 extension->repeated_bool_value =
386 Arena::Create<RepeatedField<bool> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000387 break;
388 case WireFormatLite::CPPTYPE_ENUM:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800389 extension->repeated_enum_value =
390 Arena::Create<RepeatedField<int> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000391 break;
392 case WireFormatLite::CPPTYPE_STRING:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800393 extension->repeated_string_value =
394 Arena::Create<RepeatedPtrField< ::std::string> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000395 break;
396 case WireFormatLite::CPPTYPE_MESSAGE:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800397 extension->repeated_message_value =
398 Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000399 break;
400 }
401 }
402
403 // We assume that all the RepeatedField<>* pointers have the same
404 // size and alignment within the anonymous union in Extension.
405 return extension->repeated_int32_value;
406}
407
408// Compatible version using old call signature. Does not create extensions when
409// the don't already exist; instead, just GOOGLE_CHECK-fails.
410void* ExtensionSet::MutableRawRepeatedField(int number) {
411 map<int, Extension>::iterator iter = extensions_.find(number);
412 GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
413 // We assume that all the RepeatedField<>* pointers have the same
414 // size and alignment within the anonymous union in Extension.
415 return iter->second.repeated_int32_value;
416}
417
418
temporal40ee5512008-07-10 02:12:20 +0000419// -------------------------------------------------------------------
420// Enums
421
kenton@google.comd37d46d2009-04-25 02:53:47 +0000422int ExtensionSet::GetEnum(int number, int default_value) const {
temporal40ee5512008-07-10 02:12:20 +0000423 map<int, Extension>::const_iterator iter = extensions_.find(number);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000424 if (iter == extensions_.end() || iter->second.is_cleared) {
temporal40ee5512008-07-10 02:12:20 +0000425 // Not present. Return the default value.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000426 return default_value;
temporal40ee5512008-07-10 02:12:20 +0000427 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000428 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000429 return iter->second.enum_value;
430 }
431}
432
kenton@google.comfccb1462009-12-18 02:11:36 +0000433void ExtensionSet::SetEnum(int number, FieldType type, int value,
434 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000435 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000436 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000437 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000438 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000439 extension->is_repeated = false;
temporal40ee5512008-07-10 02:12:20 +0000440 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000441 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000442 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000443 extension->is_cleared = false;
temporal40ee5512008-07-10 02:12:20 +0000444 extension->enum_value = value;
445}
446
447int ExtensionSet::GetRepeatedEnum(int number, int index) const {
448 map<int, Extension>::const_iterator iter = extensions_.find(number);
449 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000450 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000451 return iter->second.repeated_enum_value->Get(index);
452}
453
454void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
455 map<int, Extension>::iterator iter = extensions_.find(number);
456 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000457 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
temporal40ee5512008-07-10 02:12:20 +0000458 iter->second.repeated_enum_value->Set(index, value);
459}
460
kenton@google.comd37d46d2009-04-25 02:53:47 +0000461void ExtensionSet::AddEnum(int number, FieldType type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000462 bool packed, int value,
463 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000464 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000465 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000466 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000467 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000468 extension->is_repeated = true;
469 extension->is_packed = packed;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800470 extension->repeated_enum_value =
471 Arena::Create<RepeatedField<int> >(arena_, arena_);
temporal40ee5512008-07-10 02:12:20 +0000472 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000473 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
474 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
temporal40ee5512008-07-10 02:12:20 +0000475 }
temporal40ee5512008-07-10 02:12:20 +0000476 extension->repeated_enum_value->Add(value);
477}
478
479// -------------------------------------------------------------------
480// Strings
481
kenton@google.comd37d46d2009-04-25 02:53:47 +0000482const string& ExtensionSet::GetString(int number,
483 const string& default_value) const {
temporal40ee5512008-07-10 02:12:20 +0000484 map<int, Extension>::const_iterator iter = extensions_.find(number);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000485 if (iter == extensions_.end() || iter->second.is_cleared) {
temporal40ee5512008-07-10 02:12:20 +0000486 // Not present. Return the default value.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000487 return default_value;
temporal40ee5512008-07-10 02:12:20 +0000488 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000489 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
temporal40ee5512008-07-10 02:12:20 +0000490 return *iter->second.string_value;
491 }
492}
493
kenton@google.comfccb1462009-12-18 02:11:36 +0000494string* ExtensionSet::MutableString(int number, FieldType type,
495 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000496 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000497 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000498 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000499 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000500 extension->is_repeated = false;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800501 extension->string_value = Arena::Create<string>(arena_);
temporal40ee5512008-07-10 02:12:20 +0000502 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000503 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
temporal40ee5512008-07-10 02:12:20 +0000504 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000505 extension->is_cleared = false;
temporal40ee5512008-07-10 02:12:20 +0000506 return extension->string_value;
507}
508
509const string& ExtensionSet::GetRepeatedString(int number, int index) const {
510 map<int, Extension>::const_iterator iter = extensions_.find(number);
511 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000512 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
temporal40ee5512008-07-10 02:12:20 +0000513 return iter->second.repeated_string_value->Get(index);
514}
515
516string* ExtensionSet::MutableRepeatedString(int number, int index) {
517 map<int, Extension>::iterator iter = extensions_.find(number);
518 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000519 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
temporal40ee5512008-07-10 02:12:20 +0000520 return iter->second.repeated_string_value->Mutable(index);
521}
522
kenton@google.comfccb1462009-12-18 02:11:36 +0000523string* ExtensionSet::AddString(int number, FieldType type,
524 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000525 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000526 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000527 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000528 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000529 extension->is_repeated = true;
530 extension->is_packed = false;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800531 extension->repeated_string_value =
532 Arena::Create<RepeatedPtrField<string> >(arena_, arena_);
temporal40ee5512008-07-10 02:12:20 +0000533 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000534 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
temporal40ee5512008-07-10 02:12:20 +0000535 }
536 return extension->repeated_string_value->Add();
537}
538
539// -------------------------------------------------------------------
540// Messages
541
kenton@google.com80b1d622009-07-29 01:13:20 +0000542const MessageLite& ExtensionSet::GetMessage(
543 int number, const MessageLite& default_value) const {
temporal40ee5512008-07-10 02:12:20 +0000544 map<int, Extension>::const_iterator iter = extensions_.find(number);
545 if (iter == extensions_.end()) {
546 // Not present. Return the default value.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000547 return default_value;
temporal40ee5512008-07-10 02:12:20 +0000548 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000549 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000550 if (iter->second.is_lazy) {
551 return iter->second.lazymessage_value->GetMessage(default_value);
552 } else {
553 return *iter->second.message_value;
554 }
temporal40ee5512008-07-10 02:12:20 +0000555 }
556}
557
kenton@google.com80b1d622009-07-29 01:13:20 +0000558// Defined in extension_set_heavy.cc.
559// const MessageLite& ExtensionSet::GetMessage(int number,
560// const Descriptor* message_type,
561// MessageFactory* factory) const
kenton@google.comd37d46d2009-04-25 02:53:47 +0000562
kenton@google.com80b1d622009-07-29 01:13:20 +0000563MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000564 const MessageLite& prototype,
565 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000566 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000567 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000568 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000569 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000570 extension->is_repeated = false;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000571 extension->is_lazy = false;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800572 extension->message_value = prototype.New(arena_);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000573 extension->is_cleared = false;
574 return extension->message_value;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000575 } else {
576 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000577 extension->is_cleared = false;
578 if (extension->is_lazy) {
579 return extension->lazymessage_value->MutableMessage(prototype);
580 } else {
581 return extension->message_value;
582 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000583 }
kenton@google.comd37d46d2009-04-25 02:53:47 +0000584}
585
kenton@google.com80b1d622009-07-29 01:13:20 +0000586// Defined in extension_set_heavy.cc.
587// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
588// const Descriptor* message_type,
589// MessageFactory* factory)
temporal40ee5512008-07-10 02:12:20 +0000590
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000591void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
592 const FieldDescriptor* descriptor,
593 MessageLite* message) {
594 if (message == NULL) {
595 ClearExtension(number);
596 return;
597 }
598 Extension* extension;
599 if (MaybeNewExtension(number, descriptor, &extension)) {
600 extension->type = type;
601 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
602 extension->is_repeated = false;
603 extension->is_lazy = false;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800604 if (message->GetArena() == arena_) {
605 extension->message_value = message;
606 } else {
607 extension->message_value = message->New(arena_);
608 extension->message_value->CheckTypeAndMergeFrom(*message);
609 if (message->GetArena() == NULL) {
610 delete message;
611 }
612 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000613 } else {
614 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
615 if (extension->is_lazy) {
616 extension->lazymessage_value->SetAllocatedMessage(message);
617 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800618 if (arena_ == NULL) {
619 delete extension->message_value;
620 }
621 if (message->GetArena() == arena_) {
622 extension->message_value = message;
623 } else {
624 extension->message_value = message->New(arena_);
625 extension->message_value->CheckTypeAndMergeFrom(*message);
626 if (message->GetArena() == NULL) {
627 delete message;
628 }
629 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000630 }
631 }
632 extension->is_cleared = false;
633}
634
635MessageLite* ExtensionSet::ReleaseMessage(int number,
636 const MessageLite& prototype) {
637 map<int, Extension>::iterator iter = extensions_.find(number);
638 if (iter == extensions_.end()) {
639 // Not present. Return NULL.
640 return NULL;
641 } else {
642 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
643 MessageLite* ret = NULL;
644 if (iter->second.is_lazy) {
645 ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800646 if (arena_ == NULL) {
647 delete iter->second.lazymessage_value;
648 }
649 } else {
650 if (arena_ == NULL) {
651 ret = iter->second.message_value;
652 } else {
653 // ReleaseMessage() always returns a heap-allocated message, and we are
654 // on an arena, so we need to make a copy of this message to return.
655 ret = (iter->second.message_value)->New();
656 ret->CheckTypeAndMergeFrom(*iter->second.message_value);
657 }
658 }
659 extensions_.erase(number);
660 return ret;
661 }
662}
663
664MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
665 int number, const MessageLite& prototype) {
666 map<int, Extension>::iterator iter = extensions_.find(number);
667 if (iter == extensions_.end()) {
668 // Not present. Return NULL.
669 return NULL;
670 } else {
671 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
672 MessageLite* ret = NULL;
673 if (iter->second.is_lazy) {
674 ret =
675 iter->second.lazymessage_value->UnsafeArenaReleaseMessage(prototype);
676 if (arena_ == NULL) {
677 delete iter->second.lazymessage_value;
678 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000679 } else {
680 ret = iter->second.message_value;
681 }
682 extensions_.erase(number);
683 return ret;
684 }
685}
686
687// Defined in extension_set_heavy.cc.
688// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
689// MessageFactory* factory);
690
kenton@google.com80b1d622009-07-29 01:13:20 +0000691const MessageLite& ExtensionSet::GetRepeatedMessage(
692 int number, int index) const {
temporal40ee5512008-07-10 02:12:20 +0000693 map<int, Extension>::const_iterator iter = extensions_.find(number);
694 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000695 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
temporal40ee5512008-07-10 02:12:20 +0000696 return iter->second.repeated_message_value->Get(index);
697}
698
kenton@google.com80b1d622009-07-29 01:13:20 +0000699MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
temporal40ee5512008-07-10 02:12:20 +0000700 map<int, Extension>::iterator iter = extensions_.find(number);
701 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
kenton@google.comd37d46d2009-04-25 02:53:47 +0000702 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
temporal40ee5512008-07-10 02:12:20 +0000703 return iter->second.repeated_message_value->Mutable(index);
704}
705
kenton@google.com80b1d622009-07-29 01:13:20 +0000706MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
kenton@google.comfccb1462009-12-18 02:11:36 +0000707 const MessageLite& prototype,
708 const FieldDescriptor* descriptor) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000709 Extension* extension;
kenton@google.comfccb1462009-12-18 02:11:36 +0000710 if (MaybeNewExtension(number, descriptor, &extension)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000711 extension->type = type;
kenton@google.com80b1d622009-07-29 01:13:20 +0000712 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000713 extension->is_repeated = true;
temporal40ee5512008-07-10 02:12:20 +0000714 extension->repeated_message_value =
Feng Xiao6ef984a2014-11-10 17:34:54 -0800715 Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_);
temporal40ee5512008-07-10 02:12:20 +0000716 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000717 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
718 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000719
720 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
721 // allocate an abstract object, so we have to be tricky.
722 MessageLite* result = extension->repeated_message_value
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000723 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
kenton@google.com80b1d622009-07-29 01:13:20 +0000724 if (result == NULL) {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800725 result = prototype.New(arena_);
kenton@google.com80b1d622009-07-29 01:13:20 +0000726 extension->repeated_message_value->AddAllocated(result);
727 }
728 return result;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000729}
730
kenton@google.com80b1d622009-07-29 01:13:20 +0000731// Defined in extension_set_heavy.cc.
732// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
733// const Descriptor* message_type,
734// MessageFactory* factory)
temporal40ee5512008-07-10 02:12:20 +0000735
736#undef GOOGLE_DCHECK_TYPE
737
kenton@google.comceb561d2009-06-25 19:05:36 +0000738void ExtensionSet::RemoveLast(int number) {
739 map<int, Extension>::iterator iter = extensions_.find(number);
740 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
741
742 Extension* extension = &iter->second;
743 GOOGLE_DCHECK(extension->is_repeated);
744
745 switch(cpp_type(extension->type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000746 case WireFormatLite::CPPTYPE_INT32:
747 extension->repeated_int32_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000748 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000749 case WireFormatLite::CPPTYPE_INT64:
750 extension->repeated_int64_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000751 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000752 case WireFormatLite::CPPTYPE_UINT32:
753 extension->repeated_uint32_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000754 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000755 case WireFormatLite::CPPTYPE_UINT64:
756 extension->repeated_uint64_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000757 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000758 case WireFormatLite::CPPTYPE_FLOAT:
759 extension->repeated_float_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000760 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000761 case WireFormatLite::CPPTYPE_DOUBLE:
762 extension->repeated_double_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000763 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000764 case WireFormatLite::CPPTYPE_BOOL:
765 extension->repeated_bool_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000766 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000767 case WireFormatLite::CPPTYPE_ENUM:
768 extension->repeated_enum_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000769 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000770 case WireFormatLite::CPPTYPE_STRING:
771 extension->repeated_string_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000772 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000773 case WireFormatLite::CPPTYPE_MESSAGE:
774 extension->repeated_message_value->RemoveLast();
kenton@google.comceb561d2009-06-25 19:05:36 +0000775 break;
776 }
777}
778
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000779MessageLite* ExtensionSet::ReleaseLast(int number) {
780 map<int, Extension>::iterator iter = extensions_.find(number);
781 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
782
783 Extension* extension = &iter->second;
784 GOOGLE_DCHECK(extension->is_repeated);
785 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
786 return extension->repeated_message_value->ReleaseLast();
787}
788
kenton@google.comceb561d2009-06-25 19:05:36 +0000789void ExtensionSet::SwapElements(int number, int index1, int index2) {
790 map<int, Extension>::iterator iter = extensions_.find(number);
791 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
792
793 Extension* extension = &iter->second;
794 GOOGLE_DCHECK(extension->is_repeated);
795
796 switch(cpp_type(extension->type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000797 case WireFormatLite::CPPTYPE_INT32:
kenton@google.comceb561d2009-06-25 19:05:36 +0000798 extension->repeated_int32_value->SwapElements(index1, index2);
799 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000800 case WireFormatLite::CPPTYPE_INT64:
801 extension->repeated_int64_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000802 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000803 case WireFormatLite::CPPTYPE_UINT32:
kenton@google.comceb561d2009-06-25 19:05:36 +0000804 extension->repeated_uint32_value->SwapElements(index1, index2);
805 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000806 case WireFormatLite::CPPTYPE_UINT64:
kenton@google.comceb561d2009-06-25 19:05:36 +0000807 extension->repeated_uint64_value->SwapElements(index1, index2);
808 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000809 case WireFormatLite::CPPTYPE_FLOAT:
810 extension->repeated_float_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000811 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000812 case WireFormatLite::CPPTYPE_DOUBLE:
813 extension->repeated_double_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000814 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000815 case WireFormatLite::CPPTYPE_BOOL:
816 extension->repeated_bool_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000817 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000818 case WireFormatLite::CPPTYPE_ENUM:
819 extension->repeated_enum_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000820 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000821 case WireFormatLite::CPPTYPE_STRING:
822 extension->repeated_string_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000823 break;
kenton@google.com80b1d622009-07-29 01:13:20 +0000824 case WireFormatLite::CPPTYPE_MESSAGE:
825 extension->repeated_message_value->SwapElements(index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000826 break;
827 }
828}
829
temporal40ee5512008-07-10 02:12:20 +0000830// ===================================================================
831
832void ExtensionSet::Clear() {
833 for (map<int, Extension>::iterator iter = extensions_.begin();
834 iter != extensions_.end(); ++iter) {
835 iter->second.Clear();
836 }
837}
838
temporal40ee5512008-07-10 02:12:20 +0000839void ExtensionSet::MergeFrom(const ExtensionSet& other) {
temporal40ee5512008-07-10 02:12:20 +0000840 for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
841 iter != other.extensions_.end(); ++iter) {
kenton@google.comd37d46d2009-04-25 02:53:47 +0000842 const Extension& other_extension = iter->second;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800843 InternalExtensionMergeFrom(iter->first, other_extension);
844 }
845}
kenton@google.comd37d46d2009-04-25 02:53:47 +0000846
Feng Xiao6ef984a2014-11-10 17:34:54 -0800847void ExtensionSet::InternalExtensionMergeFrom(
848 int number, const Extension& other_extension) {
849 if (other_extension.is_repeated) {
850 Extension* extension;
851 bool is_new = MaybeNewExtension(number, other_extension.descriptor,
852 &extension);
853 if (is_new) {
854 // Extension did not already exist in set.
855 extension->type = other_extension.type;
856 extension->is_packed = other_extension.is_packed;
857 extension->is_repeated = true;
temporal40ee5512008-07-10 02:12:20 +0000858 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800859 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
860 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
861 GOOGLE_DCHECK(extension->is_repeated);
862 }
temporal40ee5512008-07-10 02:12:20 +0000863
Feng Xiao6ef984a2014-11-10 17:34:54 -0800864 switch (cpp_type(other_extension.type)) {
865#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
866 case WireFormatLite::CPPTYPE_##UPPERCASE: \
867 if (is_new) { \
868 extension->repeated_##LOWERCASE##_value = \
869 Arena::Create<REPEATED_TYPE >(arena_, arena_); \
870 } \
871 extension->repeated_##LOWERCASE##_value->MergeFrom( \
872 *other_extension.repeated_##LOWERCASE##_value); \
873 break;
874
875 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
876 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
877 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
878 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
879 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
880 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
881 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
882 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
883 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
temporal40ee5512008-07-10 02:12:20 +0000884#undef HANDLE_TYPE
Feng Xiao6ef984a2014-11-10 17:34:54 -0800885
886 case WireFormatLite::CPPTYPE_MESSAGE:
887 if (is_new) {
888 extension->repeated_message_value =
889 Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_);
890 }
891 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
892 // it would attempt to allocate new objects.
893 RepeatedPtrField<MessageLite>* other_repeated_message =
894 other_extension.repeated_message_value;
895 for (int i = 0; i < other_repeated_message->size(); i++) {
896 const MessageLite& other_message = other_repeated_message->Get(i);
897 MessageLite* target = extension->repeated_message_value
898 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
899 if (target == NULL) {
900 target = other_message.New(arena_);
901 extension->repeated_message_value->AddAllocated(target);
902 }
903 target->CheckTypeAndMergeFrom(other_message);
904 }
905 break;
906 }
907 } else {
908 if (!other_extension.is_cleared) {
909 switch (cpp_type(other_extension.type)) {
910#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
911 case WireFormatLite::CPPTYPE_##UPPERCASE: \
912 Set##CAMELCASE(number, other_extension.type, \
913 other_extension.LOWERCASE##_value, \
914 other_extension.descriptor); \
915 break;
916
917 HANDLE_TYPE( INT32, int32, Int32);
918 HANDLE_TYPE( INT64, int64, Int64);
919 HANDLE_TYPE(UINT32, uint32, UInt32);
920 HANDLE_TYPE(UINT64, uint64, UInt64);
921 HANDLE_TYPE( FLOAT, float, Float);
922 HANDLE_TYPE(DOUBLE, double, Double);
923 HANDLE_TYPE( BOOL, bool, Bool);
924 HANDLE_TYPE( ENUM, enum, Enum);
925#undef HANDLE_TYPE
926 case WireFormatLite::CPPTYPE_STRING:
927 SetString(number, other_extension.type,
928 *other_extension.string_value,
929 other_extension.descriptor);
930 break;
931 case WireFormatLite::CPPTYPE_MESSAGE: {
932 Extension* extension;
933 bool is_new = MaybeNewExtension(number,
934 other_extension.descriptor,
935 &extension);
936 if (is_new) {
937 extension->type = other_extension.type;
938 extension->is_packed = other_extension.is_packed;
939 extension->is_repeated = false;
940 if (other_extension.is_lazy) {
941 extension->is_lazy = true;
942 extension->lazymessage_value =
943 other_extension.lazymessage_value->New(arena_);
944 extension->lazymessage_value->MergeFrom(
945 *other_extension.lazymessage_value);
946 } else {
947 extension->is_lazy = false;
948 extension->message_value =
949 other_extension.message_value->New(arena_);
950 extension->message_value->CheckTypeAndMergeFrom(
951 *other_extension.message_value);
952 }
953 } else {
954 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
955 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
956 GOOGLE_DCHECK(!extension->is_repeated);
957 if (other_extension.is_lazy) {
958 if (extension->is_lazy) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000959 extension->lazymessage_value->MergeFrom(
960 *other_extension.lazymessage_value);
961 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800962 extension->message_value->CheckTypeAndMergeFrom(
963 other_extension.lazymessage_value->GetMessage(
964 *extension->message_value));
965 }
966 } else {
967 if (extension->is_lazy) {
968 extension->lazymessage_value->MutableMessage(
969 *other_extension.message_value)->CheckTypeAndMergeFrom(
970 *other_extension.message_value);
971 } else {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000972 extension->message_value->CheckTypeAndMergeFrom(
973 *other_extension.message_value);
974 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000975 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000976 }
Feng Xiao6ef984a2014-11-10 17:34:54 -0800977 extension->is_cleared = false;
978 break;
temporal40ee5512008-07-10 02:12:20 +0000979 }
980 }
981 }
982 }
983}
984
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000985void ExtensionSet::Swap(ExtensionSet* x) {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800986 if (GetArenaNoVirtual() == x->GetArenaNoVirtual()) {
987 extensions_.swap(x->extensions_);
988 } else {
989 // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
990 // swapping from heap to arena-allocated extension set, by just Own()'ing
991 // the extensions.
992 ExtensionSet extension_set;
993 extension_set.MergeFrom(*x);
994 x->Clear();
995 x->MergeFrom(*this);
996 Clear();
997 MergeFrom(extension_set);
998 }
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000999}
1000
jieluo@google.com4de8f552014-07-18 00:47:59 +00001001void ExtensionSet::SwapExtension(ExtensionSet* other,
1002 int number) {
1003 if (this == other) return;
1004 map<int, Extension>::iterator this_iter = extensions_.find(number);
1005 map<int, Extension>::iterator other_iter = other->extensions_.find(number);
1006
1007 if (this_iter == extensions_.end() &&
1008 other_iter == other->extensions_.end()) {
1009 return;
1010 }
1011
1012 if (this_iter != extensions_.end() &&
1013 other_iter != other->extensions_.end()) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001014 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1015 using std::swap;
1016 swap(this_iter->second, other_iter->second);
1017 } else {
1018 // TODO(cfallin, rohananil): We could further optimize these cases,
1019 // especially avoid creation of ExtensionSet, and move MergeFrom logic
1020 // into Extensions itself (which takes arena as an argument).
1021 // We do it this way to reuse the copy-across-arenas logic already
1022 // implemented in ExtensionSet's MergeFrom.
1023 ExtensionSet temp;
1024 temp.InternalExtensionMergeFrom(number, other_iter->second);
1025 map<int, Extension>::iterator temp_iter = temp.extensions_.find(number);
1026 other_iter->second.Clear();
1027 other->InternalExtensionMergeFrom(number, this_iter->second);
1028 this_iter->second.Clear();
1029 InternalExtensionMergeFrom(number, temp_iter->second);
1030 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001031 return;
1032 }
1033
1034 if (this_iter == extensions_.end()) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001035 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
Jisi Liu885b6122015-02-28 14:51:22 -08001036 extensions_.insert(std::make_pair(number, other_iter->second));
Feng Xiao6ef984a2014-11-10 17:34:54 -08001037 } else {
1038 InternalExtensionMergeFrom(number, other_iter->second);
1039 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001040 other->extensions_.erase(number);
1041 return;
1042 }
1043
1044 if (other_iter == other->extensions_.end()) {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001045 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
Jisi Liu885b6122015-02-28 14:51:22 -08001046 other->extensions_.insert(std::make_pair(number, this_iter->second));
Feng Xiao6ef984a2014-11-10 17:34:54 -08001047 } else {
1048 other->InternalExtensionMergeFrom(number, this_iter->second);
1049 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001050 extensions_.erase(number);
1051 return;
1052 }
1053}
1054
temporal40ee5512008-07-10 02:12:20 +00001055bool ExtensionSet::IsInitialized() const {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001056 // Extensions are never required. However, we need to check that all
temporal40ee5512008-07-10 02:12:20 +00001057 // embedded messages are initialized.
1058 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1059 iter != extensions_.end(); ++iter) {
1060 const Extension& extension = iter->second;
kenton@google.com80b1d622009-07-29 01:13:20 +00001061 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001062 if (extension.is_repeated) {
temporal40ee5512008-07-10 02:12:20 +00001063 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
1064 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
1065 return false;
1066 }
1067 }
1068 } else {
1069 if (!extension.is_cleared) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001070 if (extension.is_lazy) {
1071 if (!extension.lazymessage_value->IsInitialized()) return false;
1072 } else {
1073 if (!extension.message_value->IsInitialized()) return false;
1074 }
temporal40ee5512008-07-10 02:12:20 +00001075 }
1076 }
1077 }
1078 }
1079
1080 return true;
1081}
1082
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001083bool ExtensionSet::FindExtensionInfoFromTag(
jieluo@google.com4de8f552014-07-18 00:47:59 +00001084 uint32 tag, ExtensionFinder* extension_finder, int* field_number,
1085 ExtensionInfo* extension, bool* was_packed_on_wire) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001086 *field_number = WireFormatLite::GetTagFieldNumber(tag);
kenton@google.com80b1d622009-07-29 01:13:20 +00001087 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
jieluo@google.com4de8f552014-07-18 00:47:59 +00001088 return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
1089 extension_finder, extension,
1090 was_packed_on_wire);
1091}
temporal40ee5512008-07-10 02:12:20 +00001092
jieluo@google.com4de8f552014-07-18 00:47:59 +00001093bool ExtensionSet::FindExtensionInfoFromFieldNumber(
1094 int wire_type, int field_number, ExtensionFinder* extension_finder,
1095 ExtensionInfo* extension, bool* was_packed_on_wire) {
1096 if (!extension_finder->Find(field_number, extension)) {
1097 return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001098 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001099
1100 WireFormatLite::WireType expected_wire_type =
1101 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
1102
1103 // Check if this is a packed field.
1104 *was_packed_on_wire = false;
1105 if (extension->is_repeated &&
1106 wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
1107 is_packable(expected_wire_type)) {
1108 *was_packed_on_wire = true;
1109 return true;
1110 }
1111 // Otherwise the wire type must match.
1112 return expected_wire_type == wire_type;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001113}
kenton@google.comd37d46d2009-04-25 02:53:47 +00001114
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001115bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1116 ExtensionFinder* extension_finder,
1117 FieldSkipper* field_skipper) {
1118 int number;
jieluo@google.com4de8f552014-07-18 00:47:59 +00001119 bool was_packed_on_wire;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001120 ExtensionInfo extension;
jieluo@google.com4de8f552014-07-18 00:47:59 +00001121 if (!FindExtensionInfoFromTag(
1122 tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001123 return field_skipper->SkipField(input, tag);
1124 } else {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001125 return ParseFieldWithExtensionInfo(
1126 number, was_packed_on_wire, extension, input, field_skipper);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001127 }
1128}
1129
1130bool ExtensionSet::ParseFieldWithExtensionInfo(
jieluo@google.com4de8f552014-07-18 00:47:59 +00001131 int number, bool was_packed_on_wire, const ExtensionInfo& extension,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001132 io::CodedInputStream* input,
1133 FieldSkipper* field_skipper) {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001134 // Explicitly not read extension.is_packed, instead check whether the field
1135 // was encoded in packed form on the wire.
1136 if (was_packed_on_wire) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001137 uint32 size;
1138 if (!input->ReadVarint32(&size)) return false;
1139 io::CodedInputStream::Limit limit = input->PushLimit(size);
1140
kenton@google.comfccb1462009-12-18 02:11:36 +00001141 switch (extension.type) {
1142#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001143 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001144 while (input->BytesUntilLimit() > 0) { \
1145 CPP_LOWERCASE value; \
kenton@google.comfccb1462009-12-18 02:11:36 +00001146 if (!WireFormatLite::ReadPrimitive< \
1147 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1148 input, &value)) return false; \
kenton@google.com80b1d622009-07-29 01:13:20 +00001149 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
jieluo@google.com4de8f552014-07-18 00:47:59 +00001150 extension.is_packed, value, \
1151 extension.descriptor); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001152 } \
1153 break
1154
kenton@google.comfccb1462009-12-18 02:11:36 +00001155 HANDLE_TYPE( INT32, Int32, int32);
1156 HANDLE_TYPE( INT64, Int64, int64);
1157 HANDLE_TYPE( UINT32, UInt32, uint32);
1158 HANDLE_TYPE( UINT64, UInt64, uint64);
1159 HANDLE_TYPE( SINT32, Int32, int32);
1160 HANDLE_TYPE( SINT64, Int64, int64);
1161 HANDLE_TYPE( FIXED32, UInt32, uint32);
1162 HANDLE_TYPE( FIXED64, UInt64, uint64);
1163 HANDLE_TYPE(SFIXED32, Int32, int32);
1164 HANDLE_TYPE(SFIXED64, Int64, int64);
1165 HANDLE_TYPE( FLOAT, Float, float);
1166 HANDLE_TYPE( DOUBLE, Double, double);
1167 HANDLE_TYPE( BOOL, Bool, bool);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001168#undef HANDLE_TYPE
1169
kenton@google.com80b1d622009-07-29 01:13:20 +00001170 case WireFormatLite::TYPE_ENUM:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001171 while (input->BytesUntilLimit() > 0) {
1172 int value;
kenton@google.comfccb1462009-12-18 02:11:36 +00001173 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1174 input, &value)) return false;
kenton@google.comf9c59782009-12-22 18:04:23 +00001175 if (extension.enum_validity_check.func(
1176 extension.enum_validity_check.arg, value)) {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001177 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1178 value, extension.descriptor);
Jisi Liu885b6122015-02-28 14:51:22 -08001179 } else {
1180 // Invalid value. Treat as unknown.
1181 field_skipper->SkipUnknownEnum(number, value);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001182 }
1183 }
1184 break;
1185
kenton@google.com80b1d622009-07-29 01:13:20 +00001186 case WireFormatLite::TYPE_STRING:
1187 case WireFormatLite::TYPE_BYTES:
1188 case WireFormatLite::TYPE_GROUP:
1189 case WireFormatLite::TYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001190 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1191 break;
1192 }
1193
1194 input->PopLimit(limit);
1195 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001196 switch (extension.type) {
1197#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001198 case WireFormatLite::TYPE_##UPPERCASE: { \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001199 CPP_LOWERCASE value; \
kenton@google.comfccb1462009-12-18 02:11:36 +00001200 if (!WireFormatLite::ReadPrimitive< \
1201 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1202 input, &value)) return false; \
jieluo@google.com4de8f552014-07-18 00:47:59 +00001203 if (extension.is_repeated) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001204 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
jieluo@google.com4de8f552014-07-18 00:47:59 +00001205 extension.is_packed, value, \
1206 extension.descriptor); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001207 } else { \
kenton@google.comfccb1462009-12-18 02:11:36 +00001208 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
1209 extension.descriptor); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001210 } \
1211 } break
1212
kenton@google.comfccb1462009-12-18 02:11:36 +00001213 HANDLE_TYPE( INT32, Int32, int32);
1214 HANDLE_TYPE( INT64, Int64, int64);
1215 HANDLE_TYPE( UINT32, UInt32, uint32);
1216 HANDLE_TYPE( UINT64, UInt64, uint64);
1217 HANDLE_TYPE( SINT32, Int32, int32);
1218 HANDLE_TYPE( SINT64, Int64, int64);
1219 HANDLE_TYPE( FIXED32, UInt32, uint32);
1220 HANDLE_TYPE( FIXED64, UInt64, uint64);
1221 HANDLE_TYPE(SFIXED32, Int32, int32);
1222 HANDLE_TYPE(SFIXED64, Int64, int64);
1223 HANDLE_TYPE( FLOAT, Float, float);
1224 HANDLE_TYPE( DOUBLE, Double, double);
1225 HANDLE_TYPE( BOOL, Bool, bool);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001226#undef HANDLE_TYPE
1227
kenton@google.com80b1d622009-07-29 01:13:20 +00001228 case WireFormatLite::TYPE_ENUM: {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001229 int value;
kenton@google.comfccb1462009-12-18 02:11:36 +00001230 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1231 input, &value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001232
kenton@google.comf9c59782009-12-22 18:04:23 +00001233 if (!extension.enum_validity_check.func(
1234 extension.enum_validity_check.arg, value)) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001235 // Invalid value. Treat as unknown.
kenton@google.com80b1d622009-07-29 01:13:20 +00001236 field_skipper->SkipUnknownEnum(number, value);
kenton@google.comfccb1462009-12-18 02:11:36 +00001237 } else if (extension.is_repeated) {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001238 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
kenton@google.comfccb1462009-12-18 02:11:36 +00001239 extension.descriptor);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001240 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001241 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1242 extension.descriptor);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001243 }
1244 break;
1245 }
1246
kenton@google.com80b1d622009-07-29 01:13:20 +00001247 case WireFormatLite::TYPE_STRING: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001248 string* value = extension.is_repeated ?
1249 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1250 MutableString(number, WireFormatLite::TYPE_STRING,
1251 extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001252 if (!WireFormatLite::ReadString(input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001253 break;
1254 }
1255
kenton@google.com80b1d622009-07-29 01:13:20 +00001256 case WireFormatLite::TYPE_BYTES: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001257 string* value = extension.is_repeated ?
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001258 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1259 MutableString(number, WireFormatLite::TYPE_BYTES,
kenton@google.comfccb1462009-12-18 02:11:36 +00001260 extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001261 if (!WireFormatLite::ReadBytes(input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001262 break;
1263 }
1264
kenton@google.com80b1d622009-07-29 01:13:20 +00001265 case WireFormatLite::TYPE_GROUP: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001266 MessageLite* value = extension.is_repeated ?
kenton@google.com80b1d622009-07-29 01:13:20 +00001267 AddMessage(number, WireFormatLite::TYPE_GROUP,
kenton@google.comfccb1462009-12-18 02:11:36 +00001268 *extension.message_prototype, extension.descriptor) :
kenton@google.com80b1d622009-07-29 01:13:20 +00001269 MutableMessage(number, WireFormatLite::TYPE_GROUP,
kenton@google.comfccb1462009-12-18 02:11:36 +00001270 *extension.message_prototype, extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001271 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001272 break;
1273 }
1274
kenton@google.com80b1d622009-07-29 01:13:20 +00001275 case WireFormatLite::TYPE_MESSAGE: {
kenton@google.comfccb1462009-12-18 02:11:36 +00001276 MessageLite* value = extension.is_repeated ?
kenton@google.com80b1d622009-07-29 01:13:20 +00001277 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
kenton@google.comfccb1462009-12-18 02:11:36 +00001278 *extension.message_prototype, extension.descriptor) :
kenton@google.com80b1d622009-07-29 01:13:20 +00001279 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
kenton@google.comfccb1462009-12-18 02:11:36 +00001280 *extension.message_prototype, extension.descriptor);
kenton@google.com80b1d622009-07-29 01:13:20 +00001281 if (!WireFormatLite::ReadMessage(input, value)) return false;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001282 break;
1283 }
temporal40ee5512008-07-10 02:12:20 +00001284 }
1285 }
1286
1287 return true;
1288}
1289
kenton@google.com80b1d622009-07-29 01:13:20 +00001290bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1291 const MessageLite* containing_type) {
1292 FieldSkipper skipper;
kenton@google.comfccb1462009-12-18 02:11:36 +00001293 GeneratedExtensionFinder finder(containing_type);
1294 return ParseField(tag, input, &finder, &skipper);
kenton@google.com80b1d622009-07-29 01:13:20 +00001295}
1296
jieluo@google.com4de8f552014-07-18 00:47:59 +00001297bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1298 const MessageLite* containing_type,
1299 io::CodedOutputStream* unknown_fields) {
1300 CodedOutputStreamFieldSkipper skipper(unknown_fields);
1301 GeneratedExtensionFinder finder(containing_type);
1302 return ParseField(tag, input, &finder, &skipper);
1303}
1304
kenton@google.com80b1d622009-07-29 01:13:20 +00001305// Defined in extension_set_heavy.cc.
1306// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1307// const MessageLite* containing_type,
1308// UnknownFieldSet* unknown_fields)
1309
kenton@google.com80b1d622009-07-29 01:13:20 +00001310// Defined in extension_set_heavy.cc.
1311// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1312// const MessageLite* containing_type,
1313// UnknownFieldSet* unknown_fields);
1314
kenton@google.comd37d46d2009-04-25 02:53:47 +00001315void ExtensionSet::SerializeWithCachedSizes(
1316 int start_field_number, int end_field_number,
1317 io::CodedOutputStream* output) const {
1318 map<int, Extension>::const_iterator iter;
1319 for (iter = extensions_.lower_bound(start_field_number);
1320 iter != extensions_.end() && iter->first < end_field_number;
1321 ++iter) {
1322 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1323 }
1324}
1325
kenton@google.comd37d46d2009-04-25 02:53:47 +00001326int ExtensionSet::ByteSize() const {
temporal40ee5512008-07-10 02:12:20 +00001327 int total_size = 0;
1328
1329 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1330 iter != extensions_.end(); ++iter) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001331 total_size += iter->second.ByteSize(iter->first);
temporal40ee5512008-07-10 02:12:20 +00001332 }
1333
1334 return total_size;
1335}
1336
kenton@google.com80b1d622009-07-29 01:13:20 +00001337// Defined in extension_set_heavy.cc.
1338// int ExtensionSet::SpaceUsedExcludingSelf() const
1339
kenton@google.comfccb1462009-12-18 02:11:36 +00001340bool ExtensionSet::MaybeNewExtension(int number,
1341 const FieldDescriptor* descriptor,
1342 Extension** result) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001343 pair<map<int, Extension>::iterator, bool> insert_result =
Jisi Liu885b6122015-02-28 14:51:22 -08001344 extensions_.insert(std::make_pair(number, Extension()));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001345 *result = &insert_result.first->second;
kenton@google.comfccb1462009-12-18 02:11:36 +00001346 (*result)->descriptor = descriptor;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001347 return insert_result.second;
1348}
1349
temporal40ee5512008-07-10 02:12:20 +00001350// ===================================================================
1351// Methods of ExtensionSet::Extension
1352
1353void ExtensionSet::Extension::Clear() {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001354 if (is_repeated) {
1355 switch (cpp_type(type)) {
temporal40ee5512008-07-10 02:12:20 +00001356#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001357 case WireFormatLite::CPPTYPE_##UPPERCASE: \
temporal40ee5512008-07-10 02:12:20 +00001358 repeated_##LOWERCASE##_value->Clear(); \
1359 break
1360
1361 HANDLE_TYPE( INT32, int32);
1362 HANDLE_TYPE( INT64, int64);
1363 HANDLE_TYPE( UINT32, uint32);
1364 HANDLE_TYPE( UINT64, uint64);
1365 HANDLE_TYPE( FLOAT, float);
1366 HANDLE_TYPE( DOUBLE, double);
1367 HANDLE_TYPE( BOOL, bool);
1368 HANDLE_TYPE( ENUM, enum);
1369 HANDLE_TYPE( STRING, string);
1370 HANDLE_TYPE(MESSAGE, message);
1371#undef HANDLE_TYPE
1372 }
1373 } else {
1374 if (!is_cleared) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001375 switch (cpp_type(type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001376 case WireFormatLite::CPPTYPE_STRING:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001377 string_value->clear();
temporal40ee5512008-07-10 02:12:20 +00001378 break;
kenton@google.com80b1d622009-07-29 01:13:20 +00001379 case WireFormatLite::CPPTYPE_MESSAGE:
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001380 if (is_lazy) {
1381 lazymessage_value->Clear();
1382 } else {
1383 message_value->Clear();
1384 }
temporal40ee5512008-07-10 02:12:20 +00001385 break;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001386 default:
1387 // No need to do anything. Get*() will return the default value
1388 // as long as is_cleared is true and Set*() will overwrite the
1389 // previous value.
1390 break;
temporal40ee5512008-07-10 02:12:20 +00001391 }
1392
1393 is_cleared = true;
1394 }
1395 }
1396}
1397
kenton@google.comd37d46d2009-04-25 02:53:47 +00001398void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1399 int number,
temporal40ee5512008-07-10 02:12:20 +00001400 io::CodedOutputStream* output) const {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001401 if (is_repeated) {
1402 if (is_packed) {
1403 if (cached_size == 0) return;
1404
kenton@google.com80b1d622009-07-29 01:13:20 +00001405 WireFormatLite::WriteTag(number,
1406 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001407 output->WriteVarint32(cached_size);
1408
1409 switch (real_type(type)) {
1410#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001411 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001412 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001413 WireFormatLite::Write##CAMELCASE##NoTag( \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001414 repeated_##LOWERCASE##_value->Get(i), output); \
1415 } \
1416 break
1417
1418 HANDLE_TYPE( INT32, Int32, int32);
1419 HANDLE_TYPE( INT64, Int64, int64);
1420 HANDLE_TYPE( UINT32, UInt32, uint32);
1421 HANDLE_TYPE( UINT64, UInt64, uint64);
1422 HANDLE_TYPE( SINT32, SInt32, int32);
1423 HANDLE_TYPE( SINT64, SInt64, int64);
1424 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1425 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1426 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1427 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1428 HANDLE_TYPE( FLOAT, Float, float);
1429 HANDLE_TYPE( DOUBLE, Double, double);
1430 HANDLE_TYPE( BOOL, Bool, bool);
1431 HANDLE_TYPE( ENUM, Enum, enum);
1432#undef HANDLE_TYPE
1433
kenton@google.com80b1d622009-07-29 01:13:20 +00001434 case WireFormatLite::TYPE_STRING:
1435 case WireFormatLite::TYPE_BYTES:
1436 case WireFormatLite::TYPE_GROUP:
1437 case WireFormatLite::TYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001438 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1439 break;
1440 }
1441 } else {
1442 switch (real_type(type)) {
1443#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001444 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001445 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001446 WireFormatLite::Write##CAMELCASE(number, \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001447 repeated_##LOWERCASE##_value->Get(i), output); \
1448 } \
1449 break
1450
1451 HANDLE_TYPE( INT32, Int32, int32);
1452 HANDLE_TYPE( INT64, Int64, int64);
1453 HANDLE_TYPE( UINT32, UInt32, uint32);
1454 HANDLE_TYPE( UINT64, UInt64, uint64);
1455 HANDLE_TYPE( SINT32, SInt32, int32);
1456 HANDLE_TYPE( SINT64, SInt64, int64);
1457 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1458 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1459 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1460 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1461 HANDLE_TYPE( FLOAT, Float, float);
1462 HANDLE_TYPE( DOUBLE, Double, double);
1463 HANDLE_TYPE( BOOL, Bool, bool);
1464 HANDLE_TYPE( STRING, String, string);
1465 HANDLE_TYPE( BYTES, Bytes, string);
1466 HANDLE_TYPE( ENUM, Enum, enum);
1467 HANDLE_TYPE( GROUP, Group, message);
1468 HANDLE_TYPE( MESSAGE, Message, message);
1469#undef HANDLE_TYPE
1470 }
1471 }
1472 } else if (!is_cleared) {
1473 switch (real_type(type)) {
1474#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001475 case WireFormatLite::TYPE_##UPPERCASE: \
1476 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001477 break
1478
1479 HANDLE_TYPE( INT32, Int32, int32_value);
1480 HANDLE_TYPE( INT64, Int64, int64_value);
1481 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1482 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1483 HANDLE_TYPE( SINT32, SInt32, int32_value);
1484 HANDLE_TYPE( SINT64, SInt64, int64_value);
1485 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1486 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1487 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1488 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1489 HANDLE_TYPE( FLOAT, Float, float_value);
1490 HANDLE_TYPE( DOUBLE, Double, double_value);
1491 HANDLE_TYPE( BOOL, Bool, bool_value);
1492 HANDLE_TYPE( STRING, String, *string_value);
1493 HANDLE_TYPE( BYTES, Bytes, *string_value);
1494 HANDLE_TYPE( ENUM, Enum, enum_value);
1495 HANDLE_TYPE( GROUP, Group, *message_value);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001496#undef HANDLE_TYPE
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001497 case WireFormatLite::TYPE_MESSAGE:
1498 if (is_lazy) {
1499 lazymessage_value->WriteMessage(number, output);
1500 } else {
1501 WireFormatLite::WriteMessage(number, *message_value, output);
1502 }
1503 break;
kenton@google.comd37d46d2009-04-25 02:53:47 +00001504 }
temporal40ee5512008-07-10 02:12:20 +00001505 }
1506}
1507
kenton@google.comd37d46d2009-04-25 02:53:47 +00001508int ExtensionSet::Extension::ByteSize(int number) const {
1509 int result = 0;
1510
1511 if (is_repeated) {
1512 if (is_packed) {
1513 switch (real_type(type)) {
1514#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001515 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001516 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001517 result += WireFormatLite::CAMELCASE##Size( \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001518 repeated_##LOWERCASE##_value->Get(i)); \
1519 } \
1520 break
1521
1522 HANDLE_TYPE( INT32, Int32, int32);
1523 HANDLE_TYPE( INT64, Int64, int64);
1524 HANDLE_TYPE( UINT32, UInt32, uint32);
1525 HANDLE_TYPE( UINT64, UInt64, uint64);
1526 HANDLE_TYPE( SINT32, SInt32, int32);
1527 HANDLE_TYPE( SINT64, SInt64, int64);
1528 HANDLE_TYPE( ENUM, Enum, enum);
1529#undef HANDLE_TYPE
1530
1531 // Stuff with fixed size.
1532#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001533 case WireFormatLite::TYPE_##UPPERCASE: \
1534 result += WireFormatLite::k##CAMELCASE##Size * \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001535 repeated_##LOWERCASE##_value->size(); \
1536 break
1537 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1538 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1539 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1540 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1541 HANDLE_TYPE( FLOAT, Float, float);
1542 HANDLE_TYPE( DOUBLE, Double, double);
1543 HANDLE_TYPE( BOOL, Bool, bool);
1544#undef HANDLE_TYPE
1545
kenton@google.com80b1d622009-07-29 01:13:20 +00001546 case WireFormatLite::TYPE_STRING:
1547 case WireFormatLite::TYPE_BYTES:
1548 case WireFormatLite::TYPE_GROUP:
1549 case WireFormatLite::TYPE_MESSAGE:
kenton@google.comd37d46d2009-04-25 02:53:47 +00001550 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1551 break;
1552 }
1553
1554 cached_size = result;
1555 if (result > 0) {
1556 result += io::CodedOutputStream::VarintSize32(result);
1557 result += io::CodedOutputStream::VarintSize32(
kenton@google.com80b1d622009-07-29 01:13:20 +00001558 WireFormatLite::MakeTag(number,
1559 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001560 }
1561 } else {
kenton@google.com80b1d622009-07-29 01:13:20 +00001562 int tag_size = WireFormatLite::TagSize(number, real_type(type));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001563
1564 switch (real_type(type)) {
1565#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001566 case WireFormatLite::TYPE_##UPPERCASE: \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001567 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1568 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
kenton@google.com80b1d622009-07-29 01:13:20 +00001569 result += WireFormatLite::CAMELCASE##Size( \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001570 repeated_##LOWERCASE##_value->Get(i)); \
1571 } \
1572 break
1573
1574 HANDLE_TYPE( INT32, Int32, int32);
1575 HANDLE_TYPE( INT64, Int64, int64);
1576 HANDLE_TYPE( UINT32, UInt32, uint32);
1577 HANDLE_TYPE( UINT64, UInt64, uint64);
1578 HANDLE_TYPE( SINT32, SInt32, int32);
1579 HANDLE_TYPE( SINT64, SInt64, int64);
1580 HANDLE_TYPE( STRING, String, string);
1581 HANDLE_TYPE( BYTES, Bytes, string);
1582 HANDLE_TYPE( ENUM, Enum, enum);
1583 HANDLE_TYPE( GROUP, Group, message);
1584 HANDLE_TYPE( MESSAGE, Message, message);
1585#undef HANDLE_TYPE
1586
1587 // Stuff with fixed size.
1588#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001589 case WireFormatLite::TYPE_##UPPERCASE: \
1590 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001591 repeated_##LOWERCASE##_value->size(); \
1592 break
1593 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1594 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1595 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1596 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1597 HANDLE_TYPE( FLOAT, Float, float);
1598 HANDLE_TYPE( DOUBLE, Double, double);
1599 HANDLE_TYPE( BOOL, Bool, bool);
1600#undef HANDLE_TYPE
1601 }
1602 }
1603 } else if (!is_cleared) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001604 result += WireFormatLite::TagSize(number, real_type(type));
kenton@google.comd37d46d2009-04-25 02:53:47 +00001605 switch (real_type(type)) {
1606#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001607 case WireFormatLite::TYPE_##UPPERCASE: \
1608 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001609 break
1610
1611 HANDLE_TYPE( INT32, Int32, int32_value);
1612 HANDLE_TYPE( INT64, Int64, int64_value);
1613 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1614 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1615 HANDLE_TYPE( SINT32, SInt32, int32_value);
1616 HANDLE_TYPE( SINT64, SInt64, int64_value);
1617 HANDLE_TYPE( STRING, String, *string_value);
1618 HANDLE_TYPE( BYTES, Bytes, *string_value);
1619 HANDLE_TYPE( ENUM, Enum, enum_value);
1620 HANDLE_TYPE( GROUP, Group, *message_value);
kenton@google.comd37d46d2009-04-25 02:53:47 +00001621#undef HANDLE_TYPE
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001622 case WireFormatLite::TYPE_MESSAGE: {
1623 if (is_lazy) {
1624 int size = lazymessage_value->ByteSize();
1625 result += io::CodedOutputStream::VarintSize32(size) + size;
1626 } else {
1627 result += WireFormatLite::MessageSize(*message_value);
1628 }
1629 break;
1630 }
kenton@google.comd37d46d2009-04-25 02:53:47 +00001631
1632 // Stuff with fixed size.
1633#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001634 case WireFormatLite::TYPE_##UPPERCASE: \
1635 result += WireFormatLite::k##CAMELCASE##Size; \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001636 break
1637 HANDLE_TYPE( FIXED32, Fixed32);
1638 HANDLE_TYPE( FIXED64, Fixed64);
1639 HANDLE_TYPE(SFIXED32, SFixed32);
1640 HANDLE_TYPE(SFIXED64, SFixed64);
1641 HANDLE_TYPE( FLOAT, Float);
1642 HANDLE_TYPE( DOUBLE, Double);
1643 HANDLE_TYPE( BOOL, Bool);
1644#undef HANDLE_TYPE
1645 }
temporal40ee5512008-07-10 02:12:20 +00001646 }
kenton@google.comd37d46d2009-04-25 02:53:47 +00001647
1648 return result;
temporal40ee5512008-07-10 02:12:20 +00001649}
1650
1651int ExtensionSet::Extension::GetSize() const {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001652 GOOGLE_DCHECK(is_repeated);
1653 switch (cpp_type(type)) {
temporal40ee5512008-07-10 02:12:20 +00001654#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001655 case WireFormatLite::CPPTYPE_##UPPERCASE: \
temporal40ee5512008-07-10 02:12:20 +00001656 return repeated_##LOWERCASE##_value->size()
1657
1658 HANDLE_TYPE( INT32, int32);
1659 HANDLE_TYPE( INT64, int64);
1660 HANDLE_TYPE( UINT32, uint32);
1661 HANDLE_TYPE( UINT64, uint64);
1662 HANDLE_TYPE( FLOAT, float);
1663 HANDLE_TYPE( DOUBLE, double);
1664 HANDLE_TYPE( BOOL, bool);
1665 HANDLE_TYPE( ENUM, enum);
1666 HANDLE_TYPE( STRING, string);
1667 HANDLE_TYPE(MESSAGE, message);
1668#undef HANDLE_TYPE
1669 }
1670
1671 GOOGLE_LOG(FATAL) << "Can't get here.";
1672 return 0;
1673}
1674
Feng Xiao6ef984a2014-11-10 17:34:54 -08001675// This function deletes all allocated objects. This function should be only
1676// called if the Extension was created with an arena.
temporal40ee5512008-07-10 02:12:20 +00001677void ExtensionSet::Extension::Free() {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001678 if (is_repeated) {
1679 switch (cpp_type(type)) {
temporal40ee5512008-07-10 02:12:20 +00001680#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
kenton@google.com80b1d622009-07-29 01:13:20 +00001681 case WireFormatLite::CPPTYPE_##UPPERCASE: \
temporal40ee5512008-07-10 02:12:20 +00001682 delete repeated_##LOWERCASE##_value; \
1683 break
1684
1685 HANDLE_TYPE( INT32, int32);
1686 HANDLE_TYPE( INT64, int64);
1687 HANDLE_TYPE( UINT32, uint32);
1688 HANDLE_TYPE( UINT64, uint64);
1689 HANDLE_TYPE( FLOAT, float);
1690 HANDLE_TYPE( DOUBLE, double);
1691 HANDLE_TYPE( BOOL, bool);
1692 HANDLE_TYPE( ENUM, enum);
1693 HANDLE_TYPE( STRING, string);
1694 HANDLE_TYPE(MESSAGE, message);
1695#undef HANDLE_TYPE
1696 }
1697 } else {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001698 switch (cpp_type(type)) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001699 case WireFormatLite::CPPTYPE_STRING:
temporal40ee5512008-07-10 02:12:20 +00001700 delete string_value;
1701 break;
kenton@google.com80b1d622009-07-29 01:13:20 +00001702 case WireFormatLite::CPPTYPE_MESSAGE:
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001703 if (is_lazy) {
1704 delete lazymessage_value;
1705 } else {
1706 delete message_value;
1707 }
temporal40ee5512008-07-10 02:12:20 +00001708 break;
1709 default:
1710 break;
1711 }
1712 }
1713}
1714
kenton@google.com80b1d622009-07-29 01:13:20 +00001715// Defined in extension_set_heavy.cc.
1716// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001717
jieluo@google.com4de8f552014-07-18 00:47:59 +00001718// ==================================================================
1719// Default repeated field instances for iterator-compatible accessors
1720
1721const RepeatedStringTypeTraits::RepeatedFieldType*
1722RepeatedStringTypeTraits::default_repeated_field_ = NULL;
1723
1724const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
1725RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
1726
1727#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \
1728 const RepeatedField<TYPE>* \
1729 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
1730
1731PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
1732PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
1733PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
1734PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
1735PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
1736PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
1737PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
1738
1739#undef PROTOBUF_DEFINE_DEFAULT_REPEATED
1740
1741struct StaticDefaultRepeatedFieldsInitializer {
1742 StaticDefaultRepeatedFieldsInitializer() {
1743 InitializeDefaultRepeatedFields();
Antoni Busztae670b672014-10-09 07:15:44 +02001744 OnShutdown(&DestroyDefaultRepeatedFields);
Antoni Busztae83ba132014-10-08 11:21:04 +02001745 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001746} static_repeated_fields_initializer;
1747
1748void InitializeDefaultRepeatedFields() {
1749 RepeatedStringTypeTraits::default_repeated_field_ =
1750 new RepeatedStringTypeTraits::RepeatedFieldType;
1751 RepeatedMessageGenericTypeTraits::default_repeated_field_ =
1752 new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
1753 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
1754 new RepeatedField<int32>;
1755 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
1756 new RepeatedField<int64>;
1757 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
1758 new RepeatedField<uint32>;
1759 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
1760 new RepeatedField<uint64>;
1761 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
1762 new RepeatedField<double>;
1763 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
1764 new RepeatedField<float>;
1765 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
1766 new RepeatedField<bool>;
1767}
1768
Antoni Busztae83ba132014-10-08 11:21:04 +02001769void DestroyDefaultRepeatedFields() {
1770 delete RepeatedStringTypeTraits::default_repeated_field_;
1771 delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
1772 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
1773 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
1774 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
1775 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
1776 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
1777 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
1778 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
1779}
1780
temporal40ee5512008-07-10 02:12:20 +00001781} // namespace internal
1782} // namespace protobuf
1783} // namespace google