Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 : //
35 : // Contains methods defined in extension_set.h which cannot be part of the
36 : // lite library because they use descriptors or reflection.
37 :
38 : #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
39 : #include <google/protobuf/descriptor.h>
40 : #include <google/protobuf/extension_set.h>
41 : #include <google/protobuf/message.h>
42 : #include <google/protobuf/repeated_field.h>
43 : #include <google/protobuf/wire_format.h>
44 : #include <google/protobuf/wire_format_lite_inl.h>
45 :
46 : namespace google {
47 :
48 : namespace protobuf {
49 : namespace internal {
50 :
51 : // A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
52 : class MessageSetFieldSkipper
53 : : public UnknownFieldSetFieldSkipper {
54 : public:
55 0 : explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
56 0 : : UnknownFieldSetFieldSkipper(unknown_fields) {}
57 0 : virtual ~MessageSetFieldSkipper() {}
58 :
59 : virtual bool SkipMessageSetField(io::CodedInputStream* input,
60 : int field_number);
61 : };
62 0 : bool MessageSetFieldSkipper::SkipMessageSetField(
63 : io::CodedInputStream* input, int field_number) {
64 : uint32 length;
65 0 : if (!input->ReadVarint32(&length)) return false;
66 0 : if (unknown_fields_ == NULL) {
67 0 : return input->Skip(length);
68 : } else {
69 0 : return input->ReadString(
70 0 : unknown_fields_->AddLengthDelimited(field_number), length);
71 : }
72 : }
73 :
74 :
75 : // Implementation of ExtensionFinder which finds extensions in a given
76 : // DescriptorPool, using the given MessageFactory to construct sub-objects.
77 : // This class is implemented in extension_set_heavy.cc.
78 : class DescriptorPoolExtensionFinder : public ExtensionFinder {
79 : public:
80 0 : DescriptorPoolExtensionFinder(const DescriptorPool* pool,
81 : MessageFactory* factory,
82 : const Descriptor* containing_type)
83 0 : : pool_(pool), factory_(factory), containing_type_(containing_type) {}
84 0 : virtual ~DescriptorPoolExtensionFinder() {}
85 :
86 : virtual bool Find(int number, ExtensionInfo* output);
87 :
88 : private:
89 : const DescriptorPool* pool_;
90 : MessageFactory* factory_;
91 : const Descriptor* containing_type_;
92 : };
93 :
94 0 : void ExtensionSet::AppendToList(const Descriptor* containing_type,
95 : const DescriptorPool* pool,
96 : vector<const FieldDescriptor*>* output) const {
97 0 : for (map<int, Extension>::const_iterator iter = extensions_.begin();
98 0 : iter != extensions_.end(); ++iter) {
99 0 : bool has = false;
100 0 : if (iter->second.is_repeated) {
101 0 : has = iter->second.GetSize() > 0;
102 : } else {
103 0 : has = !iter->second.is_cleared;
104 : }
105 :
106 0 : if (has) {
107 : // TODO(kenton): Looking up each field by number is somewhat unfortunate.
108 : // Is there a better way? The problem is that descriptors are lazily-
109 : // initialized, so they might not even be constructed until
110 : // AppendToList() is called.
111 :
112 0 : if (iter->second.descriptor == NULL) {
113 0 : output->push_back(pool->FindExtensionByNumber(
114 0 : containing_type, iter->first));
115 : } else {
116 0 : output->push_back(iter->second.descriptor);
117 : }
118 : }
119 : }
120 0 : }
121 :
122 0 : inline FieldDescriptor::Type real_type(FieldType type) {
123 0 : GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
124 0 : return static_cast<FieldDescriptor::Type>(type);
125 : }
126 :
127 0 : inline FieldDescriptor::CppType cpp_type(FieldType type) {
128 0 : return FieldDescriptor::TypeToCppType(
129 0 : static_cast<FieldDescriptor::Type>(type));
130 : }
131 :
132 : inline WireFormatLite::FieldType field_type(FieldType type) {
133 : GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
134 : return static_cast<WireFormatLite::FieldType>(type);
135 : }
136 :
137 : #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
138 : GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
139 : : FieldDescriptor::LABEL_OPTIONAL, \
140 : FieldDescriptor::LABEL_##LABEL); \
141 : GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
142 :
143 0 : const MessageLite& ExtensionSet::GetMessage(int number,
144 : const Descriptor* message_type,
145 : MessageFactory* factory) const {
146 0 : map<int, Extension>::const_iterator iter = extensions_.find(number);
147 0 : if (iter == extensions_.end() || iter->second.is_cleared) {
148 : // Not present. Return the default value.
149 0 : return *factory->GetPrototype(message_type);
150 : } else {
151 0 : GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
152 0 : if (iter->second.is_lazy) {
153 0 : return iter->second.lazymessage_value->GetMessage(
154 0 : *factory->GetPrototype(message_type));
155 : } else {
156 0 : return *iter->second.message_value;
157 : }
158 : }
159 : }
160 :
161 0 : MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
162 : MessageFactory* factory) {
163 : Extension* extension;
164 0 : if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
165 0 : extension->type = descriptor->type();
166 0 : GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
167 0 : extension->is_repeated = false;
168 0 : extension->is_packed = false;
169 : const MessageLite* prototype =
170 0 : factory->GetPrototype(descriptor->message_type());
171 0 : extension->is_lazy = false;
172 0 : extension->message_value = prototype->New();
173 0 : extension->is_cleared = false;
174 0 : return extension->message_value;
175 : } else {
176 0 : GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
177 0 : extension->is_cleared = false;
178 0 : if (extension->is_lazy) {
179 0 : return extension->lazymessage_value->MutableMessage(
180 0 : *factory->GetPrototype(descriptor->message_type()));
181 : } else {
182 0 : return extension->message_value;
183 : }
184 : }
185 : }
186 :
187 0 : MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
188 : MessageFactory* factory) {
189 0 : map<int, Extension>::iterator iter = extensions_.find(descriptor->number());
190 0 : if (iter == extensions_.end()) {
191 : // Not present. Return NULL.
192 0 : return NULL;
193 : } else {
194 0 : GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
195 0 : MessageLite* ret = NULL;
196 0 : if (iter->second.is_lazy) {
197 0 : ret = iter->second.lazymessage_value->ReleaseMessage(
198 0 : *factory->GetPrototype(descriptor->message_type()));
199 0 : delete iter->second.lazymessage_value;
200 : } else {
201 0 : ret = iter->second.message_value;
202 : }
203 0 : extensions_.erase(descriptor->number());
204 0 : return ret;
205 : }
206 : }
207 :
208 0 : MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
209 : MessageFactory* factory) {
210 : Extension* extension;
211 0 : if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
212 0 : extension->type = descriptor->type();
213 0 : GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
214 0 : extension->is_repeated = true;
215 0 : extension->repeated_message_value =
216 0 : new RepeatedPtrField<MessageLite>();
217 : } else {
218 0 : GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
219 : }
220 :
221 : // RepeatedPtrField<Message> does not know how to Add() since it cannot
222 : // allocate an abstract object, so we have to be tricky.
223 0 : MessageLite* result = extension->repeated_message_value
224 0 : ->AddFromCleared<GenericTypeHandler<MessageLite> >();
225 0 : if (result == NULL) {
226 : const MessageLite* prototype;
227 0 : if (extension->repeated_message_value->size() == 0) {
228 0 : prototype = factory->GetPrototype(descriptor->message_type());
229 0 : GOOGLE_CHECK(prototype != NULL);
230 : } else {
231 0 : prototype = &extension->repeated_message_value->Get(0);
232 : }
233 0 : result = prototype->New();
234 0 : extension->repeated_message_value->AddAllocated(result);
235 : }
236 0 : return result;
237 : }
238 :
239 0 : static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
240 : return reinterpret_cast<const EnumDescriptor*>(arg)
241 0 : ->FindValueByNumber(number) != NULL;
242 : }
243 :
244 0 : bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
245 : const FieldDescriptor* extension =
246 0 : pool_->FindExtensionByNumber(containing_type_, number);
247 0 : if (extension == NULL) {
248 0 : return false;
249 : } else {
250 0 : output->type = extension->type();
251 0 : output->is_repeated = extension->is_repeated();
252 0 : output->is_packed = extension->options().packed();
253 0 : output->descriptor = extension;
254 0 : if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
255 0 : output->message_prototype =
256 0 : factory_->GetPrototype(extension->message_type());
257 0 : GOOGLE_CHECK(output->message_prototype != NULL)
258 0 : << "Extension factory's GetPrototype() returned NULL for extension: "
259 0 : << extension->full_name();
260 0 : } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
261 0 : output->enum_validity_check.func = ValidateEnumUsingDescriptor;
262 0 : output->enum_validity_check.arg = extension->enum_type();
263 : }
264 :
265 0 : return true;
266 : }
267 : }
268 :
269 0 : bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
270 : const Message* containing_type,
271 : UnknownFieldSet* unknown_fields) {
272 0 : UnknownFieldSetFieldSkipper skipper(unknown_fields);
273 0 : if (input->GetExtensionPool() == NULL) {
274 0 : GeneratedExtensionFinder finder(containing_type);
275 0 : return ParseField(tag, input, &finder, &skipper);
276 : } else {
277 : DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
278 : input->GetExtensionFactory(),
279 0 : containing_type->GetDescriptor());
280 0 : return ParseField(tag, input, &finder, &skipper);
281 : }
282 : }
283 :
284 0 : bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
285 : const Message* containing_type,
286 : UnknownFieldSet* unknown_fields) {
287 0 : MessageSetFieldSkipper skipper(unknown_fields);
288 0 : if (input->GetExtensionPool() == NULL) {
289 0 : GeneratedExtensionFinder finder(containing_type);
290 0 : return ParseMessageSet(input, &finder, &skipper);
291 : } else {
292 : DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
293 : input->GetExtensionFactory(),
294 0 : containing_type->GetDescriptor());
295 0 : return ParseMessageSet(input, &finder, &skipper);
296 : }
297 : }
298 :
299 0 : int ExtensionSet::SpaceUsedExcludingSelf() const {
300 : int total_size =
301 0 : extensions_.size() * sizeof(map<int, Extension>::value_type);
302 0 : for (map<int, Extension>::const_iterator iter = extensions_.begin(),
303 0 : end = extensions_.end();
304 : iter != end;
305 : ++iter) {
306 0 : total_size += iter->second.SpaceUsedExcludingSelf();
307 : }
308 0 : return total_size;
309 : }
310 :
311 0 : inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
312 : RepeatedPtrFieldBase* field) {
313 0 : return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
314 : }
315 :
316 0 : int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
317 0 : int total_size = 0;
318 0 : if (is_repeated) {
319 0 : switch (cpp_type(type)) {
320 : #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
321 : case FieldDescriptor::CPPTYPE_##UPPERCASE: \
322 : total_size += sizeof(*repeated_##LOWERCASE##_value) + \
323 : repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
324 : break
325 :
326 0 : HANDLE_TYPE( INT32, int32);
327 0 : HANDLE_TYPE( INT64, int64);
328 0 : HANDLE_TYPE( UINT32, uint32);
329 0 : HANDLE_TYPE( UINT64, uint64);
330 0 : HANDLE_TYPE( FLOAT, float);
331 0 : HANDLE_TYPE( DOUBLE, double);
332 0 : HANDLE_TYPE( BOOL, bool);
333 0 : HANDLE_TYPE( ENUM, enum);
334 0 : HANDLE_TYPE( STRING, string);
335 : #undef HANDLE_TYPE
336 :
337 : case FieldDescriptor::CPPTYPE_MESSAGE:
338 : // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
339 : // but MessageLite has no SpaceUsed(), so we must directly call
340 : // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
341 : // handler.
342 0 : total_size += sizeof(*repeated_message_value) +
343 0 : RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
344 0 : break;
345 : }
346 : } else {
347 0 : switch (cpp_type(type)) {
348 : case FieldDescriptor::CPPTYPE_STRING:
349 0 : total_size += sizeof(*string_value) +
350 0 : StringSpaceUsedExcludingSelf(*string_value);
351 0 : break;
352 : case FieldDescriptor::CPPTYPE_MESSAGE:
353 0 : if (is_lazy) {
354 0 : total_size += lazymessage_value->SpaceUsed();
355 : } else {
356 0 : total_size += down_cast<Message*>(message_value)->SpaceUsed();
357 : }
358 0 : break;
359 : default:
360 : // No extra storage costs for primitive types.
361 0 : break;
362 : }
363 : }
364 0 : return total_size;
365 : }
366 :
367 : // The Serialize*ToArray methods are only needed in the heavy library, as
368 : // the lite library only generates SerializeWithCachedSizes.
369 0 : uint8* ExtensionSet::SerializeWithCachedSizesToArray(
370 : int start_field_number, int end_field_number,
371 : uint8* target) const {
372 0 : map<int, Extension>::const_iterator iter;
373 0 : for (iter = extensions_.lower_bound(start_field_number);
374 0 : iter != extensions_.end() && iter->first < end_field_number;
375 : ++iter) {
376 0 : target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
377 0 : target);
378 : }
379 0 : return target;
380 : }
381 :
382 0 : uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
383 : uint8* target) const {
384 0 : map<int, Extension>::const_iterator iter;
385 0 : for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
386 0 : target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
387 0 : iter->first, target);
388 : }
389 0 : return target;
390 : }
391 :
392 0 : uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
393 : int number, uint8* target) const {
394 0 : if (is_repeated) {
395 0 : if (is_packed) {
396 0 : if (cached_size == 0) return target;
397 :
398 : target = WireFormatLite::WriteTagToArray(number,
399 0 : WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
400 0 : target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
401 :
402 0 : switch (real_type(type)) {
403 : #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
404 : case FieldDescriptor::TYPE_##UPPERCASE: \
405 : for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
406 : target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \
407 : repeated_##LOWERCASE##_value->Get(i), target); \
408 : } \
409 : break
410 :
411 0 : HANDLE_TYPE( INT32, Int32, int32);
412 0 : HANDLE_TYPE( INT64, Int64, int64);
413 0 : HANDLE_TYPE( UINT32, UInt32, uint32);
414 0 : HANDLE_TYPE( UINT64, UInt64, uint64);
415 0 : HANDLE_TYPE( SINT32, SInt32, int32);
416 0 : HANDLE_TYPE( SINT64, SInt64, int64);
417 0 : HANDLE_TYPE( FIXED32, Fixed32, uint32);
418 0 : HANDLE_TYPE( FIXED64, Fixed64, uint64);
419 0 : HANDLE_TYPE(SFIXED32, SFixed32, int32);
420 0 : HANDLE_TYPE(SFIXED64, SFixed64, int64);
421 0 : HANDLE_TYPE( FLOAT, Float, float);
422 0 : HANDLE_TYPE( DOUBLE, Double, double);
423 0 : HANDLE_TYPE( BOOL, Bool, bool);
424 0 : HANDLE_TYPE( ENUM, Enum, enum);
425 : #undef HANDLE_TYPE
426 :
427 : case WireFormatLite::TYPE_STRING:
428 : case WireFormatLite::TYPE_BYTES:
429 : case WireFormatLite::TYPE_GROUP:
430 : case WireFormatLite::TYPE_MESSAGE:
431 0 : GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
432 0 : break;
433 : }
434 : } else {
435 0 : switch (real_type(type)) {
436 : #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
437 : case FieldDescriptor::TYPE_##UPPERCASE: \
438 : for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
439 : target = WireFormatLite::Write##CAMELCASE##ToArray(number, \
440 : repeated_##LOWERCASE##_value->Get(i), target); \
441 : } \
442 : break
443 :
444 0 : HANDLE_TYPE( INT32, Int32, int32);
445 0 : HANDLE_TYPE( INT64, Int64, int64);
446 0 : HANDLE_TYPE( UINT32, UInt32, uint32);
447 0 : HANDLE_TYPE( UINT64, UInt64, uint64);
448 0 : HANDLE_TYPE( SINT32, SInt32, int32);
449 0 : HANDLE_TYPE( SINT64, SInt64, int64);
450 0 : HANDLE_TYPE( FIXED32, Fixed32, uint32);
451 0 : HANDLE_TYPE( FIXED64, Fixed64, uint64);
452 0 : HANDLE_TYPE(SFIXED32, SFixed32, int32);
453 0 : HANDLE_TYPE(SFIXED64, SFixed64, int64);
454 0 : HANDLE_TYPE( FLOAT, Float, float);
455 0 : HANDLE_TYPE( DOUBLE, Double, double);
456 0 : HANDLE_TYPE( BOOL, Bool, bool);
457 0 : HANDLE_TYPE( STRING, String, string);
458 0 : HANDLE_TYPE( BYTES, Bytes, string);
459 0 : HANDLE_TYPE( ENUM, Enum, enum);
460 0 : HANDLE_TYPE( GROUP, Group, message);
461 0 : HANDLE_TYPE( MESSAGE, Message, message);
462 : #undef HANDLE_TYPE
463 : }
464 : }
465 0 : } else if (!is_cleared) {
466 0 : switch (real_type(type)) {
467 : #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
468 : case FieldDescriptor::TYPE_##UPPERCASE: \
469 : target = WireFormatLite::Write##CAMELCASE##ToArray( \
470 : number, VALUE, target); \
471 : break
472 :
473 0 : HANDLE_TYPE( INT32, Int32, int32_value);
474 0 : HANDLE_TYPE( INT64, Int64, int64_value);
475 0 : HANDLE_TYPE( UINT32, UInt32, uint32_value);
476 0 : HANDLE_TYPE( UINT64, UInt64, uint64_value);
477 0 : HANDLE_TYPE( SINT32, SInt32, int32_value);
478 0 : HANDLE_TYPE( SINT64, SInt64, int64_value);
479 0 : HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
480 0 : HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
481 0 : HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
482 0 : HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
483 0 : HANDLE_TYPE( FLOAT, Float, float_value);
484 0 : HANDLE_TYPE( DOUBLE, Double, double_value);
485 0 : HANDLE_TYPE( BOOL, Bool, bool_value);
486 0 : HANDLE_TYPE( STRING, String, *string_value);
487 0 : HANDLE_TYPE( BYTES, Bytes, *string_value);
488 0 : HANDLE_TYPE( ENUM, Enum, enum_value);
489 0 : HANDLE_TYPE( GROUP, Group, *message_value);
490 : #undef HANDLE_TYPE
491 : case FieldDescriptor::TYPE_MESSAGE:
492 0 : if (is_lazy) {
493 0 : target = lazymessage_value->WriteMessageToArray(number, target);
494 : } else {
495 : target = WireFormatLite::WriteMessageToArray(
496 0 : number, *message_value, target);
497 : }
498 0 : break;
499 : }
500 : }
501 0 : return target;
502 : }
503 :
504 0 : uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
505 : int number,
506 : uint8* target) const {
507 0 : if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
508 : // Not a valid MessageSet extension, but serialize it the normal way.
509 0 : GOOGLE_LOG(WARNING) << "Invalid message set extension.";
510 0 : return SerializeFieldWithCachedSizesToArray(number, target);
511 : }
512 :
513 0 : if (is_cleared) return target;
514 :
515 : // Start group.
516 : target = io::CodedOutputStream::WriteTagToArray(
517 0 : WireFormatLite::kMessageSetItemStartTag, target);
518 : // Write type ID.
519 0 : target = WireFormatLite::WriteUInt32ToArray(
520 0 : WireFormatLite::kMessageSetTypeIdNumber, number, target);
521 : // Write message.
522 0 : if (is_lazy) {
523 0 : target = lazymessage_value->WriteMessageToArray(
524 0 : WireFormatLite::kMessageSetMessageNumber, target);
525 : } else {
526 : target = WireFormatLite::WriteMessageToArray(
527 0 : WireFormatLite::kMessageSetMessageNumber, *message_value, target);
528 : }
529 : // End group.
530 : target = io::CodedOutputStream::WriteTagToArray(
531 0 : WireFormatLite::kMessageSetItemEndTag, target);
532 0 : return target;
533 : }
534 :
535 :
536 0 : bool ExtensionSet::ParseFieldMaybeLazily(
537 : int wire_type, int field_number, io::CodedInputStream* input,
538 : ExtensionFinder* extension_finder,
539 : MessageSetFieldSkipper* field_skipper) {
540 0 : return ParseField(WireFormatLite::MakeTag(
541 : field_number, static_cast<WireFormatLite::WireType>(wire_type)),
542 0 : input, extension_finder, field_skipper);
543 : }
544 :
545 0 : bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
546 : ExtensionFinder* extension_finder,
547 : MessageSetFieldSkipper* field_skipper) {
548 : while (true) {
549 0 : const uint32 tag = input->ReadTag();
550 0 : switch (tag) {
551 : case 0:
552 0 : return true;
553 : case WireFormatLite::kMessageSetItemStartTag:
554 0 : if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
555 0 : return false;
556 : }
557 0 : break;
558 : default:
559 0 : if (!ParseField(tag, input, extension_finder, field_skipper)) {
560 0 : return false;
561 : }
562 0 : break;
563 : }
564 0 : }
565 : }
566 :
567 0 : bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
568 : const MessageLite* containing_type) {
569 0 : MessageSetFieldSkipper skipper(NULL);
570 0 : GeneratedExtensionFinder finder(containing_type);
571 0 : return ParseMessageSet(input, &finder, &skipper);
572 : }
573 :
574 0 : bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
575 : ExtensionFinder* extension_finder,
576 : MessageSetFieldSkipper* field_skipper) {
577 : // TODO(kenton): It would be nice to share code between this and
578 : // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
579 : // differences would be hard to factor out.
580 :
581 : // This method parses a group which should contain two fields:
582 : // required int32 type_id = 2;
583 : // required data message = 3;
584 :
585 0 : uint32 last_type_id = 0;
586 :
587 : // If we see message data before the type_id, we'll append it to this so
588 : // we can parse it later.
589 0 : string message_data;
590 :
591 : while (true) {
592 0 : const uint32 tag = input->ReadTag();
593 0 : if (tag == 0) return false;
594 :
595 0 : switch (tag) {
596 : case WireFormatLite::kMessageSetTypeIdTag: {
597 : uint32 type_id;
598 0 : if (!input->ReadVarint32(&type_id)) return false;
599 0 : last_type_id = type_id;
600 :
601 0 : if (!message_data.empty()) {
602 : // We saw some message data before the type_id. Have to parse it
603 : // now.
604 : io::CodedInputStream sub_input(
605 0 : reinterpret_cast<const uint8*>(message_data.data()),
606 0 : message_data.size());
607 0 : if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
608 : last_type_id, &sub_input,
609 : extension_finder, field_skipper)) {
610 0 : return false;
611 : }
612 0 : message_data.clear();
613 : }
614 :
615 0 : break;
616 : }
617 :
618 : case WireFormatLite::kMessageSetMessageTag: {
619 0 : if (last_type_id == 0) {
620 : // We haven't seen a type_id yet. Append this data to message_data.
621 0 : string temp;
622 : uint32 length;
623 0 : if (!input->ReadVarint32(&length)) return false;
624 0 : if (!input->ReadString(&temp, length)) return false;
625 0 : io::StringOutputStream output_stream(&message_data);
626 0 : io::CodedOutputStream coded_output(&output_stream);
627 0 : coded_output.WriteVarint32(length);
628 0 : coded_output.WriteString(temp);
629 : } else {
630 : // Already saw type_id, so we can parse this directly.
631 0 : if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
632 : last_type_id, input,
633 : extension_finder, field_skipper)) {
634 0 : return false;
635 : }
636 : }
637 :
638 0 : break;
639 : }
640 :
641 : case WireFormatLite::kMessageSetItemEndTag: {
642 0 : return true;
643 : }
644 :
645 : default: {
646 0 : if (!field_skipper->SkipField(input, tag)) return false;
647 : }
648 : }
649 0 : }
650 : }
651 :
652 0 : void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
653 : int number,
654 : io::CodedOutputStream* output) const {
655 0 : if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
656 : // Not a valid MessageSet extension, but serialize it the normal way.
657 0 : SerializeFieldWithCachedSizes(number, output);
658 0 : return;
659 : }
660 :
661 0 : if (is_cleared) return;
662 :
663 : // Start group.
664 0 : output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
665 :
666 : // Write type ID.
667 0 : WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
668 : number,
669 0 : output);
670 : // Write message.
671 0 : if (is_lazy) {
672 0 : lazymessage_value->WriteMessage(
673 0 : WireFormatLite::kMessageSetMessageNumber, output);
674 : } else {
675 : WireFormatLite::WriteMessageMaybeToArray(
676 : WireFormatLite::kMessageSetMessageNumber,
677 0 : *message_value,
678 0 : output);
679 : }
680 :
681 : // End group.
682 0 : output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
683 : }
684 :
685 0 : int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
686 0 : if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
687 : // Not a valid MessageSet extension, but compute the byte size for it the
688 : // normal way.
689 0 : return ByteSize(number);
690 : }
691 :
692 0 : if (is_cleared) return 0;
693 :
694 0 : int our_size = WireFormatLite::kMessageSetItemTagsSize;
695 :
696 : // type_id
697 0 : our_size += io::CodedOutputStream::VarintSize32(number);
698 :
699 : // message
700 0 : int message_size = 0;
701 0 : if (is_lazy) {
702 0 : message_size = lazymessage_value->ByteSize();
703 : } else {
704 0 : message_size = message_value->ByteSize();
705 : }
706 :
707 0 : our_size += io::CodedOutputStream::VarintSize32(message_size);
708 0 : our_size += message_size;
709 :
710 0 : return our_size;
711 : }
712 :
713 0 : void ExtensionSet::SerializeMessageSetWithCachedSizes(
714 : io::CodedOutputStream* output) const {
715 0 : for (map<int, Extension>::const_iterator iter = extensions_.begin();
716 0 : iter != extensions_.end(); ++iter) {
717 0 : iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
718 : }
719 0 : }
720 :
721 0 : int ExtensionSet::MessageSetByteSize() const {
722 0 : int total_size = 0;
723 :
724 0 : for (map<int, Extension>::const_iterator iter = extensions_.begin();
725 0 : iter != extensions_.end(); ++iter) {
726 0 : total_size += iter->second.MessageSetItemByteSize(iter->first);
727 : }
728 :
729 0 : return total_size;
730 : }
731 :
732 : } // namespace internal
733 : } // namespace protobuf
734 : } // namespace google
|