1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <stack>
36 #include <string>
37 #include <vector>
38
39 #include <google/protobuf/wire_format.h>
40
41 #include <google/protobuf/stubs/logging.h>
42 #include <google/protobuf/stubs/common.h>
43 #include <google/protobuf/stubs/stringprintf.h>
44 #include <google/protobuf/descriptor.h>
45 #include <google/protobuf/wire_format_lite_inl.h>
46 #include <google/protobuf/descriptor.pb.h>
47 #include <google/protobuf/io/coded_stream.h>
48 #include <google/protobuf/io/zero_copy_stream.h>
49 #include <google/protobuf/io/zero_copy_stream_impl.h>
50 #include <google/protobuf/unknown_field_set.h>
51
52
53
54 namespace google {
55 namespace protobuf {
56 namespace internal {
57
58 // ===================================================================
59
SkipField(io::CodedInputStream * input,uint32 tag)60 bool UnknownFieldSetFieldSkipper::SkipField(
61 io::CodedInputStream* input, uint32 tag) {
62 return WireFormat::SkipField(input, tag, unknown_fields_);
63 }
64
SkipMessage(io::CodedInputStream * input)65 bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) {
66 return WireFormat::SkipMessage(input, unknown_fields_);
67 }
68
SkipUnknownEnum(int field_number,int value)69 void UnknownFieldSetFieldSkipper::SkipUnknownEnum(
70 int field_number, int value) {
71 unknown_fields_->AddVarint(field_number, value);
72 }
73
SkipField(io::CodedInputStream * input,uint32 tag,UnknownFieldSet * unknown_fields)74 bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
75 UnknownFieldSet* unknown_fields) {
76 int number = WireFormatLite::GetTagFieldNumber(tag);
77
78 switch (WireFormatLite::GetTagWireType(tag)) {
79 case WireFormatLite::WIRETYPE_VARINT: {
80 uint64 value;
81 if (!input->ReadVarint64(&value)) return false;
82 if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
83 return true;
84 }
85 case WireFormatLite::WIRETYPE_FIXED64: {
86 uint64 value;
87 if (!input->ReadLittleEndian64(&value)) return false;
88 if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
89 return true;
90 }
91 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
92 uint32 length;
93 if (!input->ReadVarint32(&length)) return false;
94 if (unknown_fields == NULL) {
95 if (!input->Skip(length)) return false;
96 } else {
97 if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
98 length)) {
99 return false;
100 }
101 }
102 return true;
103 }
104 case WireFormatLite::WIRETYPE_START_GROUP: {
105 if (!input->IncrementRecursionDepth()) return false;
106 if (!SkipMessage(input, (unknown_fields == NULL) ?
107 NULL : unknown_fields->AddGroup(number))) {
108 return false;
109 }
110 input->DecrementRecursionDepth();
111 // Check that the ending tag matched the starting tag.
112 if (!input->LastTagWas(WireFormatLite::MakeTag(
113 WireFormatLite::GetTagFieldNumber(tag),
114 WireFormatLite::WIRETYPE_END_GROUP))) {
115 return false;
116 }
117 return true;
118 }
119 case WireFormatLite::WIRETYPE_END_GROUP: {
120 return false;
121 }
122 case WireFormatLite::WIRETYPE_FIXED32: {
123 uint32 value;
124 if (!input->ReadLittleEndian32(&value)) return false;
125 if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value);
126 return true;
127 }
128 default: {
129 return false;
130 }
131 }
132 }
133
SkipMessage(io::CodedInputStream * input,UnknownFieldSet * unknown_fields)134 bool WireFormat::SkipMessage(io::CodedInputStream* input,
135 UnknownFieldSet* unknown_fields) {
136 while (true) {
137 uint32 tag = input->ReadTag();
138 if (tag == 0) {
139 // End of input. This is a valid place to end, so return true.
140 return true;
141 }
142
143 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
144
145 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
146 // Must be the end of the message.
147 return true;
148 }
149
150 if (!SkipField(input, tag, unknown_fields)) return false;
151 }
152 }
153
ReadPackedEnumPreserveUnknowns(io::CodedInputStream * input,uint32 field_number,bool (* is_valid)(int),UnknownFieldSet * unknown_fields,RepeatedField<int> * values)154 bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input,
155 uint32 field_number,
156 bool (*is_valid)(int),
157 UnknownFieldSet* unknown_fields,
158 RepeatedField<int>* values) {
159 uint32 length;
160 if (!input->ReadVarint32(&length)) return false;
161 io::CodedInputStream::Limit limit = input->PushLimit(length);
162 while (input->BytesUntilLimit() > 0) {
163 int value;
164 if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
165 int, WireFormatLite::TYPE_ENUM>(input, &value)) {
166 return false;
167 }
168 if (is_valid == NULL || is_valid(value)) {
169 values->Add(value);
170 } else {
171 unknown_fields->AddVarint(field_number, value);
172 }
173 }
174 input->PopLimit(limit);
175 return true;
176 }
177
178
SerializeUnknownFields(const UnknownFieldSet & unknown_fields,io::CodedOutputStream * output)179 void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
180 io::CodedOutputStream* output) {
181 for (int i = 0; i < unknown_fields.field_count(); i++) {
182 const UnknownField& field = unknown_fields.field(i);
183 switch (field.type()) {
184 case UnknownField::TYPE_VARINT:
185 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
186 WireFormatLite::WIRETYPE_VARINT));
187 output->WriteVarint64(field.varint());
188 break;
189 case UnknownField::TYPE_FIXED32:
190 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
191 WireFormatLite::WIRETYPE_FIXED32));
192 output->WriteLittleEndian32(field.fixed32());
193 break;
194 case UnknownField::TYPE_FIXED64:
195 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
196 WireFormatLite::WIRETYPE_FIXED64));
197 output->WriteLittleEndian64(field.fixed64());
198 break;
199 case UnknownField::TYPE_LENGTH_DELIMITED:
200 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
201 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
202 output->WriteVarint32(field.length_delimited().size());
203 output->WriteRawMaybeAliased(field.length_delimited().data(),
204 field.length_delimited().size());
205 break;
206 case UnknownField::TYPE_GROUP:
207 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
208 WireFormatLite::WIRETYPE_START_GROUP));
209 SerializeUnknownFields(field.group(), output);
210 output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
211 WireFormatLite::WIRETYPE_END_GROUP));
212 break;
213 }
214 }
215 }
216
SerializeUnknownFieldsToArray(const UnknownFieldSet & unknown_fields,uint8 * target)217 uint8* WireFormat::SerializeUnknownFieldsToArray(
218 const UnknownFieldSet& unknown_fields,
219 uint8* target) {
220 for (int i = 0; i < unknown_fields.field_count(); i++) {
221 const UnknownField& field = unknown_fields.field(i);
222
223 switch (field.type()) {
224 case UnknownField::TYPE_VARINT:
225 target = WireFormatLite::WriteInt64ToArray(
226 field.number(), field.varint(), target);
227 break;
228 case UnknownField::TYPE_FIXED32:
229 target = WireFormatLite::WriteFixed32ToArray(
230 field.number(), field.fixed32(), target);
231 break;
232 case UnknownField::TYPE_FIXED64:
233 target = WireFormatLite::WriteFixed64ToArray(
234 field.number(), field.fixed64(), target);
235 break;
236 case UnknownField::TYPE_LENGTH_DELIMITED:
237 target = WireFormatLite::WriteBytesToArray(
238 field.number(), field.length_delimited(), target);
239 break;
240 case UnknownField::TYPE_GROUP:
241 target = WireFormatLite::WriteTagToArray(
242 field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
243 target = SerializeUnknownFieldsToArray(field.group(), target);
244 target = WireFormatLite::WriteTagToArray(
245 field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
246 break;
247 }
248 }
249 return target;
250 }
251
SerializeUnknownMessageSetItems(const UnknownFieldSet & unknown_fields,io::CodedOutputStream * output)252 void WireFormat::SerializeUnknownMessageSetItems(
253 const UnknownFieldSet& unknown_fields,
254 io::CodedOutputStream* output) {
255 for (int i = 0; i < unknown_fields.field_count(); i++) {
256 const UnknownField& field = unknown_fields.field(i);
257 // The only unknown fields that are allowed to exist in a MessageSet are
258 // messages, which are length-delimited.
259 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
260 // Start group.
261 output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
262
263 // Write type ID.
264 output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
265 output->WriteVarint32(field.number());
266
267 // Write message.
268 output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
269 field.SerializeLengthDelimitedNoTag(output);
270
271 // End group.
272 output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
273 }
274 }
275 }
276
SerializeUnknownMessageSetItemsToArray(const UnknownFieldSet & unknown_fields,uint8 * target)277 uint8* WireFormat::SerializeUnknownMessageSetItemsToArray(
278 const UnknownFieldSet& unknown_fields,
279 uint8* target) {
280 for (int i = 0; i < unknown_fields.field_count(); i++) {
281 const UnknownField& field = unknown_fields.field(i);
282
283 // The only unknown fields that are allowed to exist in a MessageSet are
284 // messages, which are length-delimited.
285 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
286 // Start group.
287 target = io::CodedOutputStream::WriteTagToArray(
288 WireFormatLite::kMessageSetItemStartTag, target);
289
290 // Write type ID.
291 target = io::CodedOutputStream::WriteTagToArray(
292 WireFormatLite::kMessageSetTypeIdTag, target);
293 target = io::CodedOutputStream::WriteVarint32ToArray(
294 field.number(), target);
295
296 // Write message.
297 target = io::CodedOutputStream::WriteTagToArray(
298 WireFormatLite::kMessageSetMessageTag, target);
299 target = field.SerializeLengthDelimitedNoTagToArray(target);
300
301 // End group.
302 target = io::CodedOutputStream::WriteTagToArray(
303 WireFormatLite::kMessageSetItemEndTag, target);
304 }
305 }
306
307 return target;
308 }
309
ComputeUnknownFieldsSize(const UnknownFieldSet & unknown_fields)310 int WireFormat::ComputeUnknownFieldsSize(
311 const UnknownFieldSet& unknown_fields) {
312 int size = 0;
313 for (int i = 0; i < unknown_fields.field_count(); i++) {
314 const UnknownField& field = unknown_fields.field(i);
315
316 switch (field.type()) {
317 case UnknownField::TYPE_VARINT:
318 size += io::CodedOutputStream::VarintSize32(
319 WireFormatLite::MakeTag(field.number(),
320 WireFormatLite::WIRETYPE_VARINT));
321 size += io::CodedOutputStream::VarintSize64(field.varint());
322 break;
323 case UnknownField::TYPE_FIXED32:
324 size += io::CodedOutputStream::VarintSize32(
325 WireFormatLite::MakeTag(field.number(),
326 WireFormatLite::WIRETYPE_FIXED32));
327 size += sizeof(int32);
328 break;
329 case UnknownField::TYPE_FIXED64:
330 size += io::CodedOutputStream::VarintSize32(
331 WireFormatLite::MakeTag(field.number(),
332 WireFormatLite::WIRETYPE_FIXED64));
333 size += sizeof(int64);
334 break;
335 case UnknownField::TYPE_LENGTH_DELIMITED:
336 size += io::CodedOutputStream::VarintSize32(
337 WireFormatLite::MakeTag(field.number(),
338 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
339 size += io::CodedOutputStream::VarintSize32(
340 field.length_delimited().size());
341 size += field.length_delimited().size();
342 break;
343 case UnknownField::TYPE_GROUP:
344 size += io::CodedOutputStream::VarintSize32(
345 WireFormatLite::MakeTag(field.number(),
346 WireFormatLite::WIRETYPE_START_GROUP));
347 size += ComputeUnknownFieldsSize(field.group());
348 size += io::CodedOutputStream::VarintSize32(
349 WireFormatLite::MakeTag(field.number(),
350 WireFormatLite::WIRETYPE_END_GROUP));
351 break;
352 }
353 }
354
355 return size;
356 }
357
ComputeUnknownMessageSetItemsSize(const UnknownFieldSet & unknown_fields)358 int WireFormat::ComputeUnknownMessageSetItemsSize(
359 const UnknownFieldSet& unknown_fields) {
360 int size = 0;
361 for (int i = 0; i < unknown_fields.field_count(); i++) {
362 const UnknownField& field = unknown_fields.field(i);
363
364 // The only unknown fields that are allowed to exist in a MessageSet are
365 // messages, which are length-delimited.
366 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
367 size += WireFormatLite::kMessageSetItemTagsSize;
368 size += io::CodedOutputStream::VarintSize32(field.number());
369
370 int field_size = field.GetLengthDelimitedSize();
371 size += io::CodedOutputStream::VarintSize32(field_size);
372 size += field_size;
373 }
374 }
375
376 return size;
377 }
378
379 // ===================================================================
380
ParseAndMergePartial(io::CodedInputStream * input,Message * message)381 bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
382 Message* message) {
383 const Descriptor* descriptor = message->GetDescriptor();
384 const Reflection* message_reflection = message->GetReflection();
385
386 while(true) {
387 uint32 tag = input->ReadTag();
388 if (tag == 0) {
389 // End of input. This is a valid place to end, so return true.
390 return true;
391 }
392
393 if (WireFormatLite::GetTagWireType(tag) ==
394 WireFormatLite::WIRETYPE_END_GROUP) {
395 // Must be the end of the message.
396 return true;
397 }
398
399 const FieldDescriptor* field = NULL;
400
401 if (descriptor != NULL) {
402 int field_number = WireFormatLite::GetTagFieldNumber(tag);
403 field = descriptor->FindFieldByNumber(field_number);
404
405 // If that failed, check if the field is an extension.
406 if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
407 if (input->GetExtensionPool() == NULL) {
408 field = message_reflection->FindKnownExtensionByNumber(field_number);
409 } else {
410 field = input->GetExtensionPool()
411 ->FindExtensionByNumber(descriptor, field_number);
412 }
413 }
414
415 // If that failed, but we're a MessageSet, and this is the tag for a
416 // MessageSet item, then parse that.
417 if (field == NULL &&
418 descriptor->options().message_set_wire_format() &&
419 tag == WireFormatLite::kMessageSetItemStartTag) {
420 if (!ParseAndMergeMessageSetItem(input, message)) {
421 return false;
422 }
423 continue; // Skip ParseAndMergeField(); already taken care of.
424 }
425 }
426
427 if (!ParseAndMergeField(tag, field, message, input)) {
428 return false;
429 }
430 }
431 }
432
SkipMessageSetField(io::CodedInputStream * input,uint32 field_number,UnknownFieldSet * unknown_fields)433 bool WireFormat::SkipMessageSetField(io::CodedInputStream* input,
434 uint32 field_number,
435 UnknownFieldSet* unknown_fields) {
436 uint32 length;
437 if (!input->ReadVarint32(&length)) return false;
438 return input->ReadString(
439 unknown_fields->AddLengthDelimited(field_number), length);
440 }
441
ParseAndMergeMessageSetField(uint32 field_number,const FieldDescriptor * field,Message * message,io::CodedInputStream * input)442 bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number,
443 const FieldDescriptor* field,
444 Message* message,
445 io::CodedInputStream* input) {
446 const Reflection* message_reflection = message->GetReflection();
447 if (field == NULL) {
448 // We store unknown MessageSet extensions as groups.
449 return SkipMessageSetField(
450 input, field_number, message_reflection->MutableUnknownFields(message));
451 } else if (field->is_repeated() ||
452 field->type() != FieldDescriptor::TYPE_MESSAGE) {
453 // This shouldn't happen as we only allow optional message extensions to
454 // MessageSet.
455 GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages.";
456 return false;
457 } else {
458 Message* sub_message = message_reflection->MutableMessage(
459 message, field, input->GetExtensionFactory());
460 return WireFormatLite::ReadMessage(input, sub_message);
461 }
462 }
463
StrictUtf8Check(const FieldDescriptor * field)464 static bool StrictUtf8Check(const FieldDescriptor* field) {
465 return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
466 }
467
ParseAndMergeField(uint32 tag,const FieldDescriptor * field,Message * message,io::CodedInputStream * input)468 bool WireFormat::ParseAndMergeField(
469 uint32 tag,
470 const FieldDescriptor* field, // May be NULL for unknown
471 Message* message,
472 io::CodedInputStream* input) {
473 const Reflection* message_reflection = message->GetReflection();
474
475 enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
476
477 if (field == NULL) {
478 value_format = UNKNOWN;
479 } else if (WireFormatLite::GetTagWireType(tag) ==
480 WireTypeForFieldType(field->type())) {
481 value_format = NORMAL_FORMAT;
482 } else if (field->is_packable() &&
483 WireFormatLite::GetTagWireType(tag) ==
484 WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
485 value_format = PACKED_FORMAT;
486 } else {
487 // We don't recognize this field. Either the field number is unknown
488 // or the wire type doesn't match. Put it in our unknown field set.
489 value_format = UNKNOWN;
490 }
491
492 if (value_format == UNKNOWN) {
493 return SkipField(input, tag,
494 message_reflection->MutableUnknownFields(message));
495 } else if (value_format == PACKED_FORMAT) {
496 uint32 length;
497 if (!input->ReadVarint32(&length)) return false;
498 io::CodedInputStream::Limit limit = input->PushLimit(length);
499
500 switch (field->type()) {
501 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
502 case FieldDescriptor::TYPE_##TYPE: { \
503 while (input->BytesUntilLimit() > 0) { \
504 CPPTYPE value; \
505 if (!WireFormatLite::ReadPrimitive< \
506 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \
507 return false; \
508 message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
509 } \
510 break; \
511 }
512
513 HANDLE_PACKED_TYPE( INT32, int32, Int32)
514 HANDLE_PACKED_TYPE( INT64, int64, Int64)
515 HANDLE_PACKED_TYPE(SINT32, int32, Int32)
516 HANDLE_PACKED_TYPE(SINT64, int64, Int64)
517 HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
518 HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
519
520 HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32)
521 HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64)
522 HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
523 HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)
524
525 HANDLE_PACKED_TYPE(FLOAT , float , Float )
526 HANDLE_PACKED_TYPE(DOUBLE, double, Double)
527
528 HANDLE_PACKED_TYPE(BOOL, bool, Bool)
529 #undef HANDLE_PACKED_TYPE
530
531 case FieldDescriptor::TYPE_ENUM: {
532 while (input->BytesUntilLimit() > 0) {
533 int value;
534 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
535 input, &value)) return false;
536 if (message->GetDescriptor()->file()->syntax() ==
537 FileDescriptor::SYNTAX_PROTO3) {
538 message_reflection->AddEnumValue(message, field, value);
539 } else {
540 const EnumValueDescriptor* enum_value =
541 field->enum_type()->FindValueByNumber(value);
542 if (enum_value != NULL) {
543 message_reflection->AddEnum(message, field, enum_value);
544 } else {
545 // The enum value is not one of the known values. Add it to the
546 // UnknownFieldSet.
547 int64 sign_extended_value = static_cast<int64>(value);
548 message_reflection->MutableUnknownFields(message)
549 ->AddVarint(
550 WireFormatLite::GetTagFieldNumber(tag),
551 sign_extended_value);
552 }
553 }
554 }
555
556 break;
557 }
558
559 case FieldDescriptor::TYPE_STRING:
560 case FieldDescriptor::TYPE_GROUP:
561 case FieldDescriptor::TYPE_MESSAGE:
562 case FieldDescriptor::TYPE_BYTES:
563 // Can't have packed fields of these types: these should be caught by
564 // the protocol compiler.
565 return false;
566 break;
567 }
568
569 input->PopLimit(limit);
570 } else {
571 // Non-packed value (value_format == NORMAL_FORMAT)
572 switch (field->type()) {
573 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
574 case FieldDescriptor::TYPE_##TYPE: { \
575 CPPTYPE value; \
576 if (!WireFormatLite::ReadPrimitive< \
577 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \
578 return false; \
579 if (field->is_repeated()) { \
580 message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
581 } else { \
582 message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
583 } \
584 break; \
585 }
586
587 HANDLE_TYPE( INT32, int32, Int32)
588 HANDLE_TYPE( INT64, int64, Int64)
589 HANDLE_TYPE(SINT32, int32, Int32)
590 HANDLE_TYPE(SINT64, int64, Int64)
591 HANDLE_TYPE(UINT32, uint32, UInt32)
592 HANDLE_TYPE(UINT64, uint64, UInt64)
593
594 HANDLE_TYPE( FIXED32, uint32, UInt32)
595 HANDLE_TYPE( FIXED64, uint64, UInt64)
596 HANDLE_TYPE(SFIXED32, int32, Int32)
597 HANDLE_TYPE(SFIXED64, int64, Int64)
598
599 HANDLE_TYPE(FLOAT , float , Float )
600 HANDLE_TYPE(DOUBLE, double, Double)
601
602 HANDLE_TYPE(BOOL, bool, Bool)
603 #undef HANDLE_TYPE
604
605 case FieldDescriptor::TYPE_ENUM: {
606 int value;
607 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
608 input, &value)) return false;
609 if (message->GetDescriptor()->file()->syntax() ==
610 FileDescriptor::SYNTAX_PROTO3) {
611 if (field->is_repeated()) {
612 message_reflection->AddEnumValue(message, field, value);
613 } else {
614 message_reflection->SetEnumValue(message, field, value);
615 }
616 } else {
617 const EnumValueDescriptor* enum_value =
618 field->enum_type()->FindValueByNumber(value);
619 if (enum_value != NULL) {
620 if (field->is_repeated()) {
621 message_reflection->AddEnum(message, field, enum_value);
622 } else {
623 message_reflection->SetEnum(message, field, enum_value);
624 }
625 } else {
626 // The enum value is not one of the known values. Add it to the
627 // UnknownFieldSet.
628 int64 sign_extended_value = static_cast<int64>(value);
629 message_reflection->MutableUnknownFields(message)
630 ->AddVarint(
631 WireFormatLite::GetTagFieldNumber(tag),
632 sign_extended_value);
633 }
634 }
635 break;
636 }
637
638 // Handle strings separately so that we can optimize the ctype=CORD case.
639 case FieldDescriptor::TYPE_STRING: {
640 bool strict_utf8_check = StrictUtf8Check(field);
641 string value;
642 if (!WireFormatLite::ReadString(input, &value)) return false;
643 if (strict_utf8_check) {
644 if (!WireFormatLite::VerifyUtf8String(
645 value.data(), value.length(), WireFormatLite::PARSE,
646 field->full_name().c_str())) {
647 return false;
648 }
649 } else {
650 VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
651 field->full_name().c_str());
652 }
653 if (field->is_repeated()) {
654 message_reflection->AddString(message, field, value);
655 } else {
656 message_reflection->SetString(message, field, value);
657 }
658 break;
659 }
660
661 case FieldDescriptor::TYPE_BYTES: {
662 string value;
663 if (!WireFormatLite::ReadBytes(input, &value)) return false;
664 if (field->is_repeated()) {
665 message_reflection->AddString(message, field, value);
666 } else {
667 message_reflection->SetString(message, field, value);
668 }
669 break;
670 }
671
672 case FieldDescriptor::TYPE_GROUP: {
673 Message* sub_message;
674 if (field->is_repeated()) {
675 sub_message = message_reflection->AddMessage(
676 message, field, input->GetExtensionFactory());
677 } else {
678 sub_message = message_reflection->MutableMessage(
679 message, field, input->GetExtensionFactory());
680 }
681
682 if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
683 input, sub_message))
684 return false;
685 break;
686 }
687
688 case FieldDescriptor::TYPE_MESSAGE: {
689 Message* sub_message;
690 if (field->is_repeated()) {
691 sub_message = message_reflection->AddMessage(
692 message, field, input->GetExtensionFactory());
693 } else {
694 sub_message = message_reflection->MutableMessage(
695 message, field, input->GetExtensionFactory());
696 }
697
698 if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
699 break;
700 }
701 }
702 }
703
704 return true;
705 }
706
ParseAndMergeMessageSetItem(io::CodedInputStream * input,Message * message)707 bool WireFormat::ParseAndMergeMessageSetItem(
708 io::CodedInputStream* input,
709 Message* message) {
710 const Reflection* message_reflection = message->GetReflection();
711
712 // This method parses a group which should contain two fields:
713 // required int32 type_id = 2;
714 // required data message = 3;
715
716 uint32 last_type_id = 0;
717
718 // Once we see a type_id, we'll look up the FieldDescriptor for the
719 // extension.
720 const FieldDescriptor* field = NULL;
721
722 // If we see message data before the type_id, we'll append it to this so
723 // we can parse it later.
724 string message_data;
725
726 while (true) {
727 uint32 tag = input->ReadTag();
728 if (tag == 0) return false;
729
730 switch (tag) {
731 case WireFormatLite::kMessageSetTypeIdTag: {
732 uint32 type_id;
733 if (!input->ReadVarint32(&type_id)) return false;
734 last_type_id = type_id;
735 field = message_reflection->FindKnownExtensionByNumber(type_id);
736
737 if (!message_data.empty()) {
738 // We saw some message data before the type_id. Have to parse it
739 // now.
740 io::ArrayInputStream raw_input(message_data.data(),
741 message_data.size());
742 io::CodedInputStream sub_input(&raw_input);
743 if (!ParseAndMergeMessageSetField(last_type_id, field, message,
744 &sub_input)) {
745 return false;
746 }
747 message_data.clear();
748 }
749
750 break;
751 }
752
753 case WireFormatLite::kMessageSetMessageTag: {
754 if (last_type_id == 0) {
755 // We haven't seen a type_id yet. Append this data to message_data.
756 string temp;
757 uint32 length;
758 if (!input->ReadVarint32(&length)) return false;
759 if (!input->ReadString(&temp, length)) return false;
760 io::StringOutputStream output_stream(&message_data);
761 io::CodedOutputStream coded_output(&output_stream);
762 coded_output.WriteVarint32(length);
763 coded_output.WriteString(temp);
764 } else {
765 // Already saw type_id, so we can parse this directly.
766 if (!ParseAndMergeMessageSetField(last_type_id, field, message,
767 input)) {
768 return false;
769 }
770 }
771
772 break;
773 }
774
775 case WireFormatLite::kMessageSetItemEndTag: {
776 return true;
777 }
778
779 default: {
780 if (!SkipField(input, tag, NULL)) return false;
781 }
782 }
783 }
784 }
785
786 // ===================================================================
787
SerializeWithCachedSizes(const Message & message,int size,io::CodedOutputStream * output)788 void WireFormat::SerializeWithCachedSizes(
789 const Message& message,
790 int size, io::CodedOutputStream* output) {
791 const Descriptor* descriptor = message.GetDescriptor();
792 const Reflection* message_reflection = message.GetReflection();
793 int expected_endpoint = output->ByteCount() + size;
794
795 vector<const FieldDescriptor*> fields;
796 message_reflection->ListFields(message, &fields);
797 for (int i = 0; i < fields.size(); i++) {
798 SerializeFieldWithCachedSizes(fields[i], message, output);
799 }
800
801 if (descriptor->options().message_set_wire_format()) {
802 SerializeUnknownMessageSetItems(
803 message_reflection->GetUnknownFields(message), output);
804 } else {
805 SerializeUnknownFields(
806 message_reflection->GetUnknownFields(message), output);
807 }
808
809 GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint)
810 << ": Protocol message serialized to a size different from what was "
811 "originally expected. Perhaps it was modified by another thread "
812 "during serialization?";
813 }
814
SerializeFieldWithCachedSizes(const FieldDescriptor * field,const Message & message,io::CodedOutputStream * output)815 void WireFormat::SerializeFieldWithCachedSizes(
816 const FieldDescriptor* field,
817 const Message& message,
818 io::CodedOutputStream* output) {
819 const Reflection* message_reflection = message.GetReflection();
820
821 if (field->is_extension() &&
822 field->containing_type()->options().message_set_wire_format() &&
823 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
824 !field->is_repeated()) {
825 SerializeMessageSetItemWithCachedSizes(field, message, output);
826 return;
827 }
828
829 int count = 0;
830
831 if (field->is_repeated()) {
832 count = message_reflection->FieldSize(message, field);
833 } else if (message_reflection->HasField(message, field)) {
834 count = 1;
835 }
836
837 const bool is_packed = field->is_packed();
838 if (is_packed && count > 0) {
839 WireFormatLite::WriteTag(field->number(),
840 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
841 const int data_size = FieldDataOnlyByteSize(field, message);
842 output->WriteVarint32(data_size);
843 }
844
845 for (int j = 0; j < count; j++) {
846 switch (field->type()) {
847 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \
848 case FieldDescriptor::TYPE_##TYPE: { \
849 const CPPTYPE value = field->is_repeated() ? \
850 message_reflection->GetRepeated##CPPTYPE_METHOD( \
851 message, field, j) : \
852 message_reflection->Get##CPPTYPE_METHOD( \
853 message, field); \
854 if (is_packed) { \
855 WireFormatLite::Write##TYPE_METHOD##NoTag(value, output); \
856 } else { \
857 WireFormatLite::Write##TYPE_METHOD(field->number(), value, output); \
858 } \
859 break; \
860 }
861
862 HANDLE_PRIMITIVE_TYPE( INT32, int32, Int32, Int32)
863 HANDLE_PRIMITIVE_TYPE( INT64, int64, Int64, Int64)
864 HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32)
865 HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64)
866 HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
867 HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
868
869 HANDLE_PRIMITIVE_TYPE( FIXED32, uint32, Fixed32, UInt32)
870 HANDLE_PRIMITIVE_TYPE( FIXED64, uint64, Fixed64, UInt64)
871 HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32)
872 HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64)
873
874 HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
875 HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
876
877 HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
878 #undef HANDLE_PRIMITIVE_TYPE
879
880 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
881 case FieldDescriptor::TYPE_##TYPE: \
882 WireFormatLite::Write##TYPE_METHOD( \
883 field->number(), \
884 field->is_repeated() ? \
885 message_reflection->GetRepeated##CPPTYPE_METHOD( \
886 message, field, j) : \
887 message_reflection->Get##CPPTYPE_METHOD(message, field), \
888 output); \
889 break;
890
891 HANDLE_TYPE(GROUP , Group , Message)
892 HANDLE_TYPE(MESSAGE, Message, Message)
893 #undef HANDLE_TYPE
894
895 case FieldDescriptor::TYPE_ENUM: {
896 const EnumValueDescriptor* value = field->is_repeated() ?
897 message_reflection->GetRepeatedEnum(message, field, j) :
898 message_reflection->GetEnum(message, field);
899 if (is_packed) {
900 WireFormatLite::WriteEnumNoTag(value->number(), output);
901 } else {
902 WireFormatLite::WriteEnum(field->number(), value->number(), output);
903 }
904 break;
905 }
906
907 // Handle strings separately so that we can get string references
908 // instead of copying.
909 case FieldDescriptor::TYPE_STRING: {
910 bool strict_utf8_check = StrictUtf8Check(field);
911 string scratch;
912 const string& value = field->is_repeated() ?
913 message_reflection->GetRepeatedStringReference(
914 message, field, j, &scratch) :
915 message_reflection->GetStringReference(message, field, &scratch);
916 if (strict_utf8_check) {
917 WireFormatLite::VerifyUtf8String(value.data(), value.length(),
918 WireFormatLite::SERIALIZE,
919 field->full_name().c_str());
920 } else {
921 VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
922 field->full_name().c_str());
923 }
924 WireFormatLite::WriteString(field->number(), value, output);
925 break;
926 }
927
928 case FieldDescriptor::TYPE_BYTES: {
929 string scratch;
930 const string& value = field->is_repeated() ?
931 message_reflection->GetRepeatedStringReference(
932 message, field, j, &scratch) :
933 message_reflection->GetStringReference(message, field, &scratch);
934 WireFormatLite::WriteBytes(field->number(), value, output);
935 break;
936 }
937 }
938 }
939 }
940
SerializeMessageSetItemWithCachedSizes(const FieldDescriptor * field,const Message & message,io::CodedOutputStream * output)941 void WireFormat::SerializeMessageSetItemWithCachedSizes(
942 const FieldDescriptor* field,
943 const Message& message,
944 io::CodedOutputStream* output) {
945 const Reflection* message_reflection = message.GetReflection();
946
947 // Start group.
948 output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
949
950 // Write type ID.
951 output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
952 output->WriteVarint32(field->number());
953
954 // Write message.
955 output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
956
957 const Message& sub_message = message_reflection->GetMessage(message, field);
958 output->WriteVarint32(sub_message.GetCachedSize());
959 sub_message.SerializeWithCachedSizes(output);
960
961 // End group.
962 output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
963 }
964
965 // ===================================================================
966
ByteSize(const Message & message)967 int WireFormat::ByteSize(const Message& message) {
968 const Descriptor* descriptor = message.GetDescriptor();
969 const Reflection* message_reflection = message.GetReflection();
970
971 int our_size = 0;
972
973 vector<const FieldDescriptor*> fields;
974 message_reflection->ListFields(message, &fields);
975 for (int i = 0; i < fields.size(); i++) {
976 our_size += FieldByteSize(fields[i], message);
977 }
978
979 if (descriptor->options().message_set_wire_format()) {
980 our_size += ComputeUnknownMessageSetItemsSize(
981 message_reflection->GetUnknownFields(message));
982 } else {
983 our_size += ComputeUnknownFieldsSize(
984 message_reflection->GetUnknownFields(message));
985 }
986
987 return our_size;
988 }
989
FieldByteSize(const FieldDescriptor * field,const Message & message)990 int WireFormat::FieldByteSize(
991 const FieldDescriptor* field,
992 const Message& message) {
993 const Reflection* message_reflection = message.GetReflection();
994
995 if (field->is_extension() &&
996 field->containing_type()->options().message_set_wire_format() &&
997 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
998 !field->is_repeated()) {
999 return MessageSetItemByteSize(field, message);
1000 }
1001
1002 int count = 0;
1003 if (field->is_repeated()) {
1004 count = message_reflection->FieldSize(message, field);
1005 } else if (message_reflection->HasField(message, field)) {
1006 count = 1;
1007 }
1008
1009 const int data_size = FieldDataOnlyByteSize(field, message);
1010 int our_size = data_size;
1011 if (field->is_packed()) {
1012 if (data_size > 0) {
1013 // Packed fields get serialized like a string, not their native type.
1014 // Technically this doesn't really matter; the size only changes if it's
1015 // a GROUP
1016 our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
1017 our_size += io::CodedOutputStream::VarintSize32(data_size);
1018 }
1019 } else {
1020 our_size += count * TagSize(field->number(), field->type());
1021 }
1022 return our_size;
1023 }
1024
FieldDataOnlyByteSize(const FieldDescriptor * field,const Message & message)1025 int WireFormat::FieldDataOnlyByteSize(
1026 const FieldDescriptor* field,
1027 const Message& message) {
1028 const Reflection* message_reflection = message.GetReflection();
1029
1030 int count = 0;
1031 if (field->is_repeated()) {
1032 count = message_reflection->FieldSize(message, field);
1033 } else if (message_reflection->HasField(message, field)) {
1034 count = 1;
1035 }
1036
1037 int data_size = 0;
1038 switch (field->type()) {
1039 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
1040 case FieldDescriptor::TYPE_##TYPE: \
1041 if (field->is_repeated()) { \
1042 for (int j = 0; j < count; j++) { \
1043 data_size += WireFormatLite::TYPE_METHOD##Size( \
1044 message_reflection->GetRepeated##CPPTYPE_METHOD( \
1045 message, field, j)); \
1046 } \
1047 } else { \
1048 data_size += WireFormatLite::TYPE_METHOD##Size( \
1049 message_reflection->Get##CPPTYPE_METHOD(message, field)); \
1050 } \
1051 break;
1052
1053 #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \
1054 case FieldDescriptor::TYPE_##TYPE: \
1055 data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \
1056 break;
1057
1058 HANDLE_TYPE( INT32, Int32, Int32)
1059 HANDLE_TYPE( INT64, Int64, Int64)
1060 HANDLE_TYPE(SINT32, SInt32, Int32)
1061 HANDLE_TYPE(SINT64, SInt64, Int64)
1062 HANDLE_TYPE(UINT32, UInt32, UInt32)
1063 HANDLE_TYPE(UINT64, UInt64, UInt64)
1064
1065 HANDLE_FIXED_TYPE( FIXED32, Fixed32)
1066 HANDLE_FIXED_TYPE( FIXED64, Fixed64)
1067 HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
1068 HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
1069
1070 HANDLE_FIXED_TYPE(FLOAT , Float )
1071 HANDLE_FIXED_TYPE(DOUBLE, Double)
1072
1073 HANDLE_FIXED_TYPE(BOOL, Bool)
1074
1075 HANDLE_TYPE(GROUP , Group , Message)
1076 HANDLE_TYPE(MESSAGE, Message, Message)
1077 #undef HANDLE_TYPE
1078 #undef HANDLE_FIXED_TYPE
1079
1080 case FieldDescriptor::TYPE_ENUM: {
1081 if (field->is_repeated()) {
1082 for (int j = 0; j < count; j++) {
1083 data_size += WireFormatLite::EnumSize(
1084 message_reflection->GetRepeatedEnum(message, field, j)->number());
1085 }
1086 } else {
1087 data_size += WireFormatLite::EnumSize(
1088 message_reflection->GetEnum(message, field)->number());
1089 }
1090 break;
1091 }
1092
1093 // Handle strings separately so that we can get string references
1094 // instead of copying.
1095 case FieldDescriptor::TYPE_STRING:
1096 case FieldDescriptor::TYPE_BYTES: {
1097 for (int j = 0; j < count; j++) {
1098 string scratch;
1099 const string& value = field->is_repeated() ?
1100 message_reflection->GetRepeatedStringReference(
1101 message, field, j, &scratch) :
1102 message_reflection->GetStringReference(message, field, &scratch);
1103 data_size += WireFormatLite::StringSize(value);
1104 }
1105 break;
1106 }
1107 }
1108 return data_size;
1109 }
1110
MessageSetItemByteSize(const FieldDescriptor * field,const Message & message)1111 int WireFormat::MessageSetItemByteSize(
1112 const FieldDescriptor* field,
1113 const Message& message) {
1114 const Reflection* message_reflection = message.GetReflection();
1115
1116 int our_size = WireFormatLite::kMessageSetItemTagsSize;
1117
1118 // type_id
1119 our_size += io::CodedOutputStream::VarintSize32(field->number());
1120
1121 // message
1122 const Message& sub_message = message_reflection->GetMessage(message, field);
1123 int message_size = sub_message.ByteSize();
1124
1125 our_size += io::CodedOutputStream::VarintSize32(message_size);
1126 our_size += message_size;
1127
1128 return our_size;
1129 }
1130
1131 } // namespace internal
1132 } // namespace protobuf
1133 } // namespace google
1134