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