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 <google/protobuf/wire_format.h> |
36 | |
37 | #include <stack> |
38 | #include <string> |
39 | #include <vector> |
40 | |
41 | #include <google/protobuf/stubs/logging.h> |
42 | #include <google/protobuf/stubs/common.h> |
43 | #include <google/protobuf/io/coded_stream.h> |
44 | #include <google/protobuf/io/zero_copy_stream.h> |
45 | #include <google/protobuf/io/zero_copy_stream_impl.h> |
46 | #include <google/protobuf/descriptor.h> |
47 | #include <google/protobuf/descriptor.pb.h> |
48 | #include <google/protobuf/dynamic_message.h> |
49 | #include <google/protobuf/map_field.h> |
50 | #include <google/protobuf/map_field_inl.h> |
51 | #include <google/protobuf/message.h> |
52 | #include <google/protobuf/message_lite.h> |
53 | #include <google/protobuf/parse_context.h> |
54 | #include <google/protobuf/unknown_field_set.h> |
55 | |
56 | |
57 | // Must be included last. |
58 | #include <google/protobuf/port_def.inc> |
59 | |
60 | const size_t kMapEntryTagByteSize = 2; |
61 | |
62 | namespace google { |
63 | namespace protobuf { |
64 | namespace internal { |
65 | |
66 | // Forward declare static functions |
67 | static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, |
68 | const MapValueConstRef& value); |
69 | |
70 | // =================================================================== |
71 | |
72 | bool UnknownFieldSetFieldSkipper::SkipField(io::CodedInputStream* input, |
73 | uint32_t tag) { |
74 | return WireFormat::SkipField(input, tag, unknown_fields: unknown_fields_); |
75 | } |
76 | |
77 | bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) { |
78 | return WireFormat::SkipMessage(input, unknown_fields: unknown_fields_); |
79 | } |
80 | |
81 | void UnknownFieldSetFieldSkipper::SkipUnknownEnum(int field_number, int value) { |
82 | unknown_fields_->AddVarint(number: field_number, value); |
83 | } |
84 | |
85 | bool WireFormat::SkipField(io::CodedInputStream* input, uint32_t tag, |
86 | UnknownFieldSet* unknown_fields) { |
87 | int number = WireFormatLite::GetTagFieldNumber(tag); |
88 | // Field number 0 is illegal. |
89 | if (number == 0) return false; |
90 | |
91 | switch (WireFormatLite::GetTagWireType(tag)) { |
92 | case WireFormatLite::WIRETYPE_VARINT: { |
93 | uint64_t value; |
94 | if (!input->ReadVarint64(value: &value)) return false; |
95 | if (unknown_fields != nullptr) unknown_fields->AddVarint(number, value); |
96 | return true; |
97 | } |
98 | case WireFormatLite::WIRETYPE_FIXED64: { |
99 | uint64_t value; |
100 | if (!input->ReadLittleEndian64(value: &value)) return false; |
101 | if (unknown_fields != nullptr) unknown_fields->AddFixed64(number, value); |
102 | return true; |
103 | } |
104 | case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { |
105 | uint32_t length; |
106 | if (!input->ReadVarint32(value: &length)) return false; |
107 | if (unknown_fields == nullptr) { |
108 | if (!input->Skip(count: length)) return false; |
109 | } else { |
110 | if (!input->ReadString(buffer: unknown_fields->AddLengthDelimited(number), |
111 | size: length)) { |
112 | return false; |
113 | } |
114 | } |
115 | return true; |
116 | } |
117 | case WireFormatLite::WIRETYPE_START_GROUP: { |
118 | if (!input->IncrementRecursionDepth()) return false; |
119 | if (!SkipMessage(input, unknown_fields: (unknown_fields == nullptr) |
120 | ? nullptr |
121 | : unknown_fields->AddGroup(number))) { |
122 | return false; |
123 | } |
124 | input->DecrementRecursionDepth(); |
125 | // Check that the ending tag matched the starting tag. |
126 | if (!input->LastTagWas( |
127 | expected: WireFormatLite::MakeTag(field_number: WireFormatLite::GetTagFieldNumber(tag), |
128 | type: WireFormatLite::WIRETYPE_END_GROUP))) { |
129 | return false; |
130 | } |
131 | return true; |
132 | } |
133 | case WireFormatLite::WIRETYPE_END_GROUP: { |
134 | return false; |
135 | } |
136 | case WireFormatLite::WIRETYPE_FIXED32: { |
137 | uint32_t value; |
138 | if (!input->ReadLittleEndian32(value: &value)) return false; |
139 | if (unknown_fields != nullptr) unknown_fields->AddFixed32(number, value); |
140 | return true; |
141 | } |
142 | default: { |
143 | return false; |
144 | } |
145 | } |
146 | } |
147 | |
148 | bool WireFormat::SkipMessage(io::CodedInputStream* input, |
149 | UnknownFieldSet* unknown_fields) { |
150 | while (true) { |
151 | uint32_t tag = input->ReadTag(); |
152 | if (tag == 0) { |
153 | // End of input. This is a valid place to end, so return true. |
154 | return true; |
155 | } |
156 | |
157 | WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); |
158 | |
159 | if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { |
160 | // Must be the end of the message. |
161 | return true; |
162 | } |
163 | |
164 | if (!SkipField(input, tag, unknown_fields)) return false; |
165 | } |
166 | } |
167 | |
168 | bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, |
169 | uint32_t field_number, |
170 | bool (*is_valid)(int), |
171 | UnknownFieldSet* unknown_fields, |
172 | RepeatedField<int>* values) { |
173 | uint32_t length; |
174 | if (!input->ReadVarint32(value: &length)) return false; |
175 | io::CodedInputStream::Limit limit = input->PushLimit(byte_limit: length); |
176 | while (input->BytesUntilLimit() > 0) { |
177 | int value; |
178 | if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
179 | input, value: &value)) { |
180 | return false; |
181 | } |
182 | if (is_valid == nullptr || is_valid(value)) { |
183 | values->Add(value); |
184 | } else { |
185 | unknown_fields->AddVarint(number: field_number, value); |
186 | } |
187 | } |
188 | input->PopLimit(limit); |
189 | return true; |
190 | } |
191 | |
192 | uint8_t* WireFormat::InternalSerializeUnknownFieldsToArray( |
193 | const UnknownFieldSet& unknown_fields, uint8_t* target, |
194 | io::EpsCopyOutputStream* stream) { |
195 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
196 | const UnknownField& field = unknown_fields.field(index: i); |
197 | |
198 | target = stream->EnsureSpace(ptr: target); |
199 | switch (field.type()) { |
200 | case UnknownField::TYPE_VARINT: |
201 | target = WireFormatLite::WriteUInt64ToArray(field_number: field.number(), |
202 | value: field.varint(), target); |
203 | break; |
204 | case UnknownField::TYPE_FIXED32: |
205 | target = WireFormatLite::WriteFixed32ToArray(field_number: field.number(), |
206 | value: field.fixed32(), target); |
207 | break; |
208 | case UnknownField::TYPE_FIXED64: |
209 | target = WireFormatLite::WriteFixed64ToArray(field_number: field.number(), |
210 | value: field.fixed64(), target); |
211 | break; |
212 | case UnknownField::TYPE_LENGTH_DELIMITED: |
213 | target = stream->WriteString(num: field.number(), s: field.length_delimited(), |
214 | ptr: target); |
215 | break; |
216 | case UnknownField::TYPE_GROUP: |
217 | target = WireFormatLite::WriteTagToArray( |
218 | field_number: field.number(), type: WireFormatLite::WIRETYPE_START_GROUP, target); |
219 | target = InternalSerializeUnknownFieldsToArray(unknown_fields: field.group(), target, |
220 | stream); |
221 | target = stream->EnsureSpace(ptr: target); |
222 | target = WireFormatLite::WriteTagToArray( |
223 | field_number: field.number(), type: WireFormatLite::WIRETYPE_END_GROUP, target); |
224 | break; |
225 | } |
226 | } |
227 | return target; |
228 | } |
229 | |
230 | uint8_t* WireFormat::InternalSerializeUnknownMessageSetItemsToArray( |
231 | const UnknownFieldSet& unknown_fields, uint8_t* target, |
232 | io::EpsCopyOutputStream* stream) { |
233 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
234 | const UnknownField& field = unknown_fields.field(index: i); |
235 | |
236 | // The only unknown fields that are allowed to exist in a MessageSet are |
237 | // messages, which are length-delimited. |
238 | if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { |
239 | target = stream->EnsureSpace(ptr: target); |
240 | // Start group. |
241 | target = io::CodedOutputStream::WriteTagToArray( |
242 | value: WireFormatLite::kMessageSetItemStartTag, target); |
243 | |
244 | // Write type ID. |
245 | target = io::CodedOutputStream::WriteTagToArray( |
246 | value: WireFormatLite::kMessageSetTypeIdTag, target); |
247 | target = |
248 | io::CodedOutputStream::WriteVarint32ToArray(value: field.number(), target); |
249 | |
250 | // Write message. |
251 | target = io::CodedOutputStream::WriteTagToArray( |
252 | value: WireFormatLite::kMessageSetMessageTag, target); |
253 | |
254 | target = field.InternalSerializeLengthDelimitedNoTag(target, stream); |
255 | |
256 | target = stream->EnsureSpace(ptr: target); |
257 | // End group. |
258 | target = io::CodedOutputStream::WriteTagToArray( |
259 | value: WireFormatLite::kMessageSetItemEndTag, target); |
260 | } |
261 | } |
262 | |
263 | return target; |
264 | } |
265 | |
266 | size_t WireFormat::ComputeUnknownFieldsSize( |
267 | const UnknownFieldSet& unknown_fields) { |
268 | size_t size = 0; |
269 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
270 | const UnknownField& field = unknown_fields.field(index: i); |
271 | |
272 | switch (field.type()) { |
273 | case UnknownField::TYPE_VARINT: |
274 | size += io::CodedOutputStream::VarintSize32(value: WireFormatLite::MakeTag( |
275 | field_number: field.number(), type: WireFormatLite::WIRETYPE_VARINT)); |
276 | size += io::CodedOutputStream::VarintSize64(value: field.varint()); |
277 | break; |
278 | case UnknownField::TYPE_FIXED32: |
279 | size += io::CodedOutputStream::VarintSize32(value: WireFormatLite::MakeTag( |
280 | field_number: field.number(), type: WireFormatLite::WIRETYPE_FIXED32)); |
281 | size += sizeof(int32_t); |
282 | break; |
283 | case UnknownField::TYPE_FIXED64: |
284 | size += io::CodedOutputStream::VarintSize32(value: WireFormatLite::MakeTag( |
285 | field_number: field.number(), type: WireFormatLite::WIRETYPE_FIXED64)); |
286 | size += sizeof(int64_t); |
287 | break; |
288 | case UnknownField::TYPE_LENGTH_DELIMITED: |
289 | size += io::CodedOutputStream::VarintSize32(value: WireFormatLite::MakeTag( |
290 | field_number: field.number(), type: WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); |
291 | size += io::CodedOutputStream::VarintSize32( |
292 | value: field.length_delimited().size()); |
293 | size += field.length_delimited().size(); |
294 | break; |
295 | case UnknownField::TYPE_GROUP: |
296 | size += io::CodedOutputStream::VarintSize32(value: WireFormatLite::MakeTag( |
297 | field_number: field.number(), type: WireFormatLite::WIRETYPE_START_GROUP)); |
298 | size += ComputeUnknownFieldsSize(unknown_fields: field.group()); |
299 | size += io::CodedOutputStream::VarintSize32(value: WireFormatLite::MakeTag( |
300 | field_number: field.number(), type: WireFormatLite::WIRETYPE_END_GROUP)); |
301 | break; |
302 | } |
303 | } |
304 | |
305 | return size; |
306 | } |
307 | |
308 | size_t WireFormat::ComputeUnknownMessageSetItemsSize( |
309 | const UnknownFieldSet& unknown_fields) { |
310 | size_t size = 0; |
311 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
312 | const UnknownField& field = unknown_fields.field(index: i); |
313 | |
314 | // The only unknown fields that are allowed to exist in a MessageSet are |
315 | // messages, which are length-delimited. |
316 | if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { |
317 | size += WireFormatLite::kMessageSetItemTagsSize; |
318 | size += io::CodedOutputStream::VarintSize32(value: field.number()); |
319 | |
320 | int field_size = field.GetLengthDelimitedSize(); |
321 | size += io::CodedOutputStream::VarintSize32(value: field_size); |
322 | size += field_size; |
323 | } |
324 | } |
325 | |
326 | return size; |
327 | } |
328 | |
329 | // =================================================================== |
330 | |
331 | bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, |
332 | Message* message) { |
333 | const Descriptor* descriptor = message->GetDescriptor(); |
334 | const Reflection* message_reflection = message->GetReflection(); |
335 | |
336 | while (true) { |
337 | uint32_t tag = input->ReadTag(); |
338 | if (tag == 0) { |
339 | // End of input. This is a valid place to end, so return true. |
340 | return true; |
341 | } |
342 | |
343 | if (WireFormatLite::GetTagWireType(tag) == |
344 | WireFormatLite::WIRETYPE_END_GROUP) { |
345 | // Must be the end of the message. |
346 | return true; |
347 | } |
348 | |
349 | const FieldDescriptor* field = nullptr; |
350 | |
351 | if (descriptor != nullptr) { |
352 | int field_number = WireFormatLite::GetTagFieldNumber(tag); |
353 | field = descriptor->FindFieldByNumber(number: field_number); |
354 | |
355 | // If that failed, check if the field is an extension. |
356 | if (field == nullptr && descriptor->IsExtensionNumber(number: field_number)) { |
357 | if (input->GetExtensionPool() == nullptr) { |
358 | field = message_reflection->FindKnownExtensionByNumber(number: field_number); |
359 | } else { |
360 | field = input->GetExtensionPool()->FindExtensionByNumber( |
361 | extendee: descriptor, number: field_number); |
362 | } |
363 | } |
364 | |
365 | // If that failed, but we're a MessageSet, and this is the tag for a |
366 | // MessageSet item, then parse that. |
367 | if (field == nullptr && descriptor->options().message_set_wire_format() && |
368 | tag == WireFormatLite::kMessageSetItemStartTag) { |
369 | if (!ParseAndMergeMessageSetItem(input, message)) { |
370 | return false; |
371 | } |
372 | continue; // Skip ParseAndMergeField(); already taken care of. |
373 | } |
374 | } |
375 | |
376 | if (!ParseAndMergeField(tag, field, message, input)) { |
377 | return false; |
378 | } |
379 | } |
380 | } |
381 | |
382 | bool WireFormat::SkipMessageSetField(io::CodedInputStream* input, |
383 | uint32_t field_number, |
384 | UnknownFieldSet* unknown_fields) { |
385 | uint32_t length; |
386 | if (!input->ReadVarint32(value: &length)) return false; |
387 | return input->ReadString(buffer: unknown_fields->AddLengthDelimited(number: field_number), |
388 | size: length); |
389 | } |
390 | |
391 | bool WireFormat::ParseAndMergeMessageSetField(uint32_t field_number, |
392 | const FieldDescriptor* field, |
393 | Message* message, |
394 | io::CodedInputStream* input) { |
395 | const Reflection* message_reflection = message->GetReflection(); |
396 | if (field == nullptr) { |
397 | // We store unknown MessageSet extensions as groups. |
398 | return SkipMessageSetField( |
399 | input, field_number, unknown_fields: message_reflection->MutableUnknownFields(message)); |
400 | } else if (field->is_repeated() || |
401 | field->type() != FieldDescriptor::TYPE_MESSAGE) { |
402 | // This shouldn't happen as we only allow optional message extensions to |
403 | // MessageSet. |
404 | GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages." ; |
405 | return false; |
406 | } else { |
407 | Message* sub_message = message_reflection->MutableMessage( |
408 | message, field, factory: input->GetExtensionFactory()); |
409 | return WireFormatLite::ReadMessage(input, value: sub_message); |
410 | } |
411 | } |
412 | |
413 | static bool StrictUtf8Check(const FieldDescriptor* field) { |
414 | return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; |
415 | } |
416 | |
417 | bool WireFormat::ParseAndMergeField( |
418 | uint32_t tag, |
419 | const FieldDescriptor* field, // May be nullptr for unknown |
420 | Message* message, io::CodedInputStream* input) { |
421 | const Reflection* message_reflection = message->GetReflection(); |
422 | |
423 | enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format; |
424 | |
425 | if (field == nullptr) { |
426 | value_format = UNKNOWN; |
427 | } else if (WireFormatLite::GetTagWireType(tag) == |
428 | WireTypeForFieldType(type: field->type())) { |
429 | value_format = NORMAL_FORMAT; |
430 | } else if (field->is_packable() && |
431 | WireFormatLite::GetTagWireType(tag) == |
432 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { |
433 | value_format = PACKED_FORMAT; |
434 | } else { |
435 | // We don't recognize this field. Either the field number is unknown |
436 | // or the wire type doesn't match. Put it in our unknown field set. |
437 | value_format = UNKNOWN; |
438 | } |
439 | |
440 | if (value_format == UNKNOWN) { |
441 | return SkipField(input, tag, |
442 | unknown_fields: message_reflection->MutableUnknownFields(message)); |
443 | } else if (value_format == PACKED_FORMAT) { |
444 | uint32_t length; |
445 | if (!input->ReadVarint32(value: &length)) return false; |
446 | io::CodedInputStream::Limit limit = input->PushLimit(byte_limit: length); |
447 | |
448 | switch (field->type()) { |
449 | #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
450 | case FieldDescriptor::TYPE_##TYPE: { \ |
451 | while (input->BytesUntilLimit() > 0) { \ |
452 | CPPTYPE value; \ |
453 | if (!WireFormatLite::ReadPrimitive<CPPTYPE, \ |
454 | WireFormatLite::TYPE_##TYPE>(input, \ |
455 | &value)) \ |
456 | return false; \ |
457 | message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ |
458 | } \ |
459 | break; \ |
460 | } |
461 | |
462 | HANDLE_PACKED_TYPE(INT32, int32_t, Int32) |
463 | HANDLE_PACKED_TYPE(INT64, int64_t, Int64) |
464 | HANDLE_PACKED_TYPE(SINT32, int32_t, Int32) |
465 | HANDLE_PACKED_TYPE(SINT64, int64_t, Int64) |
466 | HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) |
467 | HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) |
468 | |
469 | HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32) |
470 | HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64) |
471 | HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32) |
472 | HANDLE_PACKED_TYPE(SFIXED64, int64_t, Int64) |
473 | |
474 | HANDLE_PACKED_TYPE(FLOAT, float, Float) |
475 | HANDLE_PACKED_TYPE(DOUBLE, double, Double) |
476 | |
477 | HANDLE_PACKED_TYPE(BOOL, bool, Bool) |
478 | #undef HANDLE_PACKED_TYPE |
479 | |
480 | case FieldDescriptor::TYPE_ENUM: { |
481 | while (input->BytesUntilLimit() > 0) { |
482 | int value; |
483 | if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
484 | input, value: &value)) |
485 | return false; |
486 | if (message->GetDescriptor()->file()->syntax() == |
487 | FileDescriptor::SYNTAX_PROTO3) { |
488 | message_reflection->AddEnumValue(message, field, value); |
489 | } else { |
490 | const EnumValueDescriptor* enum_value = |
491 | field->enum_type()->FindValueByNumber(number: value); |
492 | if (enum_value != nullptr) { |
493 | message_reflection->AddEnum(message, field, value: enum_value); |
494 | } else { |
495 | // The enum value is not one of the known values. Add it to the |
496 | // UnknownFieldSet. |
497 | int64_t sign_extended_value = static_cast<int64_t>(value); |
498 | message_reflection->MutableUnknownFields(message)->AddVarint( |
499 | number: WireFormatLite::GetTagFieldNumber(tag), value: sign_extended_value); |
500 | } |
501 | } |
502 | } |
503 | |
504 | break; |
505 | } |
506 | |
507 | case FieldDescriptor::TYPE_STRING: |
508 | case FieldDescriptor::TYPE_GROUP: |
509 | case FieldDescriptor::TYPE_MESSAGE: |
510 | case FieldDescriptor::TYPE_BYTES: |
511 | // Can't have packed fields of these types: these should be caught by |
512 | // the protocol compiler. |
513 | return false; |
514 | break; |
515 | } |
516 | |
517 | input->PopLimit(limit); |
518 | } else { |
519 | // Non-packed value (value_format == NORMAL_FORMAT) |
520 | switch (field->type()) { |
521 | #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
522 | case FieldDescriptor::TYPE_##TYPE: { \ |
523 | CPPTYPE value; \ |
524 | if (!WireFormatLite::ReadPrimitive<CPPTYPE, WireFormatLite::TYPE_##TYPE>( \ |
525 | input, &value)) \ |
526 | return false; \ |
527 | if (field->is_repeated()) { \ |
528 | message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ |
529 | } else { \ |
530 | message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ |
531 | } \ |
532 | break; \ |
533 | } |
534 | |
535 | HANDLE_TYPE(INT32, int32_t, Int32) |
536 | HANDLE_TYPE(INT64, int64_t, Int64) |
537 | HANDLE_TYPE(SINT32, int32_t, Int32) |
538 | HANDLE_TYPE(SINT64, int64_t, Int64) |
539 | HANDLE_TYPE(UINT32, uint32_t, UInt32) |
540 | HANDLE_TYPE(UINT64, uint64_t, UInt64) |
541 | |
542 | HANDLE_TYPE(FIXED32, uint32_t, UInt32) |
543 | HANDLE_TYPE(FIXED64, uint64_t, UInt64) |
544 | HANDLE_TYPE(SFIXED32, int32_t, Int32) |
545 | HANDLE_TYPE(SFIXED64, int64_t, Int64) |
546 | |
547 | HANDLE_TYPE(FLOAT, float, Float) |
548 | HANDLE_TYPE(DOUBLE, double, Double) |
549 | |
550 | HANDLE_TYPE(BOOL, bool, Bool) |
551 | #undef HANDLE_TYPE |
552 | |
553 | case FieldDescriptor::TYPE_ENUM: { |
554 | int value; |
555 | if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
556 | input, value: &value)) |
557 | return false; |
558 | if (field->is_repeated()) { |
559 | message_reflection->AddEnumValue(message, field, value); |
560 | } else { |
561 | message_reflection->SetEnumValue(message, field, value); |
562 | } |
563 | break; |
564 | } |
565 | |
566 | // Handle strings separately so that we can optimize the ctype=CORD case. |
567 | case FieldDescriptor::TYPE_STRING: { |
568 | bool strict_utf8_check = StrictUtf8Check(field); |
569 | std::string value; |
570 | if (!WireFormatLite::ReadString(input, value: &value)) return false; |
571 | if (strict_utf8_check) { |
572 | if (!WireFormatLite::VerifyUtf8String(data: value.data(), size: value.length(), |
573 | op: WireFormatLite::PARSE, |
574 | field_name: field->full_name().c_str())) { |
575 | return false; |
576 | } |
577 | } else { |
578 | VerifyUTF8StringNamedField(data: value.data(), size: value.length(), op: PARSE, |
579 | field_name: field->full_name().c_str()); |
580 | } |
581 | if (field->is_repeated()) { |
582 | message_reflection->AddString(message, field, value); |
583 | } else { |
584 | message_reflection->SetString(message, field, value); |
585 | } |
586 | break; |
587 | } |
588 | |
589 | case FieldDescriptor::TYPE_BYTES: { |
590 | std::string value; |
591 | if (!WireFormatLite::ReadBytes(input, value: &value)) return false; |
592 | if (field->is_repeated()) { |
593 | message_reflection->AddString(message, field, value); |
594 | } else { |
595 | message_reflection->SetString(message, field, value); |
596 | } |
597 | break; |
598 | } |
599 | |
600 | case FieldDescriptor::TYPE_GROUP: { |
601 | Message* sub_message; |
602 | if (field->is_repeated()) { |
603 | sub_message = message_reflection->AddMessage( |
604 | message, field, factory: input->GetExtensionFactory()); |
605 | } else { |
606 | sub_message = message_reflection->MutableMessage( |
607 | message, field, factory: input->GetExtensionFactory()); |
608 | } |
609 | |
610 | if (!WireFormatLite::ReadGroup(field_number: WireFormatLite::GetTagFieldNumber(tag), |
611 | input, value: sub_message)) |
612 | return false; |
613 | break; |
614 | } |
615 | |
616 | case FieldDescriptor::TYPE_MESSAGE: { |
617 | Message* sub_message; |
618 | if (field->is_repeated()) { |
619 | sub_message = message_reflection->AddMessage( |
620 | message, field, factory: input->GetExtensionFactory()); |
621 | } else { |
622 | sub_message = message_reflection->MutableMessage( |
623 | message, field, factory: input->GetExtensionFactory()); |
624 | } |
625 | |
626 | if (!WireFormatLite::ReadMessage(input, value: sub_message)) return false; |
627 | break; |
628 | } |
629 | } |
630 | } |
631 | |
632 | return true; |
633 | } |
634 | |
635 | bool WireFormat::ParseAndMergeMessageSetItem(io::CodedInputStream* input, |
636 | Message* message) { |
637 | struct MSReflective { |
638 | bool ParseField(int type_id, io::CodedInputStream* input) { |
639 | const FieldDescriptor* field = |
640 | message_reflection->FindKnownExtensionByNumber(number: type_id); |
641 | return ParseAndMergeMessageSetField(field_number: type_id, field, message, input); |
642 | } |
643 | |
644 | bool SkipField(uint32_t tag, io::CodedInputStream* input) { |
645 | return WireFormat::SkipField(input, tag, unknown_fields: nullptr); |
646 | } |
647 | |
648 | const Reflection* message_reflection; |
649 | Message* message; |
650 | }; |
651 | |
652 | return ParseMessageSetItemImpl( |
653 | input, ms: MSReflective{.message_reflection: message->GetReflection(), .message: message}); |
654 | } |
655 | |
656 | struct WireFormat::MessageSetParser { |
657 | const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) { |
658 | // Parse a MessageSetItem |
659 | auto metadata = reflection->MutableInternalMetadata(message: msg); |
660 | std::string payload; |
661 | uint32_t type_id = 0; |
662 | bool payload_read = false; |
663 | while (!ctx->Done(ptr: &ptr)) { |
664 | // We use 64 bit tags in order to allow typeid's that span the whole |
665 | // range of 32 bit numbers. |
666 | uint32_t tag = static_cast<uint8_t>(*ptr++); |
667 | if (tag == WireFormatLite::kMessageSetTypeIdTag) { |
668 | uint64_t tmp; |
669 | ptr = ParseBigVarint(p: ptr, out: &tmp); |
670 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
671 | type_id = tmp; |
672 | if (payload_read) { |
673 | const FieldDescriptor* field; |
674 | if (ctx->data().pool == nullptr) { |
675 | field = reflection->FindKnownExtensionByNumber(number: type_id); |
676 | } else { |
677 | field = |
678 | ctx->data().pool->FindExtensionByNumber(extendee: descriptor, number: type_id); |
679 | } |
680 | if (field == nullptr || field->message_type() == nullptr) { |
681 | WriteLengthDelimited( |
682 | num: type_id, val: payload, |
683 | unknown: metadata->mutable_unknown_fields<UnknownFieldSet>()); |
684 | } else { |
685 | Message* value = |
686 | field->is_repeated() |
687 | ? reflection->AddMessage(message: msg, field, factory: ctx->data().factory) |
688 | : reflection->MutableMessage(message: msg, field, |
689 | factory: ctx->data().factory); |
690 | const char* p; |
691 | // We can't use regular parse from string as we have to track |
692 | // proper recursion depth and descriptor pools. |
693 | ParseContext tmp_ctx(ctx->depth(), false, &p, payload); |
694 | tmp_ctx.data().pool = ctx->data().pool; |
695 | tmp_ctx.data().factory = ctx->data().factory; |
696 | GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && |
697 | tmp_ctx.EndedAtLimit()); |
698 | } |
699 | type_id = 0; |
700 | } |
701 | continue; |
702 | } else if (tag == WireFormatLite::kMessageSetMessageTag) { |
703 | if (type_id == 0) { |
704 | int32_t size = ReadSize(pp: &ptr); |
705 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
706 | ptr = ctx->ReadString(ptr, size, s: &payload); |
707 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
708 | payload_read = true; |
709 | } else { |
710 | // We're now parsing the payload |
711 | const FieldDescriptor* field = nullptr; |
712 | if (descriptor->IsExtensionNumber(number: type_id)) { |
713 | if (ctx->data().pool == nullptr) { |
714 | field = reflection->FindKnownExtensionByNumber(number: type_id); |
715 | } else { |
716 | field = |
717 | ctx->data().pool->FindExtensionByNumber(extendee: descriptor, number: type_id); |
718 | } |
719 | } |
720 | ptr = WireFormat::_InternalParseAndMergeField( |
721 | msg, ptr, ctx, tag: static_cast<uint64_t>(type_id) * 8 + 2, reflection, |
722 | field); |
723 | type_id = 0; |
724 | } |
725 | } else { |
726 | // An unknown field in MessageSetItem. |
727 | ptr = ReadTag(p: ptr - 1, out: &tag); |
728 | if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { |
729 | ctx->SetLastTag(tag); |
730 | return ptr; |
731 | } |
732 | // Skip field. |
733 | ptr = internal::UnknownFieldParse( |
734 | tag, unknown: static_cast<std::string*>(nullptr), ptr, ctx); |
735 | } |
736 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
737 | } |
738 | return ptr; |
739 | } |
740 | |
741 | const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) { |
742 | while (!ctx->Done(ptr: &ptr)) { |
743 | uint32_t tag; |
744 | ptr = ReadTag(p: ptr, out: &tag); |
745 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
746 | if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { |
747 | ctx->SetLastTag(tag); |
748 | break; |
749 | } |
750 | if (tag == WireFormatLite::kMessageSetItemStartTag) { |
751 | // A message set item starts |
752 | ptr = ctx->ParseGroup(msg: this, ptr, tag); |
753 | } else { |
754 | // Parse other fields as normal extensions. |
755 | int field_number = WireFormatLite::GetTagFieldNumber(tag); |
756 | const FieldDescriptor* field = nullptr; |
757 | if (descriptor->IsExtensionNumber(number: field_number)) { |
758 | if (ctx->data().pool == nullptr) { |
759 | field = reflection->FindKnownExtensionByNumber(number: field_number); |
760 | } else { |
761 | field = ctx->data().pool->FindExtensionByNumber(extendee: descriptor, |
762 | number: field_number); |
763 | } |
764 | } |
765 | ptr = WireFormat::_InternalParseAndMergeField(msg, ptr, ctx, tag, |
766 | reflection, field); |
767 | } |
768 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
769 | } |
770 | return ptr; |
771 | } |
772 | |
773 | Message* msg; |
774 | const Descriptor* descriptor; |
775 | const Reflection* reflection; |
776 | }; |
777 | |
778 | const char* WireFormat::_InternalParse(Message* msg, const char* ptr, |
779 | internal::ParseContext* ctx) { |
780 | const Descriptor* descriptor = msg->GetDescriptor(); |
781 | const Reflection* reflection = msg->GetReflection(); |
782 | GOOGLE_DCHECK(descriptor); |
783 | GOOGLE_DCHECK(reflection); |
784 | if (descriptor->options().message_set_wire_format()) { |
785 | MessageSetParser message_set{.msg: msg, .descriptor: descriptor, .reflection: reflection}; |
786 | return message_set.ParseMessageSet(ptr, ctx); |
787 | } |
788 | while (!ctx->Done(ptr: &ptr)) { |
789 | uint32_t tag; |
790 | ptr = ReadTag(p: ptr, out: &tag); |
791 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
792 | if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { |
793 | ctx->SetLastTag(tag); |
794 | break; |
795 | } |
796 | const FieldDescriptor* field = nullptr; |
797 | |
798 | int field_number = WireFormatLite::GetTagFieldNumber(tag); |
799 | field = descriptor->FindFieldByNumber(number: field_number); |
800 | |
801 | // If that failed, check if the field is an extension. |
802 | if (field == nullptr && descriptor->IsExtensionNumber(number: field_number)) { |
803 | if (ctx->data().pool == nullptr) { |
804 | field = reflection->FindKnownExtensionByNumber(number: field_number); |
805 | } else { |
806 | field = |
807 | ctx->data().pool->FindExtensionByNumber(extendee: descriptor, number: field_number); |
808 | } |
809 | } |
810 | |
811 | ptr = _InternalParseAndMergeField(msg, ptr, ctx, tag, reflection, field); |
812 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
813 | } |
814 | return ptr; |
815 | } |
816 | |
817 | const char* WireFormat::_InternalParseAndMergeField( |
818 | Message* msg, const char* ptr, internal::ParseContext* ctx, uint64_t tag, |
819 | const Reflection* reflection, const FieldDescriptor* field) { |
820 | if (field == nullptr) { |
821 | // unknown field set parser takes 64bit tags, because message set type ids |
822 | // span the full 32 bit range making the tag span [0, 2^35) range. |
823 | return internal::UnknownFieldParse( |
824 | tag, unknown: reflection->MutableUnknownFields(message: msg), ptr, ctx); |
825 | } |
826 | if (WireFormatLite::GetTagWireType(tag) != |
827 | WireTypeForFieldType(type: field->type())) { |
828 | if (field->is_packable() && WireFormatLite::GetTagWireType(tag) == |
829 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { |
830 | switch (field->type()) { |
831 | #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
832 | case FieldDescriptor::TYPE_##TYPE: { \ |
833 | ptr = internal::Packed##CPPTYPE_METHOD##Parser( \ |
834 | reflection->MutableRepeatedFieldInternal<CPPTYPE>(msg, field), ptr, \ |
835 | ctx); \ |
836 | return ptr; \ |
837 | } |
838 | |
839 | HANDLE_PACKED_TYPE(INT32, int32_t, Int32) |
840 | HANDLE_PACKED_TYPE(INT64, int64_t, Int64) |
841 | HANDLE_PACKED_TYPE(SINT32, int32_t, SInt32) |
842 | HANDLE_PACKED_TYPE(SINT64, int64_t, SInt64) |
843 | HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) |
844 | HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) |
845 | |
846 | HANDLE_PACKED_TYPE(FIXED32, uint32_t, Fixed32) |
847 | HANDLE_PACKED_TYPE(FIXED64, uint64_t, Fixed64) |
848 | HANDLE_PACKED_TYPE(SFIXED32, int32_t, SFixed32) |
849 | HANDLE_PACKED_TYPE(SFIXED64, int64_t, SFixed64) |
850 | |
851 | HANDLE_PACKED_TYPE(FLOAT, float, Float) |
852 | HANDLE_PACKED_TYPE(DOUBLE, double, Double) |
853 | |
854 | HANDLE_PACKED_TYPE(BOOL, bool, Bool) |
855 | #undef HANDLE_PACKED_TYPE |
856 | |
857 | case FieldDescriptor::TYPE_ENUM: { |
858 | auto rep_enum = |
859 | reflection->MutableRepeatedFieldInternal<int>(message: msg, field); |
860 | bool open_enum = false; |
861 | if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || |
862 | open_enum) { |
863 | ptr = internal::PackedEnumParser(object: rep_enum, ptr, ctx); |
864 | } else { |
865 | return ctx->ReadPackedVarint( |
866 | ptr, add: [rep_enum, field, reflection, msg](uint64_t val) { |
867 | if (field->enum_type()->FindValueByNumber(number: val) != nullptr) { |
868 | rep_enum->Add(value: val); |
869 | } else { |
870 | WriteVarint(num: field->number(), val, |
871 | unknown: reflection->MutableUnknownFields(message: msg)); |
872 | } |
873 | }); |
874 | } |
875 | return ptr; |
876 | } |
877 | |
878 | case FieldDescriptor::TYPE_STRING: |
879 | case FieldDescriptor::TYPE_GROUP: |
880 | case FieldDescriptor::TYPE_MESSAGE: |
881 | case FieldDescriptor::TYPE_BYTES: |
882 | GOOGLE_LOG(FATAL) << "Can't reach" ; |
883 | return nullptr; |
884 | } |
885 | } else { |
886 | // mismatched wiretype; |
887 | return internal::UnknownFieldParse( |
888 | tag, unknown: reflection->MutableUnknownFields(message: msg), ptr, ctx); |
889 | } |
890 | } |
891 | |
892 | // Non-packed value |
893 | bool utf8_check = false; |
894 | bool strict_utf8_check = false; |
895 | switch (field->type()) { |
896 | #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
897 | case FieldDescriptor::TYPE_##TYPE: { \ |
898 | CPPTYPE value; \ |
899 | ptr = VarintParse(ptr, &value); \ |
900 | if (ptr == nullptr) return nullptr; \ |
901 | if (field->is_repeated()) { \ |
902 | reflection->Add##CPPTYPE_METHOD(msg, field, value); \ |
903 | } else { \ |
904 | reflection->Set##CPPTYPE_METHOD(msg, field, value); \ |
905 | } \ |
906 | return ptr; \ |
907 | } |
908 | |
909 | HANDLE_TYPE(BOOL, uint64_t, Bool) |
910 | HANDLE_TYPE(INT32, uint32_t, Int32) |
911 | HANDLE_TYPE(INT64, uint64_t, Int64) |
912 | HANDLE_TYPE(UINT32, uint32_t, UInt32) |
913 | HANDLE_TYPE(UINT64, uint64_t, UInt64) |
914 | |
915 | case FieldDescriptor::TYPE_SINT32: { |
916 | int32_t value = ReadVarintZigZag32(p: &ptr); |
917 | if (ptr == nullptr) return nullptr; |
918 | if (field->is_repeated()) { |
919 | reflection->AddInt32(message: msg, field, value); |
920 | } else { |
921 | reflection->SetInt32(message: msg, field, value); |
922 | } |
923 | return ptr; |
924 | } |
925 | case FieldDescriptor::TYPE_SINT64: { |
926 | int64_t value = ReadVarintZigZag64(p: &ptr); |
927 | if (ptr == nullptr) return nullptr; |
928 | if (field->is_repeated()) { |
929 | reflection->AddInt64(message: msg, field, value); |
930 | } else { |
931 | reflection->SetInt64(message: msg, field, value); |
932 | } |
933 | return ptr; |
934 | } |
935 | #undef HANDLE_TYPE |
936 | #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
937 | case FieldDescriptor::TYPE_##TYPE: { \ |
938 | CPPTYPE value; \ |
939 | value = UnalignedLoad<CPPTYPE>(ptr); \ |
940 | ptr += sizeof(CPPTYPE); \ |
941 | if (field->is_repeated()) { \ |
942 | reflection->Add##CPPTYPE_METHOD(msg, field, value); \ |
943 | } else { \ |
944 | reflection->Set##CPPTYPE_METHOD(msg, field, value); \ |
945 | } \ |
946 | return ptr; \ |
947 | } |
948 | |
949 | HANDLE_TYPE(FIXED32, uint32_t, UInt32) |
950 | HANDLE_TYPE(FIXED64, uint64_t, UInt64) |
951 | HANDLE_TYPE(SFIXED32, int32_t, Int32) |
952 | HANDLE_TYPE(SFIXED64, int64_t, Int64) |
953 | |
954 | HANDLE_TYPE(FLOAT, float, Float) |
955 | HANDLE_TYPE(DOUBLE, double, Double) |
956 | |
957 | #undef HANDLE_TYPE |
958 | |
959 | case FieldDescriptor::TYPE_ENUM: { |
960 | uint32_t value; |
961 | ptr = VarintParse(p: ptr, out: &value); |
962 | if (ptr == nullptr) return nullptr; |
963 | if (field->is_repeated()) { |
964 | reflection->AddEnumValue(message: msg, field, value); |
965 | } else { |
966 | reflection->SetEnumValue(message: msg, field, value); |
967 | } |
968 | return ptr; |
969 | } |
970 | |
971 | // Handle strings separately so that we can optimize the ctype=CORD case. |
972 | case FieldDescriptor::TYPE_STRING: |
973 | utf8_check = true; |
974 | strict_utf8_check = StrictUtf8Check(field); |
975 | PROTOBUF_FALLTHROUGH_INTENDED; |
976 | case FieldDescriptor::TYPE_BYTES: { |
977 | int size = ReadSize(pp: &ptr); |
978 | if (ptr == nullptr) return nullptr; |
979 | std::string value; |
980 | ptr = ctx->ReadString(ptr, size, s: &value); |
981 | if (ptr == nullptr) return nullptr; |
982 | if (utf8_check) { |
983 | if (strict_utf8_check) { |
984 | if (!WireFormatLite::VerifyUtf8String(data: value.data(), size: value.length(), |
985 | op: WireFormatLite::PARSE, |
986 | field_name: field->full_name().c_str())) { |
987 | return nullptr; |
988 | } |
989 | } else { |
990 | VerifyUTF8StringNamedField(data: value.data(), size: value.length(), op: PARSE, |
991 | field_name: field->full_name().c_str()); |
992 | } |
993 | } |
994 | if (field->is_repeated()) { |
995 | reflection->AddString(message: msg, field, value: std::move(value)); |
996 | } else { |
997 | reflection->SetString(message: msg, field, value: std::move(value)); |
998 | } |
999 | return ptr; |
1000 | } |
1001 | |
1002 | case FieldDescriptor::TYPE_GROUP: { |
1003 | Message* sub_message; |
1004 | if (field->is_repeated()) { |
1005 | sub_message = reflection->AddMessage(message: msg, field, factory: ctx->data().factory); |
1006 | } else { |
1007 | sub_message = |
1008 | reflection->MutableMessage(message: msg, field, factory: ctx->data().factory); |
1009 | } |
1010 | |
1011 | return ctx->ParseGroup(msg: sub_message, ptr, tag); |
1012 | } |
1013 | |
1014 | case FieldDescriptor::TYPE_MESSAGE: { |
1015 | Message* sub_message; |
1016 | if (field->is_repeated()) { |
1017 | sub_message = reflection->AddMessage(message: msg, field, factory: ctx->data().factory); |
1018 | } else { |
1019 | sub_message = |
1020 | reflection->MutableMessage(message: msg, field, factory: ctx->data().factory); |
1021 | } |
1022 | return ctx->ParseMessage(msg: sub_message, ptr); |
1023 | } |
1024 | } |
1025 | |
1026 | // GCC 8 complains about control reaching end of non-void function here. |
1027 | // Let's keep it happy by returning a nullptr. |
1028 | return nullptr; |
1029 | } |
1030 | |
1031 | // =================================================================== |
1032 | |
1033 | uint8_t* WireFormat::_InternalSerialize(const Message& message, uint8_t* target, |
1034 | io::EpsCopyOutputStream* stream) { |
1035 | const Descriptor* descriptor = message.GetDescriptor(); |
1036 | const Reflection* message_reflection = message.GetReflection(); |
1037 | |
1038 | std::vector<const FieldDescriptor*> fields; |
1039 | |
1040 | // Fields of map entry should always be serialized. |
1041 | if (descriptor->options().map_entry()) { |
1042 | for (int i = 0; i < descriptor->field_count(); i++) { |
1043 | fields.push_back(x: descriptor->field(index: i)); |
1044 | } |
1045 | } else { |
1046 | message_reflection->ListFields(message, output: &fields); |
1047 | } |
1048 | |
1049 | for (auto field : fields) { |
1050 | target = InternalSerializeField(field, message, target, stream); |
1051 | } |
1052 | |
1053 | if (descriptor->options().message_set_wire_format()) { |
1054 | return InternalSerializeUnknownMessageSetItemsToArray( |
1055 | unknown_fields: message_reflection->GetUnknownFields(message), target, stream); |
1056 | } else { |
1057 | return InternalSerializeUnknownFieldsToArray( |
1058 | unknown_fields: message_reflection->GetUnknownFields(message), target, stream); |
1059 | } |
1060 | } |
1061 | |
1062 | uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, |
1063 | const MapKey& value, uint8_t* target, |
1064 | io::EpsCopyOutputStream* stream) { |
1065 | target = stream->EnsureSpace(ptr: target); |
1066 | switch (field->type()) { |
1067 | case FieldDescriptor::TYPE_DOUBLE: |
1068 | case FieldDescriptor::TYPE_FLOAT: |
1069 | case FieldDescriptor::TYPE_GROUP: |
1070 | case FieldDescriptor::TYPE_MESSAGE: |
1071 | case FieldDescriptor::TYPE_BYTES: |
1072 | case FieldDescriptor::TYPE_ENUM: |
1073 | GOOGLE_LOG(FATAL) << "Unsupported" ; |
1074 | break; |
1075 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1076 | case FieldDescriptor::TYPE_##FieldType: \ |
1077 | target = WireFormatLite::Write##CamelFieldType##ToArray( \ |
1078 | 1, value.Get##CamelCppType##Value(), target); \ |
1079 | break; |
1080 | CASE_TYPE(INT64, Int64, Int64) |
1081 | CASE_TYPE(UINT64, UInt64, UInt64) |
1082 | CASE_TYPE(INT32, Int32, Int32) |
1083 | CASE_TYPE(FIXED64, Fixed64, UInt64) |
1084 | CASE_TYPE(FIXED32, Fixed32, UInt32) |
1085 | CASE_TYPE(BOOL, Bool, Bool) |
1086 | CASE_TYPE(UINT32, UInt32, UInt32) |
1087 | CASE_TYPE(SFIXED32, SFixed32, Int32) |
1088 | CASE_TYPE(SFIXED64, SFixed64, Int64) |
1089 | CASE_TYPE(SINT32, SInt32, Int32) |
1090 | CASE_TYPE(SINT64, SInt64, Int64) |
1091 | #undef CASE_TYPE |
1092 | case FieldDescriptor::TYPE_STRING: |
1093 | target = stream->WriteString(num: 1, s: value.GetStringValue(), ptr: target); |
1094 | break; |
1095 | } |
1096 | return target; |
1097 | } |
1098 | |
1099 | static uint8_t* SerializeMapValueRefWithCachedSizes( |
1100 | const FieldDescriptor* field, const MapValueConstRef& value, |
1101 | uint8_t* target, io::EpsCopyOutputStream* stream) { |
1102 | target = stream->EnsureSpace(ptr: target); |
1103 | switch (field->type()) { |
1104 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1105 | case FieldDescriptor::TYPE_##FieldType: \ |
1106 | target = WireFormatLite::Write##CamelFieldType##ToArray( \ |
1107 | 2, value.Get##CamelCppType##Value(), target); \ |
1108 | break; |
1109 | CASE_TYPE(INT64, Int64, Int64) |
1110 | CASE_TYPE(UINT64, UInt64, UInt64) |
1111 | CASE_TYPE(INT32, Int32, Int32) |
1112 | CASE_TYPE(FIXED64, Fixed64, UInt64) |
1113 | CASE_TYPE(FIXED32, Fixed32, UInt32) |
1114 | CASE_TYPE(BOOL, Bool, Bool) |
1115 | CASE_TYPE(UINT32, UInt32, UInt32) |
1116 | CASE_TYPE(SFIXED32, SFixed32, Int32) |
1117 | CASE_TYPE(SFIXED64, SFixed64, Int64) |
1118 | CASE_TYPE(SINT32, SInt32, Int32) |
1119 | CASE_TYPE(SINT64, SInt64, Int64) |
1120 | CASE_TYPE(ENUM, Enum, Enum) |
1121 | CASE_TYPE(DOUBLE, Double, Double) |
1122 | CASE_TYPE(FLOAT, Float, Float) |
1123 | #undef CASE_TYPE |
1124 | case FieldDescriptor::TYPE_STRING: |
1125 | case FieldDescriptor::TYPE_BYTES: |
1126 | target = stream->WriteString(num: 2, s: value.GetStringValue(), ptr: target); |
1127 | break; |
1128 | case FieldDescriptor::TYPE_MESSAGE: { |
1129 | auto& msg = value.GetMessageValue(); |
1130 | target = WireFormatLite::InternalWriteMessage(field_number: 2, value: msg, cached_size: msg.GetCachedSize(), |
1131 | target, stream); |
1132 | } break; |
1133 | case FieldDescriptor::TYPE_GROUP: |
1134 | target = WireFormatLite::InternalWriteGroup(field_number: 2, value: value.GetMessageValue(), |
1135 | target, stream); |
1136 | break; |
1137 | } |
1138 | return target; |
1139 | } |
1140 | |
1141 | class MapKeySorter { |
1142 | public: |
1143 | static std::vector<MapKey> SortKey(const Message& message, |
1144 | const Reflection* reflection, |
1145 | const FieldDescriptor* field) { |
1146 | std::vector<MapKey> sorted_key_list; |
1147 | for (MapIterator it = |
1148 | reflection->MapBegin(message: const_cast<Message*>(&message), field); |
1149 | it != reflection->MapEnd(message: const_cast<Message*>(&message), field); |
1150 | ++it) { |
1151 | sorted_key_list.push_back(x: it.GetKey()); |
1152 | } |
1153 | MapKeyComparator comparator; |
1154 | std::sort(first: sorted_key_list.begin(), last: sorted_key_list.end(), comp: comparator); |
1155 | return sorted_key_list; |
1156 | } |
1157 | |
1158 | private: |
1159 | class MapKeyComparator { |
1160 | public: |
1161 | bool operator()(const MapKey& a, const MapKey& b) const { |
1162 | GOOGLE_DCHECK(a.type() == b.type()); |
1163 | switch (a.type()) { |
1164 | #define CASE_TYPE(CppType, CamelCppType) \ |
1165 | case FieldDescriptor::CPPTYPE_##CppType: { \ |
1166 | return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \ |
1167 | } |
1168 | CASE_TYPE(STRING, String) |
1169 | CASE_TYPE(INT64, Int64) |
1170 | CASE_TYPE(INT32, Int32) |
1171 | CASE_TYPE(UINT64, UInt64) |
1172 | CASE_TYPE(UINT32, UInt32) |
1173 | CASE_TYPE(BOOL, Bool) |
1174 | #undef CASE_TYPE |
1175 | |
1176 | default: |
1177 | GOOGLE_LOG(DFATAL) << "Invalid key for map field." ; |
1178 | return true; |
1179 | } |
1180 | } |
1181 | }; |
1182 | }; |
1183 | |
1184 | static uint8_t* InternalSerializeMapEntry(const FieldDescriptor* field, |
1185 | const MapKey& key, |
1186 | const MapValueConstRef& value, |
1187 | uint8_t* target, |
1188 | io::EpsCopyOutputStream* stream) { |
1189 | const FieldDescriptor* key_field = field->message_type()->field(index: 0); |
1190 | const FieldDescriptor* value_field = field->message_type()->field(index: 1); |
1191 | |
1192 | size_t size = kMapEntryTagByteSize; |
1193 | size += MapKeyDataOnlyByteSize(field: key_field, value: key); |
1194 | size += MapValueRefDataOnlyByteSize(field: value_field, value); |
1195 | target = stream->EnsureSpace(ptr: target); |
1196 | target = WireFormatLite::WriteTagToArray( |
1197 | field_number: field->number(), type: WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); |
1198 | target = io::CodedOutputStream::WriteVarint32ToArray(value: size, target); |
1199 | target = SerializeMapKeyWithCachedSizes(field: key_field, value: key, target, stream); |
1200 | target = |
1201 | SerializeMapValueRefWithCachedSizes(field: value_field, value, target, stream); |
1202 | return target; |
1203 | } |
1204 | |
1205 | uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field, |
1206 | const Message& message, |
1207 | uint8_t* target, |
1208 | io::EpsCopyOutputStream* stream) { |
1209 | const Reflection* message_reflection = message.GetReflection(); |
1210 | |
1211 | if (field->is_extension() && |
1212 | field->containing_type()->options().message_set_wire_format() && |
1213 | field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
1214 | !field->is_repeated()) { |
1215 | return InternalSerializeMessageSetItem(field, message, target, stream); |
1216 | } |
1217 | |
1218 | // For map fields, we can use either repeated field reflection or map |
1219 | // reflection. Our choice has some subtle effects. If we use repeated field |
1220 | // reflection here, then the repeated field representation becomes |
1221 | // authoritative for this field: any existing references that came from map |
1222 | // reflection remain valid for reading, but mutations to them are lost and |
1223 | // will be overwritten next time we call map reflection! |
1224 | // |
1225 | // So far this mainly affects Python, which keeps long-term references to map |
1226 | // values around, and always uses map reflection. See: b/35918691 |
1227 | // |
1228 | // Here we choose to use map reflection API as long as the internal |
1229 | // map is valid. In this way, the serialization doesn't change map field's |
1230 | // internal state and existing references that came from map reflection remain |
1231 | // valid for both reading and writing. |
1232 | if (field->is_map()) { |
1233 | const MapFieldBase* map_field = |
1234 | message_reflection->GetMapData(message, field); |
1235 | if (map_field->IsMapValid()) { |
1236 | if (stream->IsSerializationDeterministic()) { |
1237 | std::vector<MapKey> sorted_key_list = |
1238 | MapKeySorter::SortKey(message, reflection: message_reflection, field); |
1239 | for (std::vector<MapKey>::iterator it = sorted_key_list.begin(); |
1240 | it != sorted_key_list.end(); ++it) { |
1241 | MapValueConstRef map_value; |
1242 | message_reflection->LookupMapValue(message, field, key: *it, val: &map_value); |
1243 | target = |
1244 | InternalSerializeMapEntry(field, key: *it, value: map_value, target, stream); |
1245 | } |
1246 | } else { |
1247 | for (MapIterator it = message_reflection->MapBegin( |
1248 | message: const_cast<Message*>(&message), field); |
1249 | it != |
1250 | message_reflection->MapEnd(message: const_cast<Message*>(&message), field); |
1251 | ++it) { |
1252 | target = InternalSerializeMapEntry(field, key: it.GetKey(), |
1253 | value: it.GetValueRef(), target, stream); |
1254 | } |
1255 | } |
1256 | |
1257 | return target; |
1258 | } |
1259 | } |
1260 | int count = 0; |
1261 | |
1262 | if (field->is_repeated()) { |
1263 | count = message_reflection->FieldSize(message, field); |
1264 | } else if (field->containing_type()->options().map_entry()) { |
1265 | // Map entry fields always need to be serialized. |
1266 | count = 1; |
1267 | } else if (message_reflection->HasField(message, field)) { |
1268 | count = 1; |
1269 | } |
1270 | |
1271 | // map_entries is for maps that'll be deterministically serialized. |
1272 | std::vector<const Message*> map_entries; |
1273 | if (count > 1 && field->is_map() && stream->IsSerializationDeterministic()) { |
1274 | map_entries = |
1275 | DynamicMapSorter::Sort(message, map_size: count, reflection: message_reflection, field); |
1276 | } |
1277 | |
1278 | if (field->is_packed()) { |
1279 | if (count == 0) return target; |
1280 | target = stream->EnsureSpace(ptr: target); |
1281 | switch (field->type()) { |
1282 | #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1283 | case FieldDescriptor::TYPE_##TYPE: { \ |
1284 | auto r = \ |
1285 | message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \ |
1286 | target = stream->Write##TYPE_METHOD##Packed( \ |
1287 | field->number(), r, FieldDataOnlyByteSize(field, message), target); \ |
1288 | break; \ |
1289 | } |
1290 | |
1291 | HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32) |
1292 | HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64) |
1293 | HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32) |
1294 | HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64) |
1295 | HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32) |
1296 | HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64) |
1297 | HANDLE_PRIMITIVE_TYPE(ENUM, int, Enum, Enum) |
1298 | |
1299 | #undef HANDLE_PRIMITIVE_TYPE |
1300 | #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1301 | case FieldDescriptor::TYPE_##TYPE: { \ |
1302 | auto r = \ |
1303 | message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \ |
1304 | target = stream->WriteFixedPacked(field->number(), r, target); \ |
1305 | break; \ |
1306 | } |
1307 | |
1308 | HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32) |
1309 | HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64) |
1310 | HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32) |
1311 | HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64) |
1312 | |
1313 | HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) |
1314 | HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) |
1315 | |
1316 | HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) |
1317 | #undef HANDLE_PRIMITIVE_TYPE |
1318 | default: |
1319 | GOOGLE_LOG(FATAL) << "Invalid descriptor" ; |
1320 | } |
1321 | return target; |
1322 | } |
1323 | |
1324 | auto get_message_from_field = [&message, &map_entries, message_reflection]( |
1325 | const FieldDescriptor* field, int j) { |
1326 | if (!field->is_repeated()) { |
1327 | return &message_reflection->GetMessage(message, field); |
1328 | } |
1329 | if (!map_entries.empty()) { |
1330 | return map_entries[j]; |
1331 | } |
1332 | return &message_reflection->GetRepeatedMessage(message, field, index: j); |
1333 | }; |
1334 | for (int j = 0; j < count; j++) { |
1335 | target = stream->EnsureSpace(ptr: target); |
1336 | switch (field->type()) { |
1337 | #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1338 | case FieldDescriptor::TYPE_##TYPE: { \ |
1339 | const CPPTYPE value = \ |
1340 | field->is_repeated() \ |
1341 | ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ |
1342 | j) \ |
1343 | : message_reflection->Get##CPPTYPE_METHOD(message, field); \ |
1344 | target = WireFormatLite::Write##TYPE_METHOD##ToArray(field->number(), \ |
1345 | value, target); \ |
1346 | break; \ |
1347 | } |
1348 | |
1349 | HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32) |
1350 | HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64) |
1351 | HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32) |
1352 | HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64) |
1353 | HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32) |
1354 | HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64) |
1355 | |
1356 | HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32) |
1357 | HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64) |
1358 | HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32) |
1359 | HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64) |
1360 | |
1361 | HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) |
1362 | HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) |
1363 | |
1364 | HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) |
1365 | #undef HANDLE_PRIMITIVE_TYPE |
1366 | |
1367 | case FieldDescriptor::TYPE_GROUP: { |
1368 | auto* msg = get_message_from_field(field, j); |
1369 | target = WireFormatLite::InternalWriteGroup(field_number: field->number(), value: *msg, |
1370 | target, stream); |
1371 | } break; |
1372 | |
1373 | case FieldDescriptor::TYPE_MESSAGE: { |
1374 | auto* msg = get_message_from_field(field, j); |
1375 | target = WireFormatLite::InternalWriteMessage( |
1376 | field_number: field->number(), value: *msg, cached_size: msg->GetCachedSize(), target, stream); |
1377 | } break; |
1378 | |
1379 | case FieldDescriptor::TYPE_ENUM: { |
1380 | const EnumValueDescriptor* value = |
1381 | field->is_repeated() |
1382 | ? message_reflection->GetRepeatedEnum(message, field, index: j) |
1383 | : message_reflection->GetEnum(message, field); |
1384 | target = WireFormatLite::WriteEnumToArray(field_number: field->number(), |
1385 | value: value->number(), target); |
1386 | break; |
1387 | } |
1388 | |
1389 | // Handle strings separately so that we can get string references |
1390 | // instead of copying. |
1391 | case FieldDescriptor::TYPE_STRING: { |
1392 | bool strict_utf8_check = StrictUtf8Check(field); |
1393 | std::string scratch; |
1394 | const std::string& value = |
1395 | field->is_repeated() |
1396 | ? message_reflection->GetRepeatedStringReference(message, field, |
1397 | index: j, scratch: &scratch) |
1398 | : message_reflection->GetStringReference(message, field, |
1399 | scratch: &scratch); |
1400 | if (strict_utf8_check) { |
1401 | WireFormatLite::VerifyUtf8String(data: value.data(), size: value.length(), |
1402 | op: WireFormatLite::SERIALIZE, |
1403 | field_name: field->full_name().c_str()); |
1404 | } else { |
1405 | VerifyUTF8StringNamedField(data: value.data(), size: value.length(), op: SERIALIZE, |
1406 | field_name: field->full_name().c_str()); |
1407 | } |
1408 | target = stream->WriteString(num: field->number(), s: value, ptr: target); |
1409 | break; |
1410 | } |
1411 | |
1412 | case FieldDescriptor::TYPE_BYTES: { |
1413 | std::string scratch; |
1414 | const std::string& value = |
1415 | field->is_repeated() |
1416 | ? message_reflection->GetRepeatedStringReference(message, field, |
1417 | index: j, scratch: &scratch) |
1418 | : message_reflection->GetStringReference(message, field, |
1419 | scratch: &scratch); |
1420 | target = stream->WriteString(num: field->number(), s: value, ptr: target); |
1421 | break; |
1422 | } |
1423 | } |
1424 | } |
1425 | return target; |
1426 | } |
1427 | |
1428 | uint8_t* WireFormat::InternalSerializeMessageSetItem( |
1429 | const FieldDescriptor* field, const Message& message, uint8_t* target, |
1430 | io::EpsCopyOutputStream* stream) { |
1431 | const Reflection* message_reflection = message.GetReflection(); |
1432 | |
1433 | target = stream->EnsureSpace(ptr: target); |
1434 | // Start group. |
1435 | target = io::CodedOutputStream::WriteTagToArray( |
1436 | value: WireFormatLite::kMessageSetItemStartTag, target); |
1437 | // Write type ID. |
1438 | target = WireFormatLite::WriteUInt32ToArray( |
1439 | field_number: WireFormatLite::kMessageSetTypeIdNumber, value: field->number(), target); |
1440 | // Write message. |
1441 | auto& msg = message_reflection->GetMessage(message, field); |
1442 | target = WireFormatLite::InternalWriteMessage( |
1443 | field_number: WireFormatLite::kMessageSetMessageNumber, value: msg, cached_size: msg.GetCachedSize(), |
1444 | target, stream); |
1445 | // End group. |
1446 | target = stream->EnsureSpace(ptr: target); |
1447 | target = io::CodedOutputStream::WriteTagToArray( |
1448 | value: WireFormatLite::kMessageSetItemEndTag, target); |
1449 | return target; |
1450 | } |
1451 | |
1452 | // =================================================================== |
1453 | |
1454 | size_t WireFormat::ByteSize(const Message& message) { |
1455 | const Descriptor* descriptor = message.GetDescriptor(); |
1456 | const Reflection* message_reflection = message.GetReflection(); |
1457 | |
1458 | size_t our_size = 0; |
1459 | |
1460 | std::vector<const FieldDescriptor*> fields; |
1461 | |
1462 | // Fields of map entry should always be serialized. |
1463 | if (descriptor->options().map_entry()) { |
1464 | for (int i = 0; i < descriptor->field_count(); i++) { |
1465 | fields.push_back(x: descriptor->field(index: i)); |
1466 | } |
1467 | } else { |
1468 | message_reflection->ListFields(message, output: &fields); |
1469 | } |
1470 | |
1471 | for (const FieldDescriptor* field : fields) { |
1472 | our_size += FieldByteSize(field, message); |
1473 | } |
1474 | |
1475 | if (descriptor->options().message_set_wire_format()) { |
1476 | our_size += ComputeUnknownMessageSetItemsSize( |
1477 | unknown_fields: message_reflection->GetUnknownFields(message)); |
1478 | } else { |
1479 | our_size += |
1480 | ComputeUnknownFieldsSize(unknown_fields: message_reflection->GetUnknownFields(message)); |
1481 | } |
1482 | |
1483 | return our_size; |
1484 | } |
1485 | |
1486 | size_t WireFormat::FieldByteSize(const FieldDescriptor* field, |
1487 | const Message& message) { |
1488 | const Reflection* message_reflection = message.GetReflection(); |
1489 | |
1490 | if (field->is_extension() && |
1491 | field->containing_type()->options().message_set_wire_format() && |
1492 | field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
1493 | !field->is_repeated()) { |
1494 | return MessageSetItemByteSize(field, message); |
1495 | } |
1496 | |
1497 | size_t count = 0; |
1498 | if (field->is_repeated()) { |
1499 | if (field->is_map()) { |
1500 | const MapFieldBase* map_field = |
1501 | message_reflection->GetMapData(message, field); |
1502 | if (map_field->IsMapValid()) { |
1503 | count = FromIntSize(size: map_field->size()); |
1504 | } else { |
1505 | count = FromIntSize(size: message_reflection->FieldSize(message, field)); |
1506 | } |
1507 | } else { |
1508 | count = FromIntSize(size: message_reflection->FieldSize(message, field)); |
1509 | } |
1510 | } else if (field->containing_type()->options().map_entry()) { |
1511 | // Map entry fields always need to be serialized. |
1512 | count = 1; |
1513 | } else if (message_reflection->HasField(message, field)) { |
1514 | count = 1; |
1515 | } |
1516 | |
1517 | const size_t data_size = FieldDataOnlyByteSize(field, message); |
1518 | size_t our_size = data_size; |
1519 | if (field->is_packed()) { |
1520 | if (data_size > 0) { |
1521 | // Packed fields get serialized like a string, not their native type. |
1522 | // Technically this doesn't really matter; the size only changes if it's |
1523 | // a GROUP |
1524 | our_size += TagSize(field_number: field->number(), type: FieldDescriptor::TYPE_STRING); |
1525 | our_size += io::CodedOutputStream::VarintSize32(value: data_size); |
1526 | } |
1527 | } else { |
1528 | our_size += count * TagSize(field_number: field->number(), type: field->type()); |
1529 | } |
1530 | return our_size; |
1531 | } |
1532 | |
1533 | size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, |
1534 | const MapKey& value) { |
1535 | GOOGLE_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type()); |
1536 | switch (field->type()) { |
1537 | case FieldDescriptor::TYPE_DOUBLE: |
1538 | case FieldDescriptor::TYPE_FLOAT: |
1539 | case FieldDescriptor::TYPE_GROUP: |
1540 | case FieldDescriptor::TYPE_MESSAGE: |
1541 | case FieldDescriptor::TYPE_BYTES: |
1542 | case FieldDescriptor::TYPE_ENUM: |
1543 | GOOGLE_LOG(FATAL) << "Unsupported" ; |
1544 | return 0; |
1545 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1546 | case FieldDescriptor::TYPE_##FieldType: \ |
1547 | return WireFormatLite::CamelFieldType##Size( \ |
1548 | value.Get##CamelCppType##Value()); |
1549 | |
1550 | #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ |
1551 | case FieldDescriptor::TYPE_##FieldType: \ |
1552 | return WireFormatLite::k##CamelFieldType##Size; |
1553 | |
1554 | CASE_TYPE(INT32, Int32, Int32); |
1555 | CASE_TYPE(INT64, Int64, Int64); |
1556 | CASE_TYPE(UINT32, UInt32, UInt32); |
1557 | CASE_TYPE(UINT64, UInt64, UInt64); |
1558 | CASE_TYPE(SINT32, SInt32, Int32); |
1559 | CASE_TYPE(SINT64, SInt64, Int64); |
1560 | CASE_TYPE(STRING, String, String); |
1561 | FIXED_CASE_TYPE(FIXED32, Fixed32); |
1562 | FIXED_CASE_TYPE(FIXED64, Fixed64); |
1563 | FIXED_CASE_TYPE(SFIXED32, SFixed32); |
1564 | FIXED_CASE_TYPE(SFIXED64, SFixed64); |
1565 | FIXED_CASE_TYPE(BOOL, Bool); |
1566 | |
1567 | #undef CASE_TYPE |
1568 | #undef FIXED_CASE_TYPE |
1569 | } |
1570 | GOOGLE_LOG(FATAL) << "Cannot get here" ; |
1571 | return 0; |
1572 | } |
1573 | |
1574 | static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, |
1575 | const MapValueConstRef& value) { |
1576 | switch (field->type()) { |
1577 | case FieldDescriptor::TYPE_GROUP: |
1578 | GOOGLE_LOG(FATAL) << "Unsupported" ; |
1579 | return 0; |
1580 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1581 | case FieldDescriptor::TYPE_##FieldType: \ |
1582 | return WireFormatLite::CamelFieldType##Size( \ |
1583 | value.Get##CamelCppType##Value()); |
1584 | |
1585 | #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ |
1586 | case FieldDescriptor::TYPE_##FieldType: \ |
1587 | return WireFormatLite::k##CamelFieldType##Size; |
1588 | |
1589 | CASE_TYPE(INT32, Int32, Int32); |
1590 | CASE_TYPE(INT64, Int64, Int64); |
1591 | CASE_TYPE(UINT32, UInt32, UInt32); |
1592 | CASE_TYPE(UINT64, UInt64, UInt64); |
1593 | CASE_TYPE(SINT32, SInt32, Int32); |
1594 | CASE_TYPE(SINT64, SInt64, Int64); |
1595 | CASE_TYPE(STRING, String, String); |
1596 | CASE_TYPE(BYTES, Bytes, String); |
1597 | CASE_TYPE(ENUM, Enum, Enum); |
1598 | CASE_TYPE(MESSAGE, Message, Message); |
1599 | FIXED_CASE_TYPE(FIXED32, Fixed32); |
1600 | FIXED_CASE_TYPE(FIXED64, Fixed64); |
1601 | FIXED_CASE_TYPE(SFIXED32, SFixed32); |
1602 | FIXED_CASE_TYPE(SFIXED64, SFixed64); |
1603 | FIXED_CASE_TYPE(DOUBLE, Double); |
1604 | FIXED_CASE_TYPE(FLOAT, Float); |
1605 | FIXED_CASE_TYPE(BOOL, Bool); |
1606 | |
1607 | #undef CASE_TYPE |
1608 | #undef FIXED_CASE_TYPE |
1609 | } |
1610 | GOOGLE_LOG(FATAL) << "Cannot get here" ; |
1611 | return 0; |
1612 | } |
1613 | |
1614 | size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, |
1615 | const Message& message) { |
1616 | const Reflection* message_reflection = message.GetReflection(); |
1617 | |
1618 | size_t data_size = 0; |
1619 | |
1620 | if (field->is_map()) { |
1621 | const MapFieldBase* map_field = |
1622 | message_reflection->GetMapData(message, field); |
1623 | if (map_field->IsMapValid()) { |
1624 | MapIterator iter(const_cast<Message*>(&message), field); |
1625 | MapIterator end(const_cast<Message*>(&message), field); |
1626 | const FieldDescriptor* key_field = field->message_type()->field(index: 0); |
1627 | const FieldDescriptor* value_field = field->message_type()->field(index: 1); |
1628 | for (map_field->MapBegin(map_iter: &iter), map_field->MapEnd(map_iter: &end); iter != end; |
1629 | ++iter) { |
1630 | size_t size = kMapEntryTagByteSize; |
1631 | size += MapKeyDataOnlyByteSize(field: key_field, value: iter.GetKey()); |
1632 | size += MapValueRefDataOnlyByteSize(field: value_field, value: iter.GetValueRef()); |
1633 | data_size += WireFormatLite::LengthDelimitedSize(length: size); |
1634 | } |
1635 | return data_size; |
1636 | } |
1637 | } |
1638 | |
1639 | size_t count = 0; |
1640 | if (field->is_repeated()) { |
1641 | count = |
1642 | internal::FromIntSize(size: message_reflection->FieldSize(message, field)); |
1643 | } else if (field->containing_type()->options().map_entry()) { |
1644 | // Map entry fields always need to be serialized. |
1645 | count = 1; |
1646 | } else if (message_reflection->HasField(message, field)) { |
1647 | count = 1; |
1648 | } |
1649 | |
1650 | switch (field->type()) { |
1651 | #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1652 | case FieldDescriptor::TYPE_##TYPE: \ |
1653 | if (field->is_repeated()) { \ |
1654 | for (size_t j = 0; j < count; j++) { \ |
1655 | data_size += WireFormatLite::TYPE_METHOD##Size( \ |
1656 | message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ |
1657 | j)); \ |
1658 | } \ |
1659 | } else { \ |
1660 | data_size += WireFormatLite::TYPE_METHOD##Size( \ |
1661 | message_reflection->Get##CPPTYPE_METHOD(message, field)); \ |
1662 | } \ |
1663 | break; |
1664 | |
1665 | #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ |
1666 | case FieldDescriptor::TYPE_##TYPE: \ |
1667 | data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \ |
1668 | break; |
1669 | |
1670 | HANDLE_TYPE(INT32, Int32, Int32) |
1671 | HANDLE_TYPE(INT64, Int64, Int64) |
1672 | HANDLE_TYPE(SINT32, SInt32, Int32) |
1673 | HANDLE_TYPE(SINT64, SInt64, Int64) |
1674 | HANDLE_TYPE(UINT32, UInt32, UInt32) |
1675 | HANDLE_TYPE(UINT64, UInt64, UInt64) |
1676 | |
1677 | HANDLE_FIXED_TYPE(FIXED32, Fixed32) |
1678 | HANDLE_FIXED_TYPE(FIXED64, Fixed64) |
1679 | HANDLE_FIXED_TYPE(SFIXED32, SFixed32) |
1680 | HANDLE_FIXED_TYPE(SFIXED64, SFixed64) |
1681 | |
1682 | HANDLE_FIXED_TYPE(FLOAT, Float) |
1683 | HANDLE_FIXED_TYPE(DOUBLE, Double) |
1684 | |
1685 | HANDLE_FIXED_TYPE(BOOL, Bool) |
1686 | |
1687 | HANDLE_TYPE(GROUP, Group, Message) |
1688 | HANDLE_TYPE(MESSAGE, Message, Message) |
1689 | #undef HANDLE_TYPE |
1690 | #undef HANDLE_FIXED_TYPE |
1691 | |
1692 | case FieldDescriptor::TYPE_ENUM: { |
1693 | if (field->is_repeated()) { |
1694 | for (size_t j = 0; j < count; j++) { |
1695 | data_size += WireFormatLite::EnumSize( |
1696 | value: message_reflection->GetRepeatedEnum(message, field, index: j)->number()); |
1697 | } |
1698 | } else { |
1699 | data_size += WireFormatLite::EnumSize( |
1700 | value: message_reflection->GetEnum(message, field)->number()); |
1701 | } |
1702 | break; |
1703 | } |
1704 | |
1705 | // Handle strings separately so that we can get string references |
1706 | // instead of copying. |
1707 | case FieldDescriptor::TYPE_STRING: |
1708 | case FieldDescriptor::TYPE_BYTES: { |
1709 | for (size_t j = 0; j < count; j++) { |
1710 | std::string scratch; |
1711 | const std::string& value = |
1712 | field->is_repeated() |
1713 | ? message_reflection->GetRepeatedStringReference(message, field, |
1714 | index: j, scratch: &scratch) |
1715 | : message_reflection->GetStringReference(message, field, |
1716 | scratch: &scratch); |
1717 | data_size += WireFormatLite::StringSize(value); |
1718 | } |
1719 | break; |
1720 | } |
1721 | } |
1722 | return data_size; |
1723 | } |
1724 | |
1725 | size_t WireFormat::MessageSetItemByteSize(const FieldDescriptor* field, |
1726 | const Message& message) { |
1727 | const Reflection* message_reflection = message.GetReflection(); |
1728 | |
1729 | size_t our_size = WireFormatLite::kMessageSetItemTagsSize; |
1730 | |
1731 | // type_id |
1732 | our_size += io::CodedOutputStream::VarintSize32(value: field->number()); |
1733 | |
1734 | // message |
1735 | const Message& sub_message = message_reflection->GetMessage(message, field); |
1736 | size_t message_size = sub_message.ByteSizeLong(); |
1737 | |
1738 | our_size += io::CodedOutputStream::VarintSize32(value: message_size); |
1739 | our_size += message_size; |
1740 | |
1741 | return our_size; |
1742 | } |
1743 | |
1744 | // Compute the size of the UnknownFieldSet on the wire. |
1745 | size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, |
1746 | size_t total_size, CachedSize* cached_size) { |
1747 | total_size += WireFormat::ComputeUnknownFieldsSize( |
1748 | unknown_fields: metadata.unknown_fields<UnknownFieldSet>( |
1749 | default_instance: UnknownFieldSet::default_instance)); |
1750 | cached_size->Set(ToCachedSize(size: total_size)); |
1751 | return total_size; |
1752 | } |
1753 | |
1754 | } // namespace internal |
1755 | } // namespace protobuf |
1756 | } // namespace google |
1757 | |
1758 | #include <google/protobuf/port_undef.inc> |
1759 | |