- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / protobuf / src / google / protobuf / wire_format.cc
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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/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>
49
50
51
52 namespace google {
53 namespace protobuf {
54 namespace internal {
55
56 namespace {
57
58 // This function turns out to be convenient when using some macros later.
59 inline int GetEnumNumber(const EnumValueDescriptor* descriptor) {
60   return descriptor->number();
61 }
62
63 }  // anonymous namespace
64
65 bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
66                                       Message* message) {
67   const Descriptor* descriptor = message->GetDescriptor();
68   const Reflection* message_reflection = message->GetReflection();
69
70   while(true) {
71     uint32 tag = input->ReadTag();
72     if (tag == 0) {
73       // End of input.  This is a valid place to end, so return true.
74       return true;
75     }
76
77     if (WireFormatLite::GetTagWireType(tag) ==
78         WireFormatLite::WIRETYPE_END_GROUP) {
79       // Must be the end of the message.
80       return true;
81     }
82
83     const FieldDescriptor* field = NULL;
84
85     if (descriptor != NULL) {
86       int field_number = WireFormatLite::GetTagFieldNumber(tag);
87       field = descriptor->FindFieldByNumber(field_number);
88
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);
93         } else {
94           field = input->GetExtensionPool()
95                        ->FindExtensionByNumber(descriptor, field_number);
96         }
97       }
98
99       // If that failed, but we're a MessageSet, and this is the tag for a
100       // MessageSet item, then parse that.
101       if (field == NULL &&
102           descriptor->options().message_set_wire_format() &&
103           tag == WireFormatLite::kMessageSetItemStartTag) {
104         if (!ParseAndMergeMessageSetItem(input, message)) {
105           return false;
106         }
107         continue;  // Skip ParseAndMergeField(); already taken care of.
108       }
109     }
110
111     if (!ParseAndMergeField(tag, field, message, input)) {
112       return false;
113     }
114   }
115 }
116
117 bool WireFormat::ParseAndMergeField(
118     uint32 tag,
119     const FieldDescriptor* field,        // May be NULL for unknown
120     Message* message,
121     io::CodedInputStream* input) {
122   const Reflection* message_reflection = message->GetReflection();
123
124   enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
125
126   if (field == NULL) {
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;
135   } else {
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;
139   }
140
141   if (value_format == UNKNOWN) {
142     return WireFormatLite::SkipField(
143         input, tag, message_reflection->MutableUnknownFields(message));
144   } else if (value_format == PACKED_FORMAT) {
145     uint32 length;
146     if (!input->ReadVarint32(&length)) return false;
147     io::CodedInputStream::Limit limit = input->PushLimit(length);
148
149     switch (field->type()) {
150 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
151       case FieldDescriptor::TYPE_##TYPE: {                                     \
152         while (input->BytesUntilLimit() > 0) {                                 \
153           CPPTYPE value;                                                       \
154           if (!WireFormatLite::ReadPrimitive<                                  \
155                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))          \
156             return false;                                                      \
157           message_reflection->Add##CPPTYPE_METHOD(message, field, value);      \
158         }                                                                      \
159         break;                                                                 \
160       }
161
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)
168
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)
173
174       HANDLE_PACKED_TYPE(FLOAT , float , Float )
175       HANDLE_PACKED_TYPE(DOUBLE, double, Double)
176
177       HANDLE_PACKED_TYPE(BOOL, bool, Bool)
178 #undef HANDLE_PACKED_TYPE
179
180       case FieldDescriptor::TYPE_ENUM: {
181         while (input->BytesUntilLimit() > 0) {
182           int value;
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);
189           }
190         }
191
192         break;
193       }
194
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.
201         return false;
202         break;
203     }
204
205     input->PopLimit(limit);
206   } else {
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: {                                    \
211         CPPTYPE value;                                                        \
212         if (!WireFormatLite::ReadPrimitive<                                   \
213                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))         \
214           return false;                                                       \
215         if (field->is_repeated()) {                                           \
216           message_reflection->Add##CPPTYPE_METHOD(message, field, value);     \
217         } else {                                                              \
218           message_reflection->Set##CPPTYPE_METHOD(message, field, value);     \
219         }                                                                     \
220         break;                                                                \
221       }
222
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)
229
230       HANDLE_TYPE( FIXED32, uint32, UInt32)
231       HANDLE_TYPE( FIXED64, uint64, UInt64)
232       HANDLE_TYPE(SFIXED32,  int32,  Int32)
233       HANDLE_TYPE(SFIXED64,  int64,  Int64)
234
235       HANDLE_TYPE(FLOAT , float , Float )
236       HANDLE_TYPE(DOUBLE, double, Double)
237
238       HANDLE_TYPE(BOOL, bool, Bool)
239 #undef HANDLE_TYPE
240
241       case FieldDescriptor::TYPE_ENUM: {
242         int value;
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);
250           } else {
251             message_reflection->SetEnum(message, field, enum_value);
252           }
253         } else {
254           // The enum value is not one of the known values.  Add it to the
255           // UnknownFieldSet.
256           int64 sign_extended_value = static_cast<int64>(value);
257           message_reflection->MutableUnknownFields(message)
258                             ->AddVarint(WireFormatLite::GetTagFieldNumber(tag),
259                                         sign_extended_value);
260         }
261         break;
262       }
263
264       // Handle strings separately so that we can optimize the ctype=CORD case.
265       case FieldDescriptor::TYPE_STRING: {
266         string value;
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);
271         } else {
272           message_reflection->SetString(message, field, value);
273         }
274         break;
275       }
276
277       case FieldDescriptor::TYPE_BYTES: {
278         string value;
279         if (!WireFormatLite::ReadBytes(input, &value)) return false;
280         if (field->is_repeated()) {
281           message_reflection->AddString(message, field, value);
282         } else {
283           message_reflection->SetString(message, field, value);
284         }
285         break;
286       }
287
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());
293         } else {
294           sub_message = message_reflection->MutableMessage(
295               message, field, input->GetExtensionFactory());
296         }
297
298         if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
299                                        input, sub_message))
300           return false;
301         break;
302       }
303
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());
309         } else {
310           sub_message = message_reflection->MutableMessage(
311               message, field, input->GetExtensionFactory());
312         }
313
314         if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
315         break;
316       }
317     }
318   }
319
320   return true;
321 }
322
323 bool WireFormat::ParseAndMergeMessageSetItem(
324     io::CodedInputStream* input,
325     Message* message) {
326   const Reflection* message_reflection = message->GetReflection();
327
328   // This method parses a group which should contain two fields:
329   //   required int32 type_id = 2;
330   //   required data message = 3;
331
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
334   // format.
335   uint32 fake_tag = 0;
336
337   // Once we see a type_id, we'll look up the FieldDescriptor for the
338   // extension.
339   const FieldDescriptor* field = NULL;
340
341   // If we see message data before the type_id, we'll append it to this so
342   // we can parse it later.
343   string message_data;
344
345   while (true) {
346     uint32 tag = input->ReadTag();
347     if (tag == 0) return false;
348
349     switch (tag) {
350       case WireFormatLite::kMessageSetTypeIdTag: {
351         uint32 type_id;
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);
356
357         if (!message_data.empty()) {
358           // We saw some message data before the type_id.  Have to parse it
359           // now.
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,
364                                   &sub_input)) {
365             return false;
366           }
367           message_data.clear();
368         }
369
370         break;
371       }
372
373       case WireFormatLite::kMessageSetMessageTag: {
374         if (fake_tag == 0) {
375           // We haven't seen a type_id yet.  Append this data to message_data.
376           string temp;
377           uint32 length;
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);
384         } else {
385           // Already saw type_id, so we can parse this directly.
386           if (!ParseAndMergeField(fake_tag, field, message, input)) {
387             return false;
388           }
389         }
390
391         break;
392       }
393
394       case WireFormatLite::kMessageSetItemEndTag: {
395         return true;
396       }
397
398       default: {
399         if (!WireFormatLite::SkipField(input, tag, NULL)) return false;
400       }
401     }
402   }
403 }
404
405 // ===================================================================
406
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;
413
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);
418   }
419
420   if (descriptor->options().message_set_wire_format()) {
421     WireFormatLite::SerializeUnknownMessageSetItems(
422         message_reflection->GetUnknownFields(message), output);
423   } else {
424     WireFormatLite::SerializeUnknownFields(
425         message_reflection->GetUnknownFields(message), output);
426   }
427
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?";
432 }
433
434 void WireFormat::SerializeFieldWithCachedSizes(
435     const FieldDescriptor* field,
436     const Message& message,
437     io::CodedOutputStream* output) {
438   const Reflection* message_reflection = message.GetReflection();
439
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);
445     return;
446   }
447
448   int count = 0;
449
450   if (field->is_repeated()) {
451     count = message_reflection->FieldSize(message, field);
452   } else if (message_reflection->HasField(message, field)) {
453     count = 1;
454   }
455
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);
462   }
463
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(         \
472                                 message, field);                               \
473         if (is_packed) {                                                       \
474           WireFormatLite::Write##TYPE_METHOD##NoTag(value, output);            \
475         } else {                                                               \
476           WireFormatLite::Write##TYPE_METHOD(field->number(), value, output);  \
477         }                                                                      \
478         break;                                                                 \
479       }
480
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)
487
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)
492
493       HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
494       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
495
496       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
497 #undef HANDLE_PRIMITIVE_TYPE
498
499 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                       \
500       case FieldDescriptor::TYPE_##TYPE:                                     \
501         WireFormatLite::Write##TYPE_METHOD(                                  \
502               field->number(),                                               \
503               field->is_repeated() ?                                         \
504                 message_reflection->GetRepeated##CPPTYPE_METHOD(             \
505                   message, field, j) :                                       \
506                 message_reflection->Get##CPPTYPE_METHOD(message, field),     \
507               output);                                                       \
508         break;
509
510       HANDLE_TYPE(GROUP  , Group  , Message)
511       HANDLE_TYPE(MESSAGE, Message, Message)
512 #undef HANDLE_TYPE
513
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);
518         if (is_packed) {
519           WireFormatLite::WriteEnumNoTag(value->number(), output);
520         } else {
521           WireFormatLite::WriteEnum(field->number(), value->number(), output);
522         }
523         break;
524       }
525
526       // Handle strings separately so that we can get string references
527       // instead of copying.
528       case FieldDescriptor::TYPE_STRING: {
529         string scratch;
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);
536         break;
537       }
538
539       case FieldDescriptor::TYPE_BYTES: {
540         string scratch;
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);
546         break;
547       }
548     }
549   }
550 }
551
552 void WireFormat::SerializeMessageSetItemWithCachedSizes(
553     const FieldDescriptor* field,
554     const Message& message,
555     io::CodedOutputStream* output) {
556   const Reflection* message_reflection = message.GetReflection();
557
558   // Start group.
559   output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
560
561   // Write type ID.
562   output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
563   output->WriteVarint32(field->number());
564
565   // Write message.
566   output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
567
568   const Message& sub_message = message_reflection->GetMessage(message, field);
569   output->WriteVarint32(sub_message.GetCachedSize());
570   sub_message.SerializeWithCachedSizes(output);
571
572   // End group.
573   output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
574 }
575
576 // ===================================================================
577
578 int WireFormat::ByteSize(const Message& message) {
579   const Descriptor* descriptor = message.GetDescriptor();
580   const Reflection* message_reflection = message.GetReflection();
581
582   int our_size = 0;
583
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);
588   }
589
590   if (descriptor->options().message_set_wire_format()) {
591     our_size += WireFormatLite::ComputeUnknownMessageSetItemsSize(
592       message_reflection->GetUnknownFields(message));
593   } else {
594     our_size += WireFormatLite::ComputeUnknownFieldsSize(
595       message_reflection->GetUnknownFields(message));
596   }
597
598   return our_size;
599 }
600
601 int WireFormat::FieldByteSize(
602     const FieldDescriptor* field,
603     const Message& message) {
604   const Reflection* message_reflection = message.GetReflection();
605
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);
611   }
612
613   int count = 0;
614   if (field->is_repeated()) {
615     count = message_reflection->FieldSize(message, field);
616   } else if (message_reflection->HasField(message, field)) {
617     count = 1;
618   }
619
620   const int data_size = FieldDataOnlyByteSize(field, message);
621   int our_size = data_size;
622   if (field->options().packed()) {
623     if (data_size > 0) {
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
626       // a GROUP
627       our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
628       our_size += io::CodedOutputStream::VarintSize32(data_size);
629     }
630   } else {
631     our_size += count * TagSize(field->number(), field->type());
632   }
633   return our_size;
634 }
635
636 int WireFormat::FieldDataOnlyByteSize(
637     const FieldDescriptor* field,
638     const Message& message) {
639   const Reflection* message_reflection = message.GetReflection();
640
641   int count = 0;
642   if (field->is_repeated()) {
643     count = message_reflection->FieldSize(message, field);
644   } else if (message_reflection->HasField(message, field)) {
645     count = 1;
646   }
647
648   int data_size = 0;
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));                                         \
657         }                                                                  \
658       } else {                                                             \
659         data_size += WireFormatLite::TYPE_METHOD##Size(                    \
660           message_reflection->Get##CPPTYPE_METHOD(message, field));        \
661       }                                                                    \
662       break;
663
664 #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                               \
665     case FieldDescriptor::TYPE_##TYPE:                                     \
666       data_size += count * WireFormatLite::k##TYPE_METHOD##Size;           \
667       break;
668
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)
675
676     HANDLE_FIXED_TYPE( FIXED32,  Fixed32)
677     HANDLE_FIXED_TYPE( FIXED64,  Fixed64)
678     HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
679     HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
680
681     HANDLE_FIXED_TYPE(FLOAT , Float )
682     HANDLE_FIXED_TYPE(DOUBLE, Double)
683
684     HANDLE_FIXED_TYPE(BOOL, Bool)
685
686     HANDLE_TYPE(GROUP  , Group  , Message)
687     HANDLE_TYPE(MESSAGE, Message, Message)
688 #undef HANDLE_TYPE
689 #undef HANDLE_FIXED_TYPE
690
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());
696         }
697       } else {
698         data_size += WireFormatLite::EnumSize(
699           message_reflection->GetEnum(message, field)->number());
700       }
701       break;
702     }
703
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++) {
709         string scratch;
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);
715       }
716       break;
717     }
718   }
719   return data_size;
720 }
721
722 int WireFormat::MessageSetItemByteSize(
723     const FieldDescriptor* field,
724     const Message& message) {
725   const Reflection* message_reflection = message.GetReflection();
726
727   int our_size = WireFormatLite::kMessageSetItemTagsSize;
728
729   // type_id
730   our_size += io::CodedOutputStream::VarintSize32(field->number());
731
732   // message
733   const Message& sub_message = message_reflection->GetMessage(message, field);
734   int message_size = sub_message.ByteSize();
735
736   our_size += io::CodedOutputStream::VarintSize32(message_size);
737   our_size += message_size;
738
739   return our_size;
740 }
741
742 void WireFormat::VerifyUTF8StringFallback(const char* data,
743                                           int size,
744                                           Operation op) {
745   if (!IsStructurallyValidUTF8(data, size)) {
746     const char* operation_str = NULL;
747     switch (op) {
748       case PARSE:
749         operation_str = "parsing";
750         break;
751       case SERIALIZE:
752         operation_str = "serializing";
753         break;
754       // no default case: have the compiler warn if a case is not covered.
755     }
756     GOOGLE_LOG(ERROR) << "String field contains invalid UTF-8 data when "
757                << operation_str
758                << " a protocol buffer. Use the 'bytes' type if you intend to "
759                   "send raw bytes.";
760   }
761 }
762
763
764 }  // namespace internal
765 }  // namespace protobuf
766 }  // namespace google