1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
39 #include <google/protobuf/wire_format.h>
41 #include <google/protobuf/stubs/common.h>
42 #include <google/protobuf/descriptor.h>
43 #include <google/protobuf/wire_format_lite_inl.h>
44 #include <google/protobuf/descriptor.pb.h>
45 #include <google/protobuf/io/coded_stream.h>
46 #include <google/protobuf/io/zero_copy_stream.h>
47 #include <google/protobuf/io/zero_copy_stream_impl.h>
48 #include <google/protobuf/unknown_field_set.h>
58 // This function turns out to be convenient when using some macros later.
59 inline int GetEnumNumber(const EnumValueDescriptor* descriptor) {
60 return descriptor->number();
63 } // anonymous namespace
65 bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
67 const Descriptor* descriptor = message->GetDescriptor();
68 const Reflection* message_reflection = message->GetReflection();
71 uint32 tag = input->ReadTag();
73 // End of input. This is a valid place to end, so return true.
77 if (WireFormatLite::GetTagWireType(tag) ==
78 WireFormatLite::WIRETYPE_END_GROUP) {
79 // Must be the end of the message.
83 const FieldDescriptor* field = NULL;
85 if (descriptor != NULL) {
86 int field_number = WireFormatLite::GetTagFieldNumber(tag);
87 field = descriptor->FindFieldByNumber(field_number);
89 // If that failed, check if the field is an extension.
90 if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
91 if (input->GetExtensionPool() == NULL) {
92 field = message_reflection->FindKnownExtensionByNumber(field_number);
94 field = input->GetExtensionPool()
95 ->FindExtensionByNumber(descriptor, field_number);
99 // If that failed, but we're a MessageSet, and this is the tag for a
100 // MessageSet item, then parse that.
102 descriptor->options().message_set_wire_format() &&
103 tag == WireFormatLite::kMessageSetItemStartTag) {
104 if (!ParseAndMergeMessageSetItem(input, message)) {
107 continue; // Skip ParseAndMergeField(); already taken care of.
111 if (!ParseAndMergeField(tag, field, message, input)) {
117 bool WireFormat::ParseAndMergeField(
119 const FieldDescriptor* field, // May be NULL for unknown
121 io::CodedInputStream* input) {
122 const Reflection* message_reflection = message->GetReflection();
124 enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
127 value_format = UNKNOWN;
128 } else if (WireFormatLite::GetTagWireType(tag) ==
129 WireTypeForFieldType(field->type())) {
130 value_format = NORMAL_FORMAT;
131 } else if (field->is_packable() &&
132 WireFormatLite::GetTagWireType(tag) ==
133 WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
134 value_format = PACKED_FORMAT;
136 // We don't recognize this field. Either the field number is unknown
137 // or the wire type doesn't match. Put it in our unknown field set.
138 value_format = UNKNOWN;
141 if (value_format == UNKNOWN) {
142 return WireFormatLite::SkipField(
143 input, tag, message_reflection->MutableUnknownFields(message));
144 } else if (value_format == PACKED_FORMAT) {
146 if (!input->ReadVarint32(&length)) return false;
147 io::CodedInputStream::Limit limit = input->PushLimit(length);
149 switch (field->type()) {
150 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
151 case FieldDescriptor::TYPE_##TYPE: { \
152 while (input->BytesUntilLimit() > 0) { \
154 if (!WireFormatLite::ReadPrimitive< \
155 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \
157 message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
162 HANDLE_PACKED_TYPE( INT32, int32, Int32)
163 HANDLE_PACKED_TYPE( INT64, int64, Int64)
164 HANDLE_PACKED_TYPE(SINT32, int32, Int32)
165 HANDLE_PACKED_TYPE(SINT64, int64, Int64)
166 HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
167 HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
169 HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32)
170 HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64)
171 HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
172 HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)
174 HANDLE_PACKED_TYPE(FLOAT , float , Float )
175 HANDLE_PACKED_TYPE(DOUBLE, double, Double)
177 HANDLE_PACKED_TYPE(BOOL, bool, Bool)
178 #undef HANDLE_PACKED_TYPE
180 case FieldDescriptor::TYPE_ENUM: {
181 while (input->BytesUntilLimit() > 0) {
183 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
184 input, &value)) return false;
185 const EnumValueDescriptor* enum_value =
186 field->enum_type()->FindValueByNumber(value);
187 if (enum_value != NULL) {
188 message_reflection->AddEnum(message, field, enum_value);
195 case FieldDescriptor::TYPE_STRING:
196 case FieldDescriptor::TYPE_GROUP:
197 case FieldDescriptor::TYPE_MESSAGE:
198 case FieldDescriptor::TYPE_BYTES:
199 // Can't have packed fields of these types: these should be caught by
200 // the protocol compiler.
205 input->PopLimit(limit);
207 // Non-packed value (value_format == NORMAL_FORMAT)
208 switch (field->type()) {
209 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
210 case FieldDescriptor::TYPE_##TYPE: { \
212 if (!WireFormatLite::ReadPrimitive< \
213 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \
215 if (field->is_repeated()) { \
216 message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
218 message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
223 HANDLE_TYPE( INT32, int32, Int32)
224 HANDLE_TYPE( INT64, int64, Int64)
225 HANDLE_TYPE(SINT32, int32, Int32)
226 HANDLE_TYPE(SINT64, int64, Int64)
227 HANDLE_TYPE(UINT32, uint32, UInt32)
228 HANDLE_TYPE(UINT64, uint64, UInt64)
230 HANDLE_TYPE( FIXED32, uint32, UInt32)
231 HANDLE_TYPE( FIXED64, uint64, UInt64)
232 HANDLE_TYPE(SFIXED32, int32, Int32)
233 HANDLE_TYPE(SFIXED64, int64, Int64)
235 HANDLE_TYPE(FLOAT , float , Float )
236 HANDLE_TYPE(DOUBLE, double, Double)
238 HANDLE_TYPE(BOOL, bool, Bool)
241 case FieldDescriptor::TYPE_ENUM: {
243 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
244 input, &value)) return false;
245 const EnumValueDescriptor* enum_value =
246 field->enum_type()->FindValueByNumber(value);
247 if (enum_value != NULL) {
248 if (field->is_repeated()) {
249 message_reflection->AddEnum(message, field, enum_value);
251 message_reflection->SetEnum(message, field, enum_value);
254 // The enum value is not one of the known values. Add it to the
256 int64 sign_extended_value = static_cast<int64>(value);
257 message_reflection->MutableUnknownFields(message)
258 ->AddVarint(WireFormatLite::GetTagFieldNumber(tag),
259 sign_extended_value);
264 // Handle strings separately so that we can optimize the ctype=CORD case.
265 case FieldDescriptor::TYPE_STRING: {
267 if (!WireFormatLite::ReadString(input, &value)) return false;
268 VerifyUTF8String(value.data(), value.length(), PARSE);
269 if (field->is_repeated()) {
270 message_reflection->AddString(message, field, value);
272 message_reflection->SetString(message, field, value);
277 case FieldDescriptor::TYPE_BYTES: {
279 if (!WireFormatLite::ReadBytes(input, &value)) return false;
280 if (field->is_repeated()) {
281 message_reflection->AddString(message, field, value);
283 message_reflection->SetString(message, field, value);
288 case FieldDescriptor::TYPE_GROUP: {
289 Message* sub_message;
290 if (field->is_repeated()) {
291 sub_message = message_reflection->AddMessage(
292 message, field, input->GetExtensionFactory());
294 sub_message = message_reflection->MutableMessage(
295 message, field, input->GetExtensionFactory());
298 if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
304 case FieldDescriptor::TYPE_MESSAGE: {
305 Message* sub_message;
306 if (field->is_repeated()) {
307 sub_message = message_reflection->AddMessage(
308 message, field, input->GetExtensionFactory());
310 sub_message = message_reflection->MutableMessage(
311 message, field, input->GetExtensionFactory());
314 if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
323 bool WireFormat::ParseAndMergeMessageSetItem(
324 io::CodedInputStream* input,
326 const Reflection* message_reflection = message->GetReflection();
328 // This method parses a group which should contain two fields:
329 // required int32 type_id = 2;
330 // required data message = 3;
332 // Once we see a type_id, we'll construct a fake tag for this extension
333 // which is the tag it would have had under the proto2 extensions wire
337 // Once we see a type_id, we'll look up the FieldDescriptor for the
339 const FieldDescriptor* field = NULL;
341 // If we see message data before the type_id, we'll append it to this so
342 // we can parse it later.
346 uint32 tag = input->ReadTag();
347 if (tag == 0) return false;
350 case WireFormatLite::kMessageSetTypeIdTag: {
352 if (!input->ReadVarint32(&type_id)) return false;
353 fake_tag = WireFormatLite::MakeTag(
354 type_id, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
355 field = message_reflection->FindKnownExtensionByNumber(type_id);
357 if (!message_data.empty()) {
358 // We saw some message data before the type_id. Have to parse it
360 io::ArrayInputStream raw_input(message_data.data(),
361 message_data.size());
362 io::CodedInputStream sub_input(&raw_input);
363 if (!ParseAndMergeField(fake_tag, field, message,
367 message_data.clear();
373 case WireFormatLite::kMessageSetMessageTag: {
375 // We haven't seen a type_id yet. Append this data to message_data.
378 if (!input->ReadVarint32(&length)) return false;
379 if (!input->ReadString(&temp, length)) return false;
380 io::StringOutputStream output_stream(&message_data);
381 io::CodedOutputStream coded_output(&output_stream);
382 coded_output.WriteVarint32(length);
383 coded_output.WriteString(temp);
385 // Already saw type_id, so we can parse this directly.
386 if (!ParseAndMergeField(fake_tag, field, message, input)) {
394 case WireFormatLite::kMessageSetItemEndTag: {
399 if (!WireFormatLite::SkipField(input, tag, NULL)) return false;
405 // ===================================================================
407 void WireFormat::SerializeWithCachedSizes(
408 const Message& message,
409 int size, io::CodedOutputStream* output) {
410 const Descriptor* descriptor = message.GetDescriptor();
411 const Reflection* message_reflection = message.GetReflection();
412 int expected_endpoint = output->ByteCount() + size;
414 vector<const FieldDescriptor*> fields;
415 message_reflection->ListFields(message, &fields);
416 for (int i = 0; i < fields.size(); i++) {
417 SerializeFieldWithCachedSizes(fields[i], message, output);
420 if (descriptor->options().message_set_wire_format()) {
421 WireFormatLite::SerializeUnknownMessageSetItems(
422 message_reflection->GetUnknownFields(message), output);
424 WireFormatLite::SerializeUnknownFields(
425 message_reflection->GetUnknownFields(message), output);
428 GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint)
429 << ": Protocol message serialized to a size different from what was "
430 "originally expected. Perhaps it was modified by another thread "
431 "during serialization?";
434 void WireFormat::SerializeFieldWithCachedSizes(
435 const FieldDescriptor* field,
436 const Message& message,
437 io::CodedOutputStream* output) {
438 const Reflection* message_reflection = message.GetReflection();
440 if (field->is_extension() &&
441 field->containing_type()->options().message_set_wire_format() &&
442 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
443 !field->is_repeated()) {
444 SerializeMessageSetItemWithCachedSizes(field, message, output);
450 if (field->is_repeated()) {
451 count = message_reflection->FieldSize(message, field);
452 } else if (message_reflection->HasField(message, field)) {
456 const bool is_packed = field->options().packed();
457 if (is_packed && count > 0) {
458 WireFormatLite::WriteTag(field->number(),
459 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
460 const int data_size = FieldDataOnlyByteSize(field, message);
461 output->WriteVarint32(data_size);
464 for (int j = 0; j < count; j++) {
465 switch (field->type()) {
466 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \
467 case FieldDescriptor::TYPE_##TYPE: { \
468 const CPPTYPE value = field->is_repeated() ? \
469 message_reflection->GetRepeated##CPPTYPE_METHOD( \
470 message, field, j) : \
471 message_reflection->Get##CPPTYPE_METHOD( \
474 WireFormatLite::Write##TYPE_METHOD##NoTag(value, output); \
476 WireFormatLite::Write##TYPE_METHOD(field->number(), value, output); \
481 HANDLE_PRIMITIVE_TYPE( INT32, int32, Int32, Int32)
482 HANDLE_PRIMITIVE_TYPE( INT64, int64, Int64, Int64)
483 HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32)
484 HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64)
485 HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
486 HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
488 HANDLE_PRIMITIVE_TYPE( FIXED32, uint32, Fixed32, UInt32)
489 HANDLE_PRIMITIVE_TYPE( FIXED64, uint64, Fixed64, UInt64)
490 HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32)
491 HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64)
493 HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
494 HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
496 HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
497 #undef HANDLE_PRIMITIVE_TYPE
499 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
500 case FieldDescriptor::TYPE_##TYPE: \
501 WireFormatLite::Write##TYPE_METHOD( \
503 field->is_repeated() ? \
504 message_reflection->GetRepeated##CPPTYPE_METHOD( \
505 message, field, j) : \
506 message_reflection->Get##CPPTYPE_METHOD(message, field), \
510 HANDLE_TYPE(GROUP , Group , Message)
511 HANDLE_TYPE(MESSAGE, Message, Message)
514 case FieldDescriptor::TYPE_ENUM: {
515 const EnumValueDescriptor* value = field->is_repeated() ?
516 message_reflection->GetRepeatedEnum(message, field, j) :
517 message_reflection->GetEnum(message, field);
519 WireFormatLite::WriteEnumNoTag(value->number(), output);
521 WireFormatLite::WriteEnum(field->number(), value->number(), output);
526 // Handle strings separately so that we can get string references
527 // instead of copying.
528 case FieldDescriptor::TYPE_STRING: {
530 const string& value = field->is_repeated() ?
531 message_reflection->GetRepeatedStringReference(
532 message, field, j, &scratch) :
533 message_reflection->GetStringReference(message, field, &scratch);
534 VerifyUTF8String(value.data(), value.length(), SERIALIZE);
535 WireFormatLite::WriteString(field->number(), value, output);
539 case FieldDescriptor::TYPE_BYTES: {
541 const string& value = field->is_repeated() ?
542 message_reflection->GetRepeatedStringReference(
543 message, field, j, &scratch) :
544 message_reflection->GetStringReference(message, field, &scratch);
545 WireFormatLite::WriteBytes(field->number(), value, output);
552 void WireFormat::SerializeMessageSetItemWithCachedSizes(
553 const FieldDescriptor* field,
554 const Message& message,
555 io::CodedOutputStream* output) {
556 const Reflection* message_reflection = message.GetReflection();
559 output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
562 output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
563 output->WriteVarint32(field->number());
566 output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
568 const Message& sub_message = message_reflection->GetMessage(message, field);
569 output->WriteVarint32(sub_message.GetCachedSize());
570 sub_message.SerializeWithCachedSizes(output);
573 output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
576 // ===================================================================
578 int WireFormat::ByteSize(const Message& message) {
579 const Descriptor* descriptor = message.GetDescriptor();
580 const Reflection* message_reflection = message.GetReflection();
584 vector<const FieldDescriptor*> fields;
585 message_reflection->ListFields(message, &fields);
586 for (int i = 0; i < fields.size(); i++) {
587 our_size += FieldByteSize(fields[i], message);
590 if (descriptor->options().message_set_wire_format()) {
591 our_size += WireFormatLite::ComputeUnknownMessageSetItemsSize(
592 message_reflection->GetUnknownFields(message));
594 our_size += WireFormatLite::ComputeUnknownFieldsSize(
595 message_reflection->GetUnknownFields(message));
601 int WireFormat::FieldByteSize(
602 const FieldDescriptor* field,
603 const Message& message) {
604 const Reflection* message_reflection = message.GetReflection();
606 if (field->is_extension() &&
607 field->containing_type()->options().message_set_wire_format() &&
608 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
609 !field->is_repeated()) {
610 return MessageSetItemByteSize(field, message);
614 if (field->is_repeated()) {
615 count = message_reflection->FieldSize(message, field);
616 } else if (message_reflection->HasField(message, field)) {
620 const int data_size = FieldDataOnlyByteSize(field, message);
621 int our_size = data_size;
622 if (field->options().packed()) {
624 // Packed fields get serialized like a string, not their native type.
625 // Technically this doesn't really matter; the size only changes if it's
627 our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
628 our_size += io::CodedOutputStream::VarintSize32(data_size);
631 our_size += count * TagSize(field->number(), field->type());
636 int WireFormat::FieldDataOnlyByteSize(
637 const FieldDescriptor* field,
638 const Message& message) {
639 const Reflection* message_reflection = message.GetReflection();
642 if (field->is_repeated()) {
643 count = message_reflection->FieldSize(message, field);
644 } else if (message_reflection->HasField(message, field)) {
649 switch (field->type()) {
650 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
651 case FieldDescriptor::TYPE_##TYPE: \
652 if (field->is_repeated()) { \
653 for (int j = 0; j < count; j++) { \
654 data_size += WireFormatLite::TYPE_METHOD##Size( \
655 message_reflection->GetRepeated##CPPTYPE_METHOD( \
656 message, field, j)); \
659 data_size += WireFormatLite::TYPE_METHOD##Size( \
660 message_reflection->Get##CPPTYPE_METHOD(message, field)); \
664 #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \
665 case FieldDescriptor::TYPE_##TYPE: \
666 data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \
669 HANDLE_TYPE( INT32, Int32, Int32)
670 HANDLE_TYPE( INT64, Int64, Int64)
671 HANDLE_TYPE(SINT32, SInt32, Int32)
672 HANDLE_TYPE(SINT64, SInt64, Int64)
673 HANDLE_TYPE(UINT32, UInt32, UInt32)
674 HANDLE_TYPE(UINT64, UInt64, UInt64)
676 HANDLE_FIXED_TYPE( FIXED32, Fixed32)
677 HANDLE_FIXED_TYPE( FIXED64, Fixed64)
678 HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
679 HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
681 HANDLE_FIXED_TYPE(FLOAT , Float )
682 HANDLE_FIXED_TYPE(DOUBLE, Double)
684 HANDLE_FIXED_TYPE(BOOL, Bool)
686 HANDLE_TYPE(GROUP , Group , Message)
687 HANDLE_TYPE(MESSAGE, Message, Message)
689 #undef HANDLE_FIXED_TYPE
691 case FieldDescriptor::TYPE_ENUM: {
692 if (field->is_repeated()) {
693 for (int j = 0; j < count; j++) {
694 data_size += WireFormatLite::EnumSize(
695 message_reflection->GetRepeatedEnum(message, field, j)->number());
698 data_size += WireFormatLite::EnumSize(
699 message_reflection->GetEnum(message, field)->number());
704 // Handle strings separately so that we can get string references
705 // instead of copying.
706 case FieldDescriptor::TYPE_STRING:
707 case FieldDescriptor::TYPE_BYTES: {
708 for (int j = 0; j < count; j++) {
710 const string& value = field->is_repeated() ?
711 message_reflection->GetRepeatedStringReference(
712 message, field, j, &scratch) :
713 message_reflection->GetStringReference(message, field, &scratch);
714 data_size += WireFormatLite::StringSize(value);
722 int WireFormat::MessageSetItemByteSize(
723 const FieldDescriptor* field,
724 const Message& message) {
725 const Reflection* message_reflection = message.GetReflection();
727 int our_size = WireFormatLite::kMessageSetItemTagsSize;
730 our_size += io::CodedOutputStream::VarintSize32(field->number());
733 const Message& sub_message = message_reflection->GetMessage(message, field);
734 int message_size = sub_message.ByteSize();
736 our_size += io::CodedOutputStream::VarintSize32(message_size);
737 our_size += message_size;
742 void WireFormat::VerifyUTF8StringFallback(const char* data,
745 if (!IsStructurallyValidUTF8(data, size)) {
746 const char* operation_str = NULL;
749 operation_str = "parsing";
752 operation_str = "serializing";
754 // no default case: have the compiler warn if a case is not covered.
756 GOOGLE_LOG(ERROR) << "String field contains invalid UTF-8 data when "
758 << " a protocol buffer. Use the 'bytes' type if you intend to "
764 } // namespace internal
765 } // namespace protobuf
766 } // namespace google