blob: 05987d3b135bbabac5aa05557b22074be4c48812 [file] [log] [blame]
Armelle Laine2f5a7072022-11-06 19:03:46 +00001// 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: jschorr@google.com (Joseph Schorr)
32// Based on original Protocol Buffers design by
33// Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <google/protobuf/text_format.h>
36
37#include <float.h>
38#include <stdio.h>
39
40#include <algorithm>
41#include <atomic>
42#include <climits>
43#include <cmath>
44#include <limits>
45#include <utility>
46#include <vector>
47
48#include <google/protobuf/io/coded_stream.h>
49#include <google/protobuf/io/tokenizer.h>
50#include <google/protobuf/io/zero_copy_stream.h>
51#include <google/protobuf/io/zero_copy_stream_impl.h>
52#include <google/protobuf/stubs/strutil.h>
53#include <google/protobuf/any.h>
54#include <google/protobuf/descriptor.h>
55#include <google/protobuf/descriptor.pb.h>
56#include <google/protobuf/dynamic_message.h>
57#include <google/protobuf/io/strtod.h>
58#include <google/protobuf/map_field.h>
59#include <google/protobuf/message.h>
60#include <google/protobuf/repeated_field.h>
61#include <google/protobuf/unknown_field_set.h>
62#include <google/protobuf/wire_format_lite.h>
63#include <google/protobuf/stubs/map_util.h>
64#include <google/protobuf/stubs/stl_util.h>
65
66// Must be included last.
67#include <google/protobuf/port_def.inc>
68
69namespace google {
70namespace protobuf {
71
72namespace {
73
74inline bool IsHexNumber(const std::string& str) {
75 return (str.length() >= 2 && str[0] == '0' &&
76 (str[1] == 'x' || str[1] == 'X'));
77}
78
79inline bool IsOctNumber(const std::string& str) {
80 return (str.length() >= 2 && str[0] == '0' &&
81 (str[1] >= '0' && str[1] < '8'));
82}
83
84} // namespace
85
86namespace internal {
87const char kDebugStringSilentMarker[] = "";
88const char kDebugStringSilentMarkerForDetection[] = "\t ";
89
90// Controls insertion of kDebugStringSilentMarker.
91PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker;
92} // namespace internal
93
94std::string Message::DebugString() const {
95 std::string debug_string;
96
97 TextFormat::Printer printer;
98 printer.SetExpandAny(true);
99 printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load(
100 std::memory_order_relaxed));
101
102 printer.PrintToString(*this, &debug_string);
103
104 return debug_string;
105}
106
107std::string Message::ShortDebugString() const {
108 std::string debug_string;
109
110 TextFormat::Printer printer;
111 printer.SetSingleLineMode(true);
112 printer.SetExpandAny(true);
113 printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load(
114 std::memory_order_relaxed));
115
116 printer.PrintToString(*this, &debug_string);
117 // Single line mode currently might have an extra space at the end.
118 if (!debug_string.empty() && debug_string[debug_string.size() - 1] == ' ') {
119 debug_string.resize(debug_string.size() - 1);
120 }
121
122 return debug_string;
123}
124
125std::string Message::Utf8DebugString() const {
126 std::string debug_string;
127
128 TextFormat::Printer printer;
129 printer.SetUseUtf8StringEscaping(true);
130 printer.SetExpandAny(true);
131 printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load(
132 std::memory_order_relaxed));
133
134 printer.PrintToString(*this, &debug_string);
135
136 return debug_string;
137}
138
139void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); }
140
141
142// ===========================================================================
143// Implementation of the parse information tree class.
144void TextFormat::ParseInfoTree::RecordLocation(
145 const FieldDescriptor* field, TextFormat::ParseLocationRange range) {
146 locations_[field].push_back(range);
147}
148
149TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
150 const FieldDescriptor* field) {
151 // Owned by us in the map.
152 auto& vec = nested_[field];
153 vec.emplace_back(new TextFormat::ParseInfoTree());
154 return vec.back().get();
155}
156
157void CheckFieldIndex(const FieldDescriptor* field, int index) {
158 if (field == nullptr) {
159 return;
160 }
161
162 if (field->is_repeated() && index == -1) {
163 GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
164 << "Field: " << field->name();
165 } else if (!field->is_repeated() && index != -1) {
166 GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
167 << "Field: " << field->name();
168 }
169}
170
171TextFormat::ParseLocationRange TextFormat::ParseInfoTree::GetLocationRange(
172 const FieldDescriptor* field, int index) const {
173 CheckFieldIndex(field, index);
174 if (index == -1) {
175 index = 0;
176 }
177
178 const std::vector<TextFormat::ParseLocationRange>* locations =
179 FindOrNull(locations_, field);
180 if (locations == nullptr ||
181 index >= static_cast<int64_t>(locations->size())) {
182 return TextFormat::ParseLocationRange();
183 }
184
185 return (*locations)[index];
186}
187
188TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
189 const FieldDescriptor* field, int index) const {
190 CheckFieldIndex(field, index);
191 if (index == -1) {
192 index = 0;
193 }
194
195 auto it = nested_.find(field);
196 if (it == nested_.end() || index >= static_cast<int64_t>(it->second.size())) {
197 return nullptr;
198 }
199
200 return it->second[index].get();
201}
202
203namespace {
204// These functions implement the behavior of the "default" TextFormat::Finder,
205// they are defined as standalone to be called when finder_ is nullptr.
206const FieldDescriptor* DefaultFinderFindExtension(Message* message,
207 const std::string& name) {
208 const Descriptor* descriptor = message->GetDescriptor();
209 return descriptor->file()->pool()->FindExtensionByPrintableName(descriptor,
210 name);
211}
212
213const FieldDescriptor* DefaultFinderFindExtensionByNumber(
214 const Descriptor* descriptor, int number) {
215 return descriptor->file()->pool()->FindExtensionByNumber(descriptor, number);
216}
217
218const Descriptor* DefaultFinderFindAnyType(const Message& message,
219 const std::string& prefix,
220 const std::string& name) {
221 if (prefix != internal::kTypeGoogleApisComPrefix &&
222 prefix != internal::kTypeGoogleProdComPrefix) {
223 return nullptr;
224 }
225 return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name);
226}
227} // namespace
228
229// ===========================================================================
230// Internal class for parsing an ASCII representation of a Protocol Message.
231// This class makes use of the Protocol Message compiler's tokenizer found
232// in //net/proto2/io/public/tokenizer.h. Note that class's Parse
233// method is *not* thread-safe and should only be used in a single thread at
234// a time.
235
236// Makes code slightly more readable. The meaning of "DO(foo)" is
237// "Execute foo and fail if it fails.", where failure is indicated by
238// returning false. Borrowed from parser.cc (Thanks Kenton!).
239#define DO(STATEMENT) \
240 if (STATEMENT) { \
241 } else { \
242 return false; \
243 }
244
245class TextFormat::Parser::ParserImpl {
246 public:
247 // Determines if repeated values for non-repeated fields and
248 // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
249 // required/optional field named "foo", or "baz: 1 bar: 2"
250 // where "baz" and "bar" are members of the same oneof.
251 enum SingularOverwritePolicy {
252 ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
253 FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
254 };
255
256 ParserImpl(const Descriptor* root_message_type,
257 io::ZeroCopyInputStream* input_stream,
258 io::ErrorCollector* error_collector,
259 const TextFormat::Finder* finder, ParseInfoTree* parse_info_tree,
260 SingularOverwritePolicy singular_overwrite_policy,
261 bool allow_case_insensitive_field, bool allow_unknown_field,
262 bool allow_unknown_extension, bool allow_unknown_enum,
263 bool allow_field_number, bool allow_relaxed_whitespace,
264 bool allow_partial, int recursion_limit)
265 : error_collector_(error_collector),
266 finder_(finder),
267 parse_info_tree_(parse_info_tree),
268 tokenizer_error_collector_(this),
269 tokenizer_(input_stream, &tokenizer_error_collector_),
270 root_message_type_(root_message_type),
271 singular_overwrite_policy_(singular_overwrite_policy),
272 allow_case_insensitive_field_(allow_case_insensitive_field),
273 allow_unknown_field_(allow_unknown_field),
274 allow_unknown_extension_(allow_unknown_extension),
275 allow_unknown_enum_(allow_unknown_enum),
276 allow_field_number_(allow_field_number),
277 allow_partial_(allow_partial),
278 initial_recursion_limit_(recursion_limit),
279 recursion_limit_(recursion_limit),
280 had_silent_marker_(false),
281 had_errors_(false) {
282 // For backwards-compatibility with proto1, we need to allow the 'f' suffix
283 // for floats.
284 tokenizer_.set_allow_f_after_float(true);
285
286 // '#' starts a comment.
287 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
288
289 if (allow_relaxed_whitespace) {
290 tokenizer_.set_require_space_after_number(false);
291 tokenizer_.set_allow_multiline_strings(true);
292 }
293
294 // Consume the starting token.
295 tokenizer_.Next();
296 }
297 ~ParserImpl() {}
298
299 // Parses the ASCII representation specified in input and saves the
300 // information into the output pointer (a Message). Returns
301 // false if an error occurs (an error will also be logged to
302 // GOOGLE_LOG(ERROR)).
303 bool Parse(Message* output) {
304 // Consume fields until we cannot do so anymore.
305 while (true) {
306 if (LookingAtType(io::Tokenizer::TYPE_END)) {
307 // Ensures recursion limit properly unwinded, but only for success
308 // cases. This implicitly avoids the check when `Parse` returns false
309 // via `DO(...)`.
310 GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_)
311 << "Recursion limit at end of parse should be "
312 << initial_recursion_limit_ << ", but was " << recursion_limit_
313 << ". Difference of " << initial_recursion_limit_ - recursion_limit_
314 << " stack frames not accounted for stack unwind.";
315
316 return !had_errors_;
317 }
318
319 DO(ConsumeField(output));
320 }
321 }
322
323 bool ParseField(const FieldDescriptor* field, Message* output) {
324 bool suc;
325 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
326 suc = ConsumeFieldMessage(output, output->GetReflection(), field);
327 } else {
328 suc = ConsumeFieldValue(output, output->GetReflection(), field);
329 }
330 return suc && LookingAtType(io::Tokenizer::TYPE_END);
331 }
332
333 void ReportError(int line, int col, const std::string& message) {
334 had_errors_ = true;
335 if (error_collector_ == nullptr) {
336 if (line >= 0) {
337 GOOGLE_LOG(ERROR) << "Error parsing text-format "
338 << root_message_type_->full_name() << ": " << (line + 1)
339 << ":" << (col + 1) << ": " << message;
340 } else {
341 GOOGLE_LOG(ERROR) << "Error parsing text-format "
342 << root_message_type_->full_name() << ": " << message;
343 }
344 } else {
345 error_collector_->AddError(line, col, message);
346 }
347 }
348
349 void ReportWarning(int line, int col, const std::string& message) {
350 if (error_collector_ == nullptr) {
351 if (line >= 0) {
352 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
353 << root_message_type_->full_name() << ": " << (line + 1)
354 << ":" << (col + 1) << ": " << message;
355 } else {
356 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
357 << root_message_type_->full_name() << ": " << message;
358 }
359 } else {
360 error_collector_->AddWarning(line, col, message);
361 }
362 }
363
364 private:
365 static constexpr int32_t kint32max = std::numeric_limits<int32_t>::max();
366 static constexpr uint32_t kuint32max = std::numeric_limits<uint32_t>::max();
367 static constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
368 static constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
369 static constexpr uint64_t kuint64max = std::numeric_limits<uint64_t>::max();
370
371 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
372
373 // Reports an error with the given message with information indicating
374 // the position (as derived from the current token).
375 void ReportError(const std::string& message) {
376 ReportError(tokenizer_.current().line, tokenizer_.current().column,
377 message);
378 }
379
380 // Reports a warning with the given message with information indicating
381 // the position (as derived from the current token).
382 void ReportWarning(const std::string& message) {
383 ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
384 message);
385 }
386
387 // Consumes the specified message with the given starting delimiter.
388 // This method checks to see that the end delimiter at the conclusion of
389 // the consumption matches the starting delimiter passed in here.
390 bool ConsumeMessage(Message* message, const std::string delimiter) {
391 while (!LookingAt(">") && !LookingAt("}")) {
392 DO(ConsumeField(message));
393 }
394
395 // Confirm that we have a valid ending delimiter.
396 DO(Consume(delimiter));
397 return true;
398 }
399
400 // Consume either "<" or "{".
401 bool ConsumeMessageDelimiter(std::string* delimiter) {
402 if (TryConsume("<")) {
403 *delimiter = ">";
404 } else {
405 DO(Consume("{"));
406 *delimiter = "}";
407 }
408 return true;
409 }
410
411
412 // Consumes the current field (as returned by the tokenizer) on the
413 // passed in message.
414 bool ConsumeField(Message* message) {
415 const Reflection* reflection = message->GetReflection();
416 const Descriptor* descriptor = message->GetDescriptor();
417
418 std::string field_name;
419 bool reserved_field = false;
420 const FieldDescriptor* field = nullptr;
421 int start_line = tokenizer_.current().line;
422 int start_column = tokenizer_.current().column;
423
424 const FieldDescriptor* any_type_url_field;
425 const FieldDescriptor* any_value_field;
426 if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field,
427 &any_value_field) &&
428 TryConsume("[")) {
429 std::string full_type_name, prefix;
430 DO(ConsumeAnyTypeUrl(&full_type_name, &prefix));
431 std::string prefix_and_full_type_name =
432 StrCat(prefix, full_type_name);
433 DO(ConsumeBeforeWhitespace("]"));
434 TryConsumeWhitespace();
435 // ':' is optional between message labels and values.
436 if (TryConsumeBeforeWhitespace(":")) {
437 TryConsumeWhitespace();
438 }
439 std::string serialized_value;
440 const Descriptor* value_descriptor =
441 finder_ ? finder_->FindAnyType(*message, prefix, full_type_name)
442 : DefaultFinderFindAnyType(*message, prefix, full_type_name);
443 if (value_descriptor == nullptr) {
444 ReportError("Could not find type \"" + prefix_and_full_type_name +
445 "\" stored in google.protobuf.Any.");
446 return false;
447 }
448 DO(ConsumeAnyValue(value_descriptor, &serialized_value));
449 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
450 // Fail if any_type_url_field has already been specified.
451 if ((!any_type_url_field->is_repeated() &&
452 reflection->HasField(*message, any_type_url_field)) ||
453 (!any_value_field->is_repeated() &&
454 reflection->HasField(*message, any_value_field))) {
455 ReportError("Non-repeated Any specified multiple times.");
456 return false;
457 }
458 }
459 reflection->SetString(message, any_type_url_field,
460 std::move(prefix_and_full_type_name));
461 reflection->SetString(message, any_value_field,
462 std::move(serialized_value));
463 return true;
464 }
465 if (TryConsume("[")) {
466 // Extension.
467 DO(ConsumeFullTypeName(&field_name));
468 DO(ConsumeBeforeWhitespace("]"));
469 TryConsumeWhitespace();
470
471 field = finder_ ? finder_->FindExtension(message, field_name)
472 : DefaultFinderFindExtension(message, field_name);
473
474 if (field == nullptr) {
475 if (!allow_unknown_field_ && !allow_unknown_extension_) {
476 ReportError("Extension \"" + field_name +
477 "\" is not defined or "
478 "is not an extension of \"" +
479 descriptor->full_name() + "\".");
480 return false;
481 } else {
482 ReportWarning("Ignoring extension \"" + field_name +
483 "\" which is not defined or is not an extension of \"" +
484 descriptor->full_name() + "\".");
485 }
486 }
487 } else {
488 DO(ConsumeIdentifierBeforeWhitespace(&field_name));
489 TryConsumeWhitespace();
490
491 int32_t field_number;
492 if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
493 if (descriptor->IsExtensionNumber(field_number)) {
494 field = finder_
495 ? finder_->FindExtensionByNumber(descriptor, field_number)
496 : DefaultFinderFindExtensionByNumber(descriptor,
497 field_number);
498 } else if (descriptor->IsReservedNumber(field_number)) {
499 reserved_field = true;
500 } else {
501 field = descriptor->FindFieldByNumber(field_number);
502 }
503 } else {
504 field = descriptor->FindFieldByName(field_name);
505 // Group names are expected to be capitalized as they appear in the
506 // .proto file, which actually matches their type names, not their
507 // field names.
508 if (field == nullptr) {
509 std::string lower_field_name = field_name;
510 LowerString(&lower_field_name);
511 field = descriptor->FindFieldByName(lower_field_name);
512 // If the case-insensitive match worked but the field is NOT a group,
513 if (field != nullptr &&
514 field->type() != FieldDescriptor::TYPE_GROUP) {
515 field = nullptr;
516 }
517 }
518 // Again, special-case group names as described above.
519 if (field != nullptr && field->type() == FieldDescriptor::TYPE_GROUP &&
520 field->message_type()->name() != field_name) {
521 field = nullptr;
522 }
523
524 if (field == nullptr && allow_case_insensitive_field_) {
525 std::string lower_field_name = field_name;
526 LowerString(&lower_field_name);
527 field = descriptor->FindFieldByLowercaseName(lower_field_name);
528 }
529
530 if (field == nullptr) {
531 reserved_field = descriptor->IsReservedName(field_name);
532 }
533 }
534
535 if (field == nullptr && !reserved_field) {
536 if (!allow_unknown_field_) {
537 ReportError("Message type \"" + descriptor->full_name() +
538 "\" has no field named \"" + field_name + "\".");
539 return false;
540 } else {
541 ReportWarning("Message type \"" + descriptor->full_name() +
542 "\" has no field named \"" + field_name + "\".");
543 }
544 }
545 }
546
547 // Skips unknown or reserved fields.
548 if (field == nullptr) {
549 GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field);
550
551 // Try to guess the type of this field.
552 // If this field is not a message, there should be a ":" between the
553 // field name and the field value and also the field value should not
554 // start with "{" or "<" which indicates the beginning of a message body.
555 // If there is no ":" or there is a "{" or "<" after ":", this field has
556 // to be a message or the input is ill-formed.
557 if (TryConsumeBeforeWhitespace(":")) {
558 TryConsumeWhitespace();
559 if (!LookingAt("{") && !LookingAt("<")) {
560 return SkipFieldValue();
561 }
562 }
563 return SkipFieldMessage();
564 }
565
566 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
567 // Fail if the field is not repeated and it has already been specified.
568 if (!field->is_repeated() && reflection->HasField(*message, field)) {
569 ReportError("Non-repeated field \"" + field_name +
570 "\" is specified multiple times.");
571 return false;
572 }
573 // Fail if the field is a member of a oneof and another member has already
574 // been specified.
575 const OneofDescriptor* oneof = field->containing_oneof();
576 if (oneof != nullptr && reflection->HasOneof(*message, oneof)) {
577 const FieldDescriptor* other_field =
578 reflection->GetOneofFieldDescriptor(*message, oneof);
579 ReportError("Field \"" + field_name +
580 "\" is specified along with "
581 "field \"" +
582 other_field->name() +
583 "\", another member "
584 "of oneof \"" +
585 oneof->name() + "\".");
586 return false;
587 }
588 }
589
590 // Perform special handling for embedded message types.
591 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
592 // ':' is optional here.
593 bool consumed_semicolon = TryConsumeBeforeWhitespace(":");
594 if (consumed_semicolon) {
595 TryConsumeWhitespace();
596 }
597 if (consumed_semicolon && field->options().weak() &&
598 LookingAtType(io::Tokenizer::TYPE_STRING)) {
599 // we are getting a bytes string for a weak field.
600 std::string tmp;
601 DO(ConsumeString(&tmp));
602 MessageFactory* factory =
603 finder_ ? finder_->FindExtensionFactory(field) : nullptr;
604 reflection->MutableMessage(message, field, factory)
605 ->ParseFromString(tmp);
606 goto label_skip_parsing;
607 }
608 } else {
609 // ':' is required here.
610 DO(ConsumeBeforeWhitespace(":"));
611 TryConsumeWhitespace();
612 }
613
614 if (field->is_repeated() && TryConsume("[")) {
615 // Short repeated format, e.g. "foo: [1, 2, 3]".
616 if (!TryConsume("]")) {
617 // "foo: []" is treated as empty.
618 while (true) {
619 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
620 // Perform special handling for embedded message types.
621 DO(ConsumeFieldMessage(message, reflection, field));
622 } else {
623 DO(ConsumeFieldValue(message, reflection, field));
624 }
625 if (TryConsume("]")) {
626 break;
627 }
628 DO(Consume(","));
629 }
630 }
631 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
632 DO(ConsumeFieldMessage(message, reflection, field));
633 } else {
634 DO(ConsumeFieldValue(message, reflection, field));
635 }
636 label_skip_parsing:
637 // For historical reasons, fields may optionally be separated by commas or
638 // semicolons.
639 TryConsume(";") || TryConsume(",");
640
641 if (field->options().deprecated()) {
642 ReportWarning("text format contains deprecated field \"" + field_name +
643 "\"");
644 }
645
646 // If a parse info tree exists, add the location for the parsed
647 // field.
648 if (parse_info_tree_ != nullptr) {
649 int end_line = tokenizer_.previous().line;
650 int end_column = tokenizer_.previous().end_column;
651
652 RecordLocation(parse_info_tree_, field,
653 ParseLocationRange(ParseLocation(start_line, start_column),
654 ParseLocation(end_line, end_column)));
655 }
656
657 return true;
658 }
659
660 // Skips the next field including the field's name and value.
661 bool SkipField() {
662 std::string field_name;
663 if (TryConsume("[")) {
664 // Extension name or type URL.
665 DO(ConsumeTypeUrlOrFullTypeName(&field_name));
666 DO(ConsumeBeforeWhitespace("]"));
667 } else {
668 DO(ConsumeIdentifierBeforeWhitespace(&field_name));
669 }
670 TryConsumeWhitespace();
671
672 // Try to guess the type of this field.
673 // If this field is not a message, there should be a ":" between the
674 // field name and the field value and also the field value should not
675 // start with "{" or "<" which indicates the beginning of a message body.
676 // If there is no ":" or there is a "{" or "<" after ":", this field has
677 // to be a message or the input is ill-formed.
678 if (TryConsumeBeforeWhitespace(":")) {
679 TryConsumeWhitespace();
680 if (!LookingAt("{") && !LookingAt("<")) {
681 DO(SkipFieldValue());
682 } else {
683 DO(SkipFieldMessage());
684 }
685 } else {
686 DO(SkipFieldMessage());
687 }
688 // For historical reasons, fields may optionally be separated by commas or
689 // semicolons.
690 TryConsume(";") || TryConsume(",");
691 return true;
692 }
693
694 bool ConsumeFieldMessage(Message* message, const Reflection* reflection,
695 const FieldDescriptor* field) {
696 if (--recursion_limit_ < 0) {
697 ReportError(
698 StrCat("Message is too deep, the parser exceeded the "
699 "configured recursion limit of ",
700 initial_recursion_limit_, "."));
701 return false;
702 }
703 // If the parse information tree is not nullptr, create a nested one
704 // for the nested message.
705 ParseInfoTree* parent = parse_info_tree_;
706 if (parent != nullptr) {
707 parse_info_tree_ = CreateNested(parent, field);
708 }
709
710 std::string delimiter;
711 DO(ConsumeMessageDelimiter(&delimiter));
712 MessageFactory* factory =
713 finder_ ? finder_->FindExtensionFactory(field) : nullptr;
714 if (field->is_repeated()) {
715 DO(ConsumeMessage(reflection->AddMessage(message, field, factory),
716 delimiter));
717 } else {
718 DO(ConsumeMessage(reflection->MutableMessage(message, field, factory),
719 delimiter));
720 }
721
722 ++recursion_limit_;
723
724 // Reset the parse information tree.
725 parse_info_tree_ = parent;
726 return true;
727 }
728
729 // Skips the whole body of a message including the beginning delimiter and
730 // the ending delimiter.
731 bool SkipFieldMessage() {
732 if (--recursion_limit_ < 0) {
733 ReportError(
734 StrCat("Message is too deep, the parser exceeded the "
735 "configured recursion limit of ",
736 initial_recursion_limit_, "."));
737 return false;
738 }
739
740 std::string delimiter;
741 DO(ConsumeMessageDelimiter(&delimiter));
742 while (!LookingAt(">") && !LookingAt("}")) {
743 DO(SkipField());
744 }
745 DO(Consume(delimiter));
746
747 ++recursion_limit_;
748 return true;
749 }
750
751 bool ConsumeFieldValue(Message* message, const Reflection* reflection,
752 const FieldDescriptor* field) {
753// Define an easy to use macro for setting fields. This macro checks
754// to see if the field is repeated (in which case we need to use the Add
755// methods or not (in which case we need to use the Set methods).
756#define SET_FIELD(CPPTYPE, VALUE) \
757 if (field->is_repeated()) { \
758 reflection->Add##CPPTYPE(message, field, VALUE); \
759 } else { \
760 reflection->Set##CPPTYPE(message, field, VALUE); \
761 }
762
763 switch (field->cpp_type()) {
764 case FieldDescriptor::CPPTYPE_INT32: {
765 int64_t value;
766 DO(ConsumeSignedInteger(&value, kint32max));
767 SET_FIELD(Int32, static_cast<int32_t>(value));
768 break;
769 }
770
771 case FieldDescriptor::CPPTYPE_UINT32: {
772 uint64_t value;
773 DO(ConsumeUnsignedInteger(&value, kuint32max));
774 SET_FIELD(UInt32, static_cast<uint32_t>(value));
775 break;
776 }
777
778 case FieldDescriptor::CPPTYPE_INT64: {
779 int64_t value;
780 DO(ConsumeSignedInteger(&value, kint64max));
781 SET_FIELD(Int64, value);
782 break;
783 }
784
785 case FieldDescriptor::CPPTYPE_UINT64: {
786 uint64_t value;
787 DO(ConsumeUnsignedInteger(&value, kuint64max));
788 SET_FIELD(UInt64, value);
789 break;
790 }
791
792 case FieldDescriptor::CPPTYPE_FLOAT: {
793 double value;
794 DO(ConsumeDouble(&value));
795 SET_FIELD(Float, io::SafeDoubleToFloat(value));
796 break;
797 }
798
799 case FieldDescriptor::CPPTYPE_DOUBLE: {
800 double value;
801 DO(ConsumeDouble(&value));
802 SET_FIELD(Double, value);
803 break;
804 }
805
806 case FieldDescriptor::CPPTYPE_STRING: {
807 std::string value;
808 DO(ConsumeString(&value));
809 SET_FIELD(String, std::move(value));
810 break;
811 }
812
813 case FieldDescriptor::CPPTYPE_BOOL: {
814 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
815 uint64_t value;
816 DO(ConsumeUnsignedInteger(&value, 1));
817 SET_FIELD(Bool, value);
818 } else {
819 std::string value;
820 DO(ConsumeIdentifier(&value));
821 if (value == "true" || value == "True" || value == "t") {
822 SET_FIELD(Bool, true);
823 } else if (value == "false" || value == "False" || value == "f") {
824 SET_FIELD(Bool, false);
825 } else {
826 ReportError("Invalid value for boolean field \"" + field->name() +
827 "\". Value: \"" + value + "\".");
828 return false;
829 }
830 }
831 break;
832 }
833
834 case FieldDescriptor::CPPTYPE_ENUM: {
835 std::string value;
836 int64_t int_value = kint64max;
837 const EnumDescriptor* enum_type = field->enum_type();
838 const EnumValueDescriptor* enum_value = nullptr;
839
840 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
841 DO(ConsumeIdentifier(&value));
842 // Find the enumeration value.
843 enum_value = enum_type->FindValueByName(value);
844
845 } else if (LookingAt("-") ||
846 LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
847 DO(ConsumeSignedInteger(&int_value, kint32max));
848 value = StrCat(int_value); // for error reporting
849 enum_value = enum_type->FindValueByNumber(int_value);
850 } else {
851 ReportError("Expected integer or identifier, got: " +
852 tokenizer_.current().text);
853 return false;
854 }
855
856 if (enum_value == nullptr) {
857 if (int_value != kint64max &&
858 reflection->SupportsUnknownEnumValues()) {
859 SET_FIELD(EnumValue, int_value);
860 return true;
861 } else if (!allow_unknown_enum_) {
862 ReportError("Unknown enumeration value of \"" + value +
863 "\" for "
864 "field \"" +
865 field->name() + "\".");
866 return false;
867 } else {
868 ReportWarning("Unknown enumeration value of \"" + value +
869 "\" for "
870 "field \"" +
871 field->name() + "\".");
872 return true;
873 }
874 }
875
876 SET_FIELD(Enum, enum_value);
877 break;
878 }
879
880 case FieldDescriptor::CPPTYPE_MESSAGE: {
881 // We should never get here. Put here instead of a default
882 // so that if new types are added, we get a nice compiler warning.
883 GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
884 break;
885 }
886 }
887#undef SET_FIELD
888 return true;
889 }
890
891 bool SkipFieldValue() {
892 if (--recursion_limit_ < 0) {
893 ReportError(
894 StrCat("Message is too deep, the parser exceeded the "
895 "configured recursion limit of ",
896 initial_recursion_limit_, "."));
897 return false;
898 }
899
900 if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
901 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
902 tokenizer_.Next();
903 }
904 ++recursion_limit_;
905 return true;
906 }
907 if (TryConsume("[")) {
908 while (true) {
909 if (!LookingAt("{") && !LookingAt("<")) {
910 DO(SkipFieldValue());
911 } else {
912 DO(SkipFieldMessage());
913 }
914 if (TryConsume("]")) {
915 break;
916 }
917 DO(Consume(","));
918 }
919 ++recursion_limit_;
920 return true;
921 }
922 // Possible field values other than string:
923 // 12345 => TYPE_INTEGER
924 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
925 // 1.2345 => TYPE_FLOAT
926 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
927 // inf => TYPE_IDENTIFIER
928 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
929 // TYPE_INTEGER => TYPE_IDENTIFIER
930 // Divides them into two group, one with TYPE_SYMBOL
931 // and the other without:
932 // Group one:
933 // 12345 => TYPE_INTEGER
934 // 1.2345 => TYPE_FLOAT
935 // inf => TYPE_IDENTIFIER
936 // TYPE_INTEGER => TYPE_IDENTIFIER
937 // Group two:
938 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
939 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
940 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
941 // As we can see, the field value consists of an optional '-' and one of
942 // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
943 bool has_minus = TryConsume("-");
944 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
945 !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
946 !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
947 std::string text = tokenizer_.current().text;
948 ReportError("Cannot skip field value, unexpected token: " + text);
949 ++recursion_limit_;
950 return false;
951 }
952 // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
953 // value while other combinations all generate valid values.
954 // We check if the value of this combination is valid here.
955 // TYPE_IDENTIFIER after a '-' should be one of the float values listed
956 // below:
957 // inf, inff, infinity, nan
958 if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
959 std::string text = tokenizer_.current().text;
960 LowerString(&text);
961 if (text != "inf" &&
962 text != "infinity" && text != "nan") {
963 ReportError("Invalid float number: " + text);
964 ++recursion_limit_;
965 return false;
966 }
967 }
968 tokenizer_.Next();
969 ++recursion_limit_;
970 return true;
971 }
972
973 // Returns true if the current token's text is equal to that specified.
974 bool LookingAt(const std::string& text) {
975 return tokenizer_.current().text == text;
976 }
977
978 // Returns true if the current token's type is equal to that specified.
979 bool LookingAtType(io::Tokenizer::TokenType token_type) {
980 return tokenizer_.current().type == token_type;
981 }
982
983 // Consumes an identifier and saves its value in the identifier parameter.
984 // Returns false if the token is not of type IDENTIFIER.
985 bool ConsumeIdentifier(std::string* identifier) {
986 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
987 *identifier = tokenizer_.current().text;
988 tokenizer_.Next();
989 return true;
990 }
991
992 // If allow_field_numer_ or allow_unknown_field_ is true, we should able
993 // to parse integer identifiers.
994 if ((allow_field_number_ || allow_unknown_field_ ||
995 allow_unknown_extension_) &&
996 LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
997 *identifier = tokenizer_.current().text;
998 tokenizer_.Next();
999 return true;
1000 }
1001
1002 ReportError("Expected identifier, got: " + tokenizer_.current().text);
1003 return false;
1004 }
1005
1006 // Similar to `ConsumeIdentifier`, but any following whitespace token may
1007 // be reported.
1008 bool ConsumeIdentifierBeforeWhitespace(std::string* identifier) {
1009 tokenizer_.set_report_whitespace(true);
1010 bool result = ConsumeIdentifier(identifier);
1011 tokenizer_.set_report_whitespace(false);
1012 return result;
1013 }
1014
1015 // Consume a string of form "<id1>.<id2>....<idN>".
1016 bool ConsumeFullTypeName(std::string* name) {
1017 DO(ConsumeIdentifier(name));
1018 while (TryConsume(".")) {
1019 std::string part;
1020 DO(ConsumeIdentifier(&part));
1021 *name += ".";
1022 *name += part;
1023 }
1024 return true;
1025 }
1026
1027 bool ConsumeTypeUrlOrFullTypeName(std::string* name) {
1028 DO(ConsumeIdentifier(name));
1029 while (true) {
1030 std::string connector;
1031 if (TryConsume(".")) {
1032 connector = ".";
1033 } else if (TryConsume("/")) {
1034 connector = "/";
1035 } else {
1036 break;
1037 }
1038 std::string part;
1039 DO(ConsumeIdentifier(&part));
1040 *name += connector;
1041 *name += part;
1042 }
1043 return true;
1044 }
1045
1046 // Consumes a string and saves its value in the text parameter.
1047 // Returns false if the token is not of type STRING.
1048 bool ConsumeString(std::string* text) {
1049 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
1050 ReportError("Expected string, got: " + tokenizer_.current().text);
1051 return false;
1052 }
1053
1054 text->clear();
1055 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
1056 io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
1057
1058 tokenizer_.Next();
1059 }
1060
1061 return true;
1062 }
1063
1064 // Consumes a uint64_t and saves its value in the value parameter.
1065 // Returns false if the token is not of type INTEGER.
1066 bool ConsumeUnsignedInteger(uint64_t* value, uint64_t max_value) {
1067 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1068 ReportError("Expected integer, got: " + tokenizer_.current().text);
1069 return false;
1070 }
1071
1072 if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value,
1073 value)) {
1074 ReportError("Integer out of range (" + tokenizer_.current().text + ")");
1075 return false;
1076 }
1077
1078 tokenizer_.Next();
1079 return true;
1080 }
1081
1082 // Consumes an int64_t and saves its value in the value parameter.
1083 // Note that since the tokenizer does not support negative numbers,
1084 // we actually may consume an additional token (for the minus sign) in this
1085 // method. Returns false if the token is not an integer
1086 // (signed or otherwise).
1087 bool ConsumeSignedInteger(int64_t* value, uint64_t max_value) {
1088 bool negative = false;
1089
1090 if (TryConsume("-")) {
1091 negative = true;
1092 // Two's complement always allows one more negative integer than
1093 // positive.
1094 ++max_value;
1095 }
1096
1097 uint64_t unsigned_value;
1098
1099 DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
1100
1101 if (negative) {
1102 if ((static_cast<uint64_t>(kint64max) + 1) == unsigned_value) {
1103 *value = kint64min;
1104 } else {
1105 *value = -static_cast<int64_t>(unsigned_value);
1106 }
1107 } else {
1108 *value = static_cast<int64_t>(unsigned_value);
1109 }
1110
1111 return true;
1112 }
1113
1114 // Consumes a double and saves its value in the value parameter.
1115 // Accepts decimal numbers only, rejects hex or oct numbers.
1116 bool ConsumeUnsignedDecimalAsDouble(double* value, uint64_t max_value) {
1117 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1118 ReportError("Expected integer, got: " + tokenizer_.current().text);
1119 return false;
1120 }
1121
1122 const std::string& text = tokenizer_.current().text;
1123 if (IsHexNumber(text) || IsOctNumber(text)) {
1124 ReportError("Expect a decimal number, got: " + text);
1125 return false;
1126 }
1127
1128 uint64_t uint64_value;
1129 if (io::Tokenizer::ParseInteger(text, max_value, &uint64_value)) {
1130 *value = static_cast<double>(uint64_value);
1131 } else {
1132 // Uint64 overflow, attempt to parse as a double instead.
1133 *value = io::Tokenizer::ParseFloat(text);
1134 }
1135
1136 tokenizer_.Next();
1137 return true;
1138 }
1139
1140 // Consumes a double and saves its value in the value parameter.
1141 // Note that since the tokenizer does not support negative numbers,
1142 // we actually may consume an additional token (for the minus sign) in this
1143 // method. Returns false if the token is not a double
1144 // (signed or otherwise).
1145 bool ConsumeDouble(double* value) {
1146 bool negative = false;
1147
1148 if (TryConsume("-")) {
1149 negative = true;
1150 }
1151
1152 // A double can actually be an integer, according to the tokenizer.
1153 // Therefore, we must check both cases here.
1154 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1155 // We have found an integer value for the double.
1156 DO(ConsumeUnsignedDecimalAsDouble(value, kuint64max));
1157 } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
1158 // We have found a float value for the double.
1159 *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
1160
1161 // Mark the current token as consumed.
1162 tokenizer_.Next();
1163 } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
1164 std::string text = tokenizer_.current().text;
1165 LowerString(&text);
1166 if (text == "inf" ||
1167 text == "infinity") {
1168 *value = std::numeric_limits<double>::infinity();
1169 tokenizer_.Next();
1170 } else if (text == "nan") {
1171 *value = std::numeric_limits<double>::quiet_NaN();
1172 tokenizer_.Next();
1173 } else {
1174 ReportError("Expected double, got: " + text);
1175 return false;
1176 }
1177 } else {
1178 ReportError("Expected double, got: " + tokenizer_.current().text);
1179 return false;
1180 }
1181
1182 if (negative) {
1183 *value = -*value;
1184 }
1185
1186 return true;
1187 }
1188
1189 // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name"
1190 // or "type.googleprod.com/full.type.Name"
1191 bool ConsumeAnyTypeUrl(std::string* full_type_name, std::string* prefix) {
1192 // TODO(saito) Extend Consume() to consume multiple tokens at once, so that
1193 // this code can be written as just DO(Consume(kGoogleApisTypePrefix)).
1194 DO(ConsumeIdentifier(prefix));
1195 while (TryConsume(".")) {
1196 std::string url;
1197 DO(ConsumeIdentifier(&url));
1198 *prefix += "." + url;
1199 }
1200 DO(Consume("/"));
1201 *prefix += "/";
1202 DO(ConsumeFullTypeName(full_type_name));
1203
1204 return true;
1205 }
1206
1207 // A helper function for reconstructing Any::value. Consumes a text of
1208 // full_type_name, then serializes it into serialized_value.
1209 bool ConsumeAnyValue(const Descriptor* value_descriptor,
1210 std::string* serialized_value) {
1211 DynamicMessageFactory factory;
1212 const Message* value_prototype = factory.GetPrototype(value_descriptor);
1213 if (value_prototype == nullptr) {
1214 return false;
1215 }
1216 std::unique_ptr<Message> value(value_prototype->New());
1217 std::string sub_delimiter;
1218 DO(ConsumeMessageDelimiter(&sub_delimiter));
1219 DO(ConsumeMessage(value.get(), sub_delimiter));
1220
1221 if (allow_partial_) {
1222 value->AppendPartialToString(serialized_value);
1223 } else {
1224 if (!value->IsInitialized()) {
1225 ReportError(
1226 "Value of type \"" + value_descriptor->full_name() +
1227 "\" stored in google.protobuf.Any has missing required fields");
1228 return false;
1229 }
1230 value->AppendToString(serialized_value);
1231 }
1232 return true;
1233 }
1234
1235 // Consumes a token and confirms that it matches that specified in the
1236 // value parameter. Returns false if the token found does not match that
1237 // which was specified.
1238 bool Consume(const std::string& value) {
1239 const std::string& current_value = tokenizer_.current().text;
1240
1241 if (current_value != value) {
1242 ReportError("Expected \"" + value + "\", found \"" + current_value +
1243 "\".");
1244 return false;
1245 }
1246
1247 tokenizer_.Next();
1248
1249 return true;
1250 }
1251
1252 // Similar to `Consume`, but the following token may be tokenized as
1253 // TYPE_WHITESPACE.
1254 bool ConsumeBeforeWhitespace(const std::string& value) {
1255 // Report whitespace after this token, but only once.
1256 tokenizer_.set_report_whitespace(true);
1257 bool result = Consume(value);
1258 tokenizer_.set_report_whitespace(false);
1259 return result;
1260 }
1261
1262 // Attempts to consume the supplied value. Returns false if a the
1263 // token found does not match the value specified.
1264 bool TryConsume(const std::string& value) {
1265 if (tokenizer_.current().text == value) {
1266 tokenizer_.Next();
1267 return true;
1268 } else {
1269 return false;
1270 }
1271 }
1272
1273 // Similar to `TryConsume`, but the following token may be tokenized as
1274 // TYPE_WHITESPACE.
1275 bool TryConsumeBeforeWhitespace(const std::string& value) {
1276 // Report whitespace after this token, but only once.
1277 tokenizer_.set_report_whitespace(true);
1278 bool result = TryConsume(value);
1279 tokenizer_.set_report_whitespace(false);
1280 return result;
1281 }
1282
1283 bool TryConsumeWhitespace() {
1284 had_silent_marker_ = false;
1285 if (LookingAtType(io::Tokenizer::TYPE_WHITESPACE)) {
1286 if (tokenizer_.current().text ==
1287 StrCat(" ", internal::kDebugStringSilentMarkerForDetection)) {
1288 had_silent_marker_ = true;
1289 }
1290 tokenizer_.Next();
1291 return true;
1292 }
1293 return false;
1294 }
1295
1296 // An internal instance of the Tokenizer's error collector, used to
1297 // collect any base-level parse errors and feed them to the ParserImpl.
1298 class ParserErrorCollector : public io::ErrorCollector {
1299 public:
1300 explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser)
1301 : parser_(parser) {}
1302
1303 ~ParserErrorCollector() override {}
1304
1305 void AddError(int line, int column, const std::string& message) override {
1306 parser_->ReportError(line, column, message);
1307 }
1308
1309 void AddWarning(int line, int column, const std::string& message) override {
1310 parser_->ReportWarning(line, column, message);
1311 }
1312
1313 private:
1314 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
1315 TextFormat::Parser::ParserImpl* parser_;
1316 };
1317
1318 io::ErrorCollector* error_collector_;
1319 const TextFormat::Finder* finder_;
1320 ParseInfoTree* parse_info_tree_;
1321 ParserErrorCollector tokenizer_error_collector_;
1322 io::Tokenizer tokenizer_;
1323 const Descriptor* root_message_type_;
1324 SingularOverwritePolicy singular_overwrite_policy_;
1325 const bool allow_case_insensitive_field_;
1326 const bool allow_unknown_field_;
1327 const bool allow_unknown_extension_;
1328 const bool allow_unknown_enum_;
1329 const bool allow_field_number_;
1330 const bool allow_partial_;
1331 const int initial_recursion_limit_;
1332 int recursion_limit_;
1333 bool had_silent_marker_;
1334 bool had_errors_;
1335};
1336
1337// ===========================================================================
1338// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
1339// from the Printer found in //net/proto2/io/public/printer.h
1340class TextFormat::Printer::TextGenerator
1341 : public TextFormat::BaseTextGenerator {
1342 public:
1343 explicit TextGenerator(io::ZeroCopyOutputStream* output,
1344 int initial_indent_level)
1345 : output_(output),
1346 buffer_(nullptr),
1347 buffer_size_(0),
1348 at_start_of_line_(true),
1349 failed_(false),
1350 insert_silent_marker_(false),
1351 indent_level_(initial_indent_level),
1352 initial_indent_level_(initial_indent_level) {}
1353
1354 explicit TextGenerator(io::ZeroCopyOutputStream* output,
1355 bool insert_silent_marker, int initial_indent_level)
1356 : output_(output),
1357 buffer_(nullptr),
1358 buffer_size_(0),
1359 at_start_of_line_(true),
1360 failed_(false),
1361 insert_silent_marker_(insert_silent_marker),
1362 indent_level_(initial_indent_level),
1363 initial_indent_level_(initial_indent_level) {}
1364
1365 ~TextGenerator() override {
1366 // Only BackUp() if we're sure we've successfully called Next() at least
1367 // once.
1368 if (!failed_) {
1369 output_->BackUp(buffer_size_);
1370 }
1371 }
1372
1373 // Indent text by two spaces. After calling Indent(), two spaces will be
1374 // inserted at the beginning of each line of text. Indent() may be called
1375 // multiple times to produce deeper indents.
1376 void Indent() override { ++indent_level_; }
1377
1378 // Reduces the current indent level by two spaces, or crashes if the indent
1379 // level is zero.
1380 void Outdent() override {
1381 if (indent_level_ == 0 || indent_level_ < initial_indent_level_) {
1382 GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
1383 return;
1384 }
1385
1386 --indent_level_;
1387 }
1388
1389 size_t GetCurrentIndentationSize() const override {
1390 return 2 * indent_level_;
1391 }
1392
1393 // Print text to the output stream.
1394 void Print(const char* text, size_t size) override {
1395 if (indent_level_ > 0) {
1396 size_t pos = 0; // The number of bytes we've written so far.
1397 for (size_t i = 0; i < size; i++) {
1398 if (text[i] == '\n') {
1399 // Saw newline. If there is more text, we may need to insert an
1400 // indent here. So, write what we have so far, including the '\n'.
1401 Write(text + pos, i - pos + 1);
1402 pos = i + 1;
1403
1404 // Setting this true will cause the next Write() to insert an indent
1405 // first.
1406 at_start_of_line_ = true;
1407 }
1408 }
1409 // Write the rest.
1410 Write(text + pos, size - pos);
1411 } else {
1412 Write(text, size);
1413 if (size > 0 && text[size - 1] == '\n') {
1414 at_start_of_line_ = true;
1415 }
1416 }
1417 }
1418
1419 // True if any write to the underlying stream failed. (We don't just
1420 // crash in this case because this is an I/O failure, not a programming
1421 // error.)
1422 bool failed() const { return failed_; }
1423
1424 void PrintMaybeWithMarker(StringPiece text) {
1425 Print(text.data(), text.size());
1426 if (ConsumeInsertSilentMarker()) {
1427 PrintLiteral(internal::kDebugStringSilentMarker);
1428 }
1429 }
1430
1431 void PrintMaybeWithMarker(StringPiece text_head,
1432 StringPiece text_tail) {
1433 Print(text_head.data(), text_head.size());
1434 if (ConsumeInsertSilentMarker()) {
1435 PrintLiteral(internal::kDebugStringSilentMarker);
1436 }
1437 Print(text_tail.data(), text_tail.size());
1438 }
1439
1440 private:
1441 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
1442
1443 void Write(const char* data, size_t size) {
1444 if (failed_) return;
1445 if (size == 0) return;
1446
1447 if (at_start_of_line_) {
1448 // Insert an indent.
1449 at_start_of_line_ = false;
1450 WriteIndent();
1451 if (failed_) return;
1452 }
1453
1454 while (static_cast<int64_t>(size) > buffer_size_) {
1455 // Data exceeds space in the buffer. Copy what we can and request a
1456 // new buffer.
1457 if (buffer_size_ > 0) {
1458 memcpy(buffer_, data, buffer_size_);
1459 data += buffer_size_;
1460 size -= buffer_size_;
1461 }
1462 void* void_buffer = nullptr;
1463 failed_ = !output_->Next(&void_buffer, &buffer_size_);
1464 if (failed_) return;
1465 buffer_ = reinterpret_cast<char*>(void_buffer);
1466 }
1467
1468 // Buffer is big enough to receive the data; copy it.
1469 memcpy(buffer_, data, size);
1470 buffer_ += size;
1471 buffer_size_ -= size;
1472 }
1473
1474 void WriteIndent() {
1475 if (indent_level_ == 0) {
1476 return;
1477 }
1478 GOOGLE_DCHECK(!failed_);
1479 int size = GetCurrentIndentationSize();
1480
1481 while (size > buffer_size_) {
1482 // Data exceeds space in the buffer. Write what we can and request a new
1483 // buffer.
1484 if (buffer_size_ > 0) {
1485 memset(buffer_, ' ', buffer_size_);
1486 }
1487 size -= buffer_size_;
1488 void* void_buffer;
1489 failed_ = !output_->Next(&void_buffer, &buffer_size_);
1490 if (failed_) return;
1491 buffer_ = reinterpret_cast<char*>(void_buffer);
1492 }
1493
1494 // Buffer is big enough to receive the data; copy it.
1495 memset(buffer_, ' ', size);
1496 buffer_ += size;
1497 buffer_size_ -= size;
1498 }
1499
1500 // Return the current value of insert_silent_marker_. If it is true, set it
1501 // to false as we assume that a silent marker is inserted after a call to this
1502 // function.
1503 bool ConsumeInsertSilentMarker() {
1504 if (insert_silent_marker_) {
1505 insert_silent_marker_ = false;
1506 return true;
1507 }
1508 return false;
1509 }
1510
1511 io::ZeroCopyOutputStream* const output_;
1512 char* buffer_;
1513 int buffer_size_;
1514 bool at_start_of_line_;
1515 bool failed_;
1516 // This flag is false when inserting silent marker is disabled or a silent
1517 // marker has been inserted.
1518 bool insert_silent_marker_;
1519
1520 int indent_level_;
1521 int initial_indent_level_;
1522};
1523
1524// ===========================================================================
1525// An internal field value printer that may insert a silent marker in
1526// DebugStrings.
1527class TextFormat::Printer::DebugStringFieldValuePrinter
1528 : public TextFormat::FastFieldValuePrinter {
1529 public:
1530 void PrintMessageStart(const Message& /*message*/, int /*field_index*/,
1531 int /*field_count*/, bool single_line_mode,
1532 BaseTextGenerator* generator) const override {
1533 // This is safe as only TextGenerator is used with
1534 // DebugStringFieldValuePrinter.
1535 TextGenerator* text_generator = static_cast<TextGenerator*>(generator);
1536 if (single_line_mode) {
1537 text_generator->PrintMaybeWithMarker(" ", "{ ");
1538 } else {
1539 text_generator->PrintMaybeWithMarker(" ", "{\n");
1540 }
1541 }
1542};
1543
1544// ===========================================================================
1545// An internal field value printer that escape UTF8 strings.
1546class TextFormat::Printer::FastFieldValuePrinterUtf8Escaping
1547 : public TextFormat::Printer::DebugStringFieldValuePrinter {
1548 public:
1549 void PrintString(const std::string& val,
1550 TextFormat::BaseTextGenerator* generator) const override {
1551 generator->PrintLiteral("\"");
1552 generator->PrintString(strings::Utf8SafeCEscape(val));
1553 generator->PrintLiteral("\"");
1554 }
1555 void PrintBytes(const std::string& val,
1556 TextFormat::BaseTextGenerator* generator) const override {
1557 return FastFieldValuePrinter::PrintString(val, generator);
1558 }
1559};
1560
1561// ===========================================================================
1562// Implementation of the default Finder for extensions.
1563TextFormat::Finder::~Finder() {}
1564
1565const FieldDescriptor* TextFormat::Finder::FindExtension(
1566 Message* message, const std::string& name) const {
1567 return DefaultFinderFindExtension(message, name);
1568}
1569
1570const FieldDescriptor* TextFormat::Finder::FindExtensionByNumber(
1571 const Descriptor* descriptor, int number) const {
1572 return DefaultFinderFindExtensionByNumber(descriptor, number);
1573}
1574
1575const Descriptor* TextFormat::Finder::FindAnyType(
1576 const Message& message, const std::string& prefix,
1577 const std::string& name) const {
1578 return DefaultFinderFindAnyType(message, prefix, name);
1579}
1580
1581MessageFactory* TextFormat::Finder::FindExtensionFactory(
1582 const FieldDescriptor* /*field*/) const {
1583 return nullptr;
1584}
1585
1586// ===========================================================================
1587
1588TextFormat::Parser::Parser()
1589 : error_collector_(nullptr),
1590 finder_(nullptr),
1591 parse_info_tree_(nullptr),
1592 allow_partial_(false),
1593 allow_case_insensitive_field_(false),
1594 allow_unknown_field_(false),
1595 allow_unknown_extension_(false),
1596 allow_unknown_enum_(false),
1597 allow_field_number_(false),
1598 allow_relaxed_whitespace_(false),
1599 allow_singular_overwrites_(false),
1600 recursion_limit_(std::numeric_limits<int>::max()) {}
1601
1602TextFormat::Parser::~Parser() {}
1603
1604namespace {
1605
1606bool CheckParseInputSize(StringPiece input,
1607 io::ErrorCollector* error_collector) {
1608 if (input.size() > INT_MAX) {
1609 error_collector->AddError(
1610 -1, 0,
1611 StrCat(
1612 "Input size too large: ", static_cast<int64_t>(input.size()),
1613 " bytes", " > ", INT_MAX, " bytes."));
1614 return false;
1615 }
1616 return true;
1617}
1618
1619} // namespace
1620
1621bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
1622 Message* output) {
1623 output->Clear();
1624
1625 ParserImpl::SingularOverwritePolicy overwrites_policy =
1626 allow_singular_overwrites_ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
1627 : ParserImpl::FORBID_SINGULAR_OVERWRITES;
1628
1629 ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
1630 parse_info_tree_, overwrites_policy,
1631 allow_case_insensitive_field_, allow_unknown_field_,
1632 allow_unknown_extension_, allow_unknown_enum_,
1633 allow_field_number_, allow_relaxed_whitespace_,
1634 allow_partial_, recursion_limit_);
1635 return MergeUsingImpl(input, output, &parser);
1636}
1637
1638bool TextFormat::Parser::ParseFromString(ConstStringParam input,
1639 Message* output) {
1640 DO(CheckParseInputSize(input, error_collector_));
1641 io::ArrayInputStream input_stream(input.data(), input.size());
1642 return Parse(&input_stream, output);
1643}
1644
1645bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
1646 Message* output) {
1647 ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
1648 parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1649 allow_case_insensitive_field_, allow_unknown_field_,
1650 allow_unknown_extension_, allow_unknown_enum_,
1651 allow_field_number_, allow_relaxed_whitespace_,
1652 allow_partial_, recursion_limit_);
1653 return MergeUsingImpl(input, output, &parser);
1654}
1655
1656bool TextFormat::Parser::MergeFromString(ConstStringParam input,
1657 Message* output) {
1658 DO(CheckParseInputSize(input, error_collector_));
1659 io::ArrayInputStream input_stream(input.data(), input.size());
1660 return Merge(&input_stream, output);
1661}
1662
1663bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
1664 Message* output,
1665 ParserImpl* parser_impl) {
1666 if (!parser_impl->Parse(output)) return false;
1667 if (!allow_partial_ && !output->IsInitialized()) {
1668 std::vector<std::string> missing_fields;
1669 output->FindInitializationErrors(&missing_fields);
1670 parser_impl->ReportError(-1, 0,
1671 "Message missing required fields: " +
1672 Join(missing_fields, ", "));
1673 return false;
1674 }
1675 return true;
1676}
1677
1678bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input,
1679 const FieldDescriptor* field,
1680 Message* output) {
1681 io::ArrayInputStream input_stream(input.data(), input.size());
1682 ParserImpl parser(
1683 output->GetDescriptor(), &input_stream, error_collector_, finder_,
1684 parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1685 allow_case_insensitive_field_, allow_unknown_field_,
1686 allow_unknown_extension_, allow_unknown_enum_, allow_field_number_,
1687 allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
1688 return parser.ParseField(field, output);
1689}
1690
1691/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1692 Message* output) {
1693 return Parser().Parse(input, output);
1694}
1695
1696/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1697 Message* output) {
1698 return Parser().Merge(input, output);
1699}
1700
1701/* static */ bool TextFormat::ParseFromString(ConstStringParam input,
1702 Message* output) {
1703 return Parser().ParseFromString(input, output);
1704}
1705
1706/* static */ bool TextFormat::MergeFromString(ConstStringParam input,
1707 Message* output) {
1708 return Parser().MergeFromString(input, output);
1709}
1710
1711#undef DO
1712
1713// ===========================================================================
1714
1715TextFormat::BaseTextGenerator::~BaseTextGenerator() {}
1716
1717namespace {
1718
1719// A BaseTextGenerator that writes to a string.
1720class StringBaseTextGenerator : public TextFormat::BaseTextGenerator {
1721 public:
1722 void Print(const char* text, size_t size) override {
1723 output_.append(text, size);
1724 }
1725
1726// Some compilers do not support ref-qualifiers even in C++11 mode.
1727// Disable the optimization for now and revisit it later.
1728#if 0 // LANG_CXX11
1729 std::string Consume() && { return std::move(output_); }
1730#else // !LANG_CXX11
1731 const std::string& Get() { return output_; }
1732#endif // LANG_CXX11
1733
1734 private:
1735 std::string output_;
1736};
1737
1738} // namespace
1739
1740// The default implementation for FieldValuePrinter. We just delegate the
1741// implementation to the default FastFieldValuePrinter to avoid duplicating the
1742// logic.
1743TextFormat::FieldValuePrinter::FieldValuePrinter() {}
1744TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
1745
1746#if 0 // LANG_CXX11
1747#define FORWARD_IMPL(fn, ...) \
1748 StringBaseTextGenerator generator; \
1749 delegate_.fn(__VA_ARGS__, &generator); \
1750 return std::move(generator).Consume()
1751#else // !LANG_CXX11
1752#define FORWARD_IMPL(fn, ...) \
1753 StringBaseTextGenerator generator; \
1754 delegate_.fn(__VA_ARGS__, &generator); \
1755 return generator.Get()
1756#endif // LANG_CXX11
1757
1758std::string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
1759 FORWARD_IMPL(PrintBool, val);
1760}
1761std::string TextFormat::FieldValuePrinter::PrintInt32(int32_t val) const {
1762 FORWARD_IMPL(PrintInt32, val);
1763}
1764std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32_t val) const {
1765 FORWARD_IMPL(PrintUInt32, val);
1766}
1767std::string TextFormat::FieldValuePrinter::PrintInt64(int64_t val) const {
1768 FORWARD_IMPL(PrintInt64, val);
1769}
1770std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64_t val) const {
1771 FORWARD_IMPL(PrintUInt64, val);
1772}
1773std::string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
1774 FORWARD_IMPL(PrintFloat, val);
1775}
1776std::string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
1777 FORWARD_IMPL(PrintDouble, val);
1778}
1779std::string TextFormat::FieldValuePrinter::PrintString(
1780 const std::string& val) const {
1781 FORWARD_IMPL(PrintString, val);
1782}
1783std::string TextFormat::FieldValuePrinter::PrintBytes(
1784 const std::string& val) const {
1785 return PrintString(val);
1786}
1787std::string TextFormat::FieldValuePrinter::PrintEnum(
1788 int32_t val, const std::string& name) const {
1789 FORWARD_IMPL(PrintEnum, val, name);
1790}
1791std::string TextFormat::FieldValuePrinter::PrintFieldName(
1792 const Message& message, const Reflection* reflection,
1793 const FieldDescriptor* field) const {
1794 FORWARD_IMPL(PrintFieldName, message, reflection, field);
1795}
1796std::string TextFormat::FieldValuePrinter::PrintMessageStart(
1797 const Message& message, int field_index, int field_count,
1798 bool single_line_mode) const {
1799 FORWARD_IMPL(PrintMessageStart, message, field_index, field_count,
1800 single_line_mode);
1801}
1802std::string TextFormat::FieldValuePrinter::PrintMessageEnd(
1803 const Message& message, int field_index, int field_count,
1804 bool single_line_mode) const {
1805 FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count,
1806 single_line_mode);
1807}
1808#undef FORWARD_IMPL
1809
1810TextFormat::FastFieldValuePrinter::FastFieldValuePrinter() {}
1811TextFormat::FastFieldValuePrinter::~FastFieldValuePrinter() {}
1812void TextFormat::FastFieldValuePrinter::PrintBool(
1813 bool val, BaseTextGenerator* generator) const {
1814 if (val) {
1815 generator->PrintLiteral("true");
1816 } else {
1817 generator->PrintLiteral("false");
1818 }
1819}
1820void TextFormat::FastFieldValuePrinter::PrintInt32(
1821 int32_t val, BaseTextGenerator* generator) const {
1822 generator->PrintString(StrCat(val));
1823}
1824void TextFormat::FastFieldValuePrinter::PrintUInt32(
1825 uint32_t val, BaseTextGenerator* generator) const {
1826 generator->PrintString(StrCat(val));
1827}
1828void TextFormat::FastFieldValuePrinter::PrintInt64(
1829 int64_t val, BaseTextGenerator* generator) const {
1830 generator->PrintString(StrCat(val));
1831}
1832void TextFormat::FastFieldValuePrinter::PrintUInt64(
1833 uint64_t val, BaseTextGenerator* generator) const {
1834 generator->PrintString(StrCat(val));
1835}
1836void TextFormat::FastFieldValuePrinter::PrintFloat(
1837 float val, BaseTextGenerator* generator) const {
1838 generator->PrintString(!std::isnan(val) ? SimpleFtoa(val) : "nan");
1839}
1840void TextFormat::FastFieldValuePrinter::PrintDouble(
1841 double val, BaseTextGenerator* generator) const {
1842 generator->PrintString(!std::isnan(val) ? SimpleDtoa(val) : "nan");
1843}
1844void TextFormat::FastFieldValuePrinter::PrintEnum(
1845 int32_t /*val*/, const std::string& name,
1846 BaseTextGenerator* generator) const {
1847 generator->PrintString(name);
1848}
1849
1850void TextFormat::FastFieldValuePrinter::PrintString(
1851 const std::string& val, BaseTextGenerator* generator) const {
1852 generator->PrintLiteral("\"");
1853 generator->PrintString(CEscape(val));
1854 generator->PrintLiteral("\"");
1855}
1856void TextFormat::FastFieldValuePrinter::PrintBytes(
1857 const std::string& val, BaseTextGenerator* generator) const {
1858 PrintString(val, generator);
1859}
1860void TextFormat::FastFieldValuePrinter::PrintFieldName(
1861 const Message& message, int /*field_index*/, int /*field_count*/,
1862 const Reflection* reflection, const FieldDescriptor* field,
1863 BaseTextGenerator* generator) const {
1864 PrintFieldName(message, reflection, field, generator);
1865}
1866void TextFormat::FastFieldValuePrinter::PrintFieldName(
1867 const Message& /*message*/, const Reflection* /*reflection*/,
1868 const FieldDescriptor* field, BaseTextGenerator* generator) const {
1869 if (field->is_extension()) {
1870 generator->PrintLiteral("[");
1871 generator->PrintString(field->PrintableNameForExtension());
1872 generator->PrintLiteral("]");
1873 } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
1874 // Groups must be serialized with their original capitalization.
1875 generator->PrintString(field->message_type()->name());
1876 } else {
1877 generator->PrintString(field->name());
1878 }
1879}
1880void TextFormat::FastFieldValuePrinter::PrintMessageStart(
1881 const Message& /*message*/, int /*field_index*/, int /*field_count*/,
1882 bool single_line_mode, BaseTextGenerator* generator) const {
1883 if (single_line_mode) {
1884 generator->PrintLiteral(" { ");
1885 } else {
1886 generator->PrintLiteral(" {\n");
1887 }
1888}
1889bool TextFormat::FastFieldValuePrinter::PrintMessageContent(
1890 const Message& /*message*/, int /*field_index*/, int /*field_count*/,
1891 bool /*single_line_mode*/, BaseTextGenerator* /*generator*/) const {
1892 return false; // Use the default printing function.
1893}
1894void TextFormat::FastFieldValuePrinter::PrintMessageEnd(
1895 const Message& /*message*/, int /*field_index*/, int /*field_count*/,
1896 bool single_line_mode, BaseTextGenerator* generator) const {
1897 if (single_line_mode) {
1898 generator->PrintLiteral("} ");
1899 } else {
1900 generator->PrintLiteral("}\n");
1901 }
1902}
1903
1904namespace {
1905
1906// A legacy compatibility wrapper. Takes ownership of the delegate.
1907class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter {
1908 public:
1909 explicit FieldValuePrinterWrapper(
1910 const TextFormat::FieldValuePrinter* delegate)
1911 : delegate_(delegate) {}
1912
1913 void SetDelegate(const TextFormat::FieldValuePrinter* delegate) {
1914 delegate_.reset(delegate);
1915 }
1916
1917 void PrintBool(bool val,
1918 TextFormat::BaseTextGenerator* generator) const override {
1919 generator->PrintString(delegate_->PrintBool(val));
1920 }
1921 void PrintInt32(int32_t val,
1922 TextFormat::BaseTextGenerator* generator) const override {
1923 generator->PrintString(delegate_->PrintInt32(val));
1924 }
1925 void PrintUInt32(uint32_t val,
1926 TextFormat::BaseTextGenerator* generator) const override {
1927 generator->PrintString(delegate_->PrintUInt32(val));
1928 }
1929 void PrintInt64(int64_t val,
1930 TextFormat::BaseTextGenerator* generator) const override {
1931 generator->PrintString(delegate_->PrintInt64(val));
1932 }
1933 void PrintUInt64(uint64_t val,
1934 TextFormat::BaseTextGenerator* generator) const override {
1935 generator->PrintString(delegate_->PrintUInt64(val));
1936 }
1937 void PrintFloat(float val,
1938 TextFormat::BaseTextGenerator* generator) const override {
1939 generator->PrintString(delegate_->PrintFloat(val));
1940 }
1941 void PrintDouble(double val,
1942 TextFormat::BaseTextGenerator* generator) const override {
1943 generator->PrintString(delegate_->PrintDouble(val));
1944 }
1945 void PrintString(const std::string& val,
1946 TextFormat::BaseTextGenerator* generator) const override {
1947 generator->PrintString(delegate_->PrintString(val));
1948 }
1949 void PrintBytes(const std::string& val,
1950 TextFormat::BaseTextGenerator* generator) const override {
1951 generator->PrintString(delegate_->PrintBytes(val));
1952 }
1953 void PrintEnum(int32_t val, const std::string& name,
1954 TextFormat::BaseTextGenerator* generator) const override {
1955 generator->PrintString(delegate_->PrintEnum(val, name));
1956 }
1957 void PrintFieldName(const Message& message, int /*field_index*/,
1958 int /*field_count*/, const Reflection* reflection,
1959 const FieldDescriptor* field,
1960 TextFormat::BaseTextGenerator* generator) const override {
1961 generator->PrintString(
1962 delegate_->PrintFieldName(message, reflection, field));
1963 }
1964 void PrintFieldName(const Message& message, const Reflection* reflection,
1965 const FieldDescriptor* field,
1966 TextFormat::BaseTextGenerator* generator) const override {
1967 generator->PrintString(
1968 delegate_->PrintFieldName(message, reflection, field));
1969 }
1970 void PrintMessageStart(
1971 const Message& message, int field_index, int field_count,
1972 bool single_line_mode,
1973 TextFormat::BaseTextGenerator* generator) const override {
1974 generator->PrintString(delegate_->PrintMessageStart(
1975 message, field_index, field_count, single_line_mode));
1976 }
1977 void PrintMessageEnd(
1978 const Message& message, int field_index, int field_count,
1979 bool single_line_mode,
1980 TextFormat::BaseTextGenerator* generator) const override {
1981 generator->PrintString(delegate_->PrintMessageEnd(
1982 message, field_index, field_count, single_line_mode));
1983 }
1984
1985 private:
1986 std::unique_ptr<const TextFormat::FieldValuePrinter> delegate_;
1987};
1988
1989} // namespace
1990
1991const char* const TextFormat::Printer::kDoNotParse =
1992 "DO NOT PARSE: fields may be stripped and missing.\n";
1993
1994TextFormat::Printer::Printer()
1995 : initial_indent_level_(0),
1996 single_line_mode_(false),
1997 use_field_number_(false),
1998 use_short_repeated_primitives_(false),
1999 insert_silent_marker_(false),
2000 hide_unknown_fields_(false),
2001 print_message_fields_in_index_order_(false),
2002 expand_any_(false),
2003 truncate_string_field_longer_than_(0LL),
2004 finder_(nullptr) {
2005 SetUseUtf8StringEscaping(false);
2006}
2007
2008void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
2009 SetDefaultFieldValuePrinter(as_utf8 ? new FastFieldValuePrinterUtf8Escaping()
2010 : new DebugStringFieldValuePrinter());
2011}
2012
2013void TextFormat::Printer::SetDefaultFieldValuePrinter(
2014 const FieldValuePrinter* printer) {
2015 default_field_value_printer_.reset(new FieldValuePrinterWrapper(printer));
2016}
2017
2018void TextFormat::Printer::SetDefaultFieldValuePrinter(
2019 const FastFieldValuePrinter* printer) {
2020 default_field_value_printer_.reset(printer);
2021}
2022
2023bool TextFormat::Printer::RegisterFieldValuePrinter(
2024 const FieldDescriptor* field, const FieldValuePrinter* printer) {
2025 if (field == nullptr || printer == nullptr) {
2026 return false;
2027 }
2028 std::unique_ptr<FieldValuePrinterWrapper> wrapper(
2029 new FieldValuePrinterWrapper(nullptr));
2030 auto pair = custom_printers_.insert(std::make_pair(field, nullptr));
2031 if (pair.second) {
2032 wrapper->SetDelegate(printer);
2033 pair.first->second = std::move(wrapper);
2034 return true;
2035 } else {
2036 return false;
2037 }
2038}
2039
2040bool TextFormat::Printer::RegisterFieldValuePrinter(
2041 const FieldDescriptor* field, const FastFieldValuePrinter* printer) {
2042 if (field == nullptr || printer == nullptr) {
2043 return false;
2044 }
2045 auto pair = custom_printers_.insert(std::make_pair(field, nullptr));
2046 if (pair.second) {
2047 pair.first->second.reset(printer);
2048 return true;
2049 } else {
2050 return false;
2051 }
2052}
2053
2054bool TextFormat::Printer::RegisterMessagePrinter(
2055 const Descriptor* descriptor, const MessagePrinter* printer) {
2056 if (descriptor == nullptr || printer == nullptr) {
2057 return false;
2058 }
2059 auto pair =
2060 custom_message_printers_.insert(std::make_pair(descriptor, nullptr));
2061 if (pair.second) {
2062 pair.first->second.reset(printer);
2063 return true;
2064 } else {
2065 return false;
2066 }
2067}
2068
2069bool TextFormat::Printer::PrintToString(const Message& message,
2070 std::string* output) const {
2071 GOOGLE_DCHECK(output) << "output specified is nullptr";
2072
2073 output->clear();
2074 io::StringOutputStream output_stream(output);
2075
2076 return Print(message, &output_stream);
2077}
2078
2079bool TextFormat::Printer::PrintUnknownFieldsToString(
2080 const UnknownFieldSet& unknown_fields, std::string* output) const {
2081 GOOGLE_DCHECK(output) << "output specified is nullptr";
2082
2083 output->clear();
2084 io::StringOutputStream output_stream(output);
2085 return PrintUnknownFields(unknown_fields, &output_stream);
2086}
2087
2088bool TextFormat::Printer::Print(const Message& message,
2089 io::ZeroCopyOutputStream* output) const {
2090 TextGenerator generator(output, insert_silent_marker_, initial_indent_level_);
2091
2092 Print(message, &generator);
2093
2094 // Output false if the generator failed internally.
2095 return !generator.failed();
2096}
2097
2098// Maximum recursion depth for heuristically printing out length-delimited
2099// unknown fields as messages.
2100static constexpr int kUnknownFieldRecursionLimit = 10;
2101
2102bool TextFormat::Printer::PrintUnknownFields(
2103 const UnknownFieldSet& unknown_fields,
2104 io::ZeroCopyOutputStream* output) const {
2105 TextGenerator generator(output, initial_indent_level_);
2106
2107 PrintUnknownFields(unknown_fields, &generator, kUnknownFieldRecursionLimit);
2108
2109 // Output false if the generator failed internally.
2110 return !generator.failed();
2111}
2112
2113namespace {
2114// Comparison functor for sorting FieldDescriptors by field index.
2115// Normal fields have higher precedence than extensions.
2116struct FieldIndexSorter {
2117 bool operator()(const FieldDescriptor* left,
2118 const FieldDescriptor* right) const {
2119 if (left->is_extension() && right->is_extension()) {
2120 return left->number() < right->number();
2121 } else if (left->is_extension()) {
2122 return false;
2123 } else if (right->is_extension()) {
2124 return true;
2125 } else {
2126 return left->index() < right->index();
2127 }
2128 }
2129};
2130
2131} // namespace
2132
2133bool TextFormat::Printer::PrintAny(const Message& message,
2134 TextGenerator* generator) const {
2135 const FieldDescriptor* type_url_field;
2136 const FieldDescriptor* value_field;
2137 if (!internal::GetAnyFieldDescriptors(message, &type_url_field,
2138 &value_field)) {
2139 return false;
2140 }
2141
2142 const Reflection* reflection = message.GetReflection();
2143
2144 // Extract the full type name from the type_url field.
2145 const std::string& type_url = reflection->GetString(message, type_url_field);
2146 std::string url_prefix;
2147 std::string full_type_name;
2148 if (!internal::ParseAnyTypeUrl(type_url, &url_prefix, &full_type_name)) {
2149 return false;
2150 }
2151
2152 // Print the "value" in text.
2153 const Descriptor* value_descriptor =
2154 finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name)
2155 : DefaultFinderFindAnyType(message, url_prefix, full_type_name);
2156 if (value_descriptor == nullptr) {
2157 GOOGLE_LOG(WARNING) << "Can't print proto content: proto type " << type_url
2158 << " not found";
2159 return false;
2160 }
2161 DynamicMessageFactory factory;
2162 std::unique_ptr<Message> value_message(
2163 factory.GetPrototype(value_descriptor)->New());
2164 std::string serialized_value = reflection->GetString(message, value_field);
2165 if (!value_message->ParseFromString(serialized_value)) {
2166 GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents";
2167 return false;
2168 }
2169 generator->PrintLiteral("[");
2170 generator->PrintString(type_url);
2171 generator->PrintLiteral("]");
2172 const FastFieldValuePrinter* printer = GetFieldPrinter(value_field);
2173 printer->PrintMessageStart(message, -1, 0, single_line_mode_, generator);
2174 generator->Indent();
2175 Print(*value_message, generator);
2176 generator->Outdent();
2177 printer->PrintMessageEnd(message, -1, 0, single_line_mode_, generator);
2178 return true;
2179}
2180
2181void TextFormat::Printer::Print(const Message& message,
2182 TextGenerator* generator) const {
2183 const Reflection* reflection = message.GetReflection();
2184 if (!reflection) {
2185 // This message does not provide any way to describe its structure.
2186 // Parse it again in an UnknownFieldSet, and display this instead.
2187 UnknownFieldSet unknown_fields;
2188 {
2189 std::string serialized = message.SerializeAsString();
2190 io::ArrayInputStream input(serialized.data(), serialized.size());
2191 unknown_fields.ParseFromZeroCopyStream(&input);
2192 }
2193 PrintUnknownFields(unknown_fields, generator, kUnknownFieldRecursionLimit);
2194 return;
2195 }
2196 const Descriptor* descriptor = message.GetDescriptor();
2197 auto itr = custom_message_printers_.find(descriptor);
2198 if (itr != custom_message_printers_.end()) {
2199 itr->second->Print(message, single_line_mode_, generator);
2200 return;
2201 }
2202 if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ &&
2203 PrintAny(message, generator)) {
2204 return;
2205 }
2206 std::vector<const FieldDescriptor*> fields;
2207 if (descriptor->options().map_entry()) {
2208 fields.push_back(descriptor->field(0));
2209 fields.push_back(descriptor->field(1));
2210 } else {
2211 reflection->ListFieldsOmitStripped(message, &fields);
2212 if (reflection->IsMessageStripped(message.GetDescriptor())) {
2213 generator->Print(kDoNotParse, std::strlen(kDoNotParse));
2214 }
2215 }
2216
2217 if (print_message_fields_in_index_order_) {
2218 std::sort(fields.begin(), fields.end(), FieldIndexSorter());
2219 }
2220 for (const FieldDescriptor* field : fields) {
2221 PrintField(message, reflection, field, generator);
2222 }
2223 if (!hide_unknown_fields_) {
2224 PrintUnknownFields(reflection->GetUnknownFields(message), generator,
2225 kUnknownFieldRecursionLimit);
2226 }
2227}
2228
2229void TextFormat::Printer::PrintFieldValueToString(const Message& message,
2230 const FieldDescriptor* field,
2231 int index,
2232 std::string* output) const {
2233 GOOGLE_DCHECK(output) << "output specified is nullptr";
2234
2235 output->clear();
2236 io::StringOutputStream output_stream(output);
2237 TextGenerator generator(&output_stream, initial_indent_level_);
2238
2239 PrintFieldValue(message, message.GetReflection(), field, index, &generator);
2240}
2241
2242class MapEntryMessageComparator {
2243 public:
2244 explicit MapEntryMessageComparator(const Descriptor* descriptor)
2245 : field_(descriptor->field(0)) {}
2246
2247 bool operator()(const Message* a, const Message* b) {
2248 const Reflection* reflection = a->GetReflection();
2249 switch (field_->cpp_type()) {
2250 case FieldDescriptor::CPPTYPE_BOOL: {
2251 bool first = reflection->GetBool(*a, field_);
2252 bool second = reflection->GetBool(*b, field_);
2253 return first < second;
2254 }
2255 case FieldDescriptor::CPPTYPE_INT32: {
2256 int32_t first = reflection->GetInt32(*a, field_);
2257 int32_t second = reflection->GetInt32(*b, field_);
2258 return first < second;
2259 }
2260 case FieldDescriptor::CPPTYPE_INT64: {
2261 int64_t first = reflection->GetInt64(*a, field_);
2262 int64_t second = reflection->GetInt64(*b, field_);
2263 return first < second;
2264 }
2265 case FieldDescriptor::CPPTYPE_UINT32: {
2266 uint32_t first = reflection->GetUInt32(*a, field_);
2267 uint32_t second = reflection->GetUInt32(*b, field_);
2268 return first < second;
2269 }
2270 case FieldDescriptor::CPPTYPE_UINT64: {
2271 uint64_t first = reflection->GetUInt64(*a, field_);
2272 uint64_t second = reflection->GetUInt64(*b, field_);
2273 return first < second;
2274 }
2275 case FieldDescriptor::CPPTYPE_STRING: {
2276 std::string first = reflection->GetString(*a, field_);
2277 std::string second = reflection->GetString(*b, field_);
2278 return first < second;
2279 }
2280 default:
2281 GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
2282 return true;
2283 }
2284 }
2285
2286 private:
2287 const FieldDescriptor* field_;
2288};
2289
2290namespace internal {
2291class MapFieldPrinterHelper {
2292 public:
2293 // DynamicMapSorter::Sort cannot be used because it enforces syncing with
2294 // repeated field.
2295 static bool SortMap(const Message& message, const Reflection* reflection,
2296 const FieldDescriptor* field,
2297 std::vector<const Message*>* sorted_map_field);
2298 static void CopyKey(const MapKey& key, Message* message,
2299 const FieldDescriptor* field_desc);
2300 static void CopyValue(const MapValueRef& value, Message* message,
2301 const FieldDescriptor* field_desc);
2302};
2303
2304// Returns true if elements contained in sorted_map_field need to be released.
2305bool MapFieldPrinterHelper::SortMap(
2306 const Message& message, const Reflection* reflection,
2307 const FieldDescriptor* field,
2308 std::vector<const Message*>* sorted_map_field) {
2309 bool need_release = false;
2310 const MapFieldBase& base = *reflection->GetMapData(message, field);
2311
2312 if (base.IsRepeatedFieldValid()) {
2313 const RepeatedPtrField<Message>& map_field =
2314 reflection->GetRepeatedPtrFieldInternal<Message>(message, field);
2315 for (int i = 0; i < map_field.size(); ++i) {
2316 sorted_map_field->push_back(
2317 const_cast<RepeatedPtrField<Message>*>(&map_field)->Mutable(i));
2318 }
2319 } else {
2320 // TODO(teboring): For performance, instead of creating map entry message
2321 // for each element, just store map keys and sort them.
2322 const Descriptor* map_entry_desc = field->message_type();
2323 const Message* prototype =
2324 reflection->GetMessageFactory()->GetPrototype(map_entry_desc);
2325 for (MapIterator iter =
2326 reflection->MapBegin(const_cast<Message*>(&message), field);
2327 iter != reflection->MapEnd(const_cast<Message*>(&message), field);
2328 ++iter) {
2329 Message* map_entry_message = prototype->New();
2330 CopyKey(iter.GetKey(), map_entry_message, map_entry_desc->field(0));
2331 CopyValue(iter.GetValueRef(), map_entry_message,
2332 map_entry_desc->field(1));
2333 sorted_map_field->push_back(map_entry_message);
2334 }
2335 need_release = true;
2336 }
2337
2338 MapEntryMessageComparator comparator(field->message_type());
2339 std::stable_sort(sorted_map_field->begin(), sorted_map_field->end(),
2340 comparator);
2341 return need_release;
2342}
2343
2344void MapFieldPrinterHelper::CopyKey(const MapKey& key, Message* message,
2345 const FieldDescriptor* field_desc) {
2346 const Reflection* reflection = message->GetReflection();
2347 switch (field_desc->cpp_type()) {
2348 case FieldDescriptor::CPPTYPE_DOUBLE:
2349 case FieldDescriptor::CPPTYPE_FLOAT:
2350 case FieldDescriptor::CPPTYPE_ENUM:
2351 case FieldDescriptor::CPPTYPE_MESSAGE:
2352 GOOGLE_LOG(ERROR) << "Not supported.";
2353 break;
2354 case FieldDescriptor::CPPTYPE_STRING:
2355 reflection->SetString(message, field_desc, key.GetStringValue());
2356 return;
2357 case FieldDescriptor::CPPTYPE_INT64:
2358 reflection->SetInt64(message, field_desc, key.GetInt64Value());
2359 return;
2360 case FieldDescriptor::CPPTYPE_INT32:
2361 reflection->SetInt32(message, field_desc, key.GetInt32Value());
2362 return;
2363 case FieldDescriptor::CPPTYPE_UINT64:
2364 reflection->SetUInt64(message, field_desc, key.GetUInt64Value());
2365 return;
2366 case FieldDescriptor::CPPTYPE_UINT32:
2367 reflection->SetUInt32(message, field_desc, key.GetUInt32Value());
2368 return;
2369 case FieldDescriptor::CPPTYPE_BOOL:
2370 reflection->SetBool(message, field_desc, key.GetBoolValue());
2371 return;
2372 }
2373}
2374
2375void MapFieldPrinterHelper::CopyValue(const MapValueRef& value,
2376 Message* message,
2377 const FieldDescriptor* field_desc) {
2378 const Reflection* reflection = message->GetReflection();
2379 switch (field_desc->cpp_type()) {
2380 case FieldDescriptor::CPPTYPE_DOUBLE:
2381 reflection->SetDouble(message, field_desc, value.GetDoubleValue());
2382 return;
2383 case FieldDescriptor::CPPTYPE_FLOAT:
2384 reflection->SetFloat(message, field_desc, value.GetFloatValue());
2385 return;
2386 case FieldDescriptor::CPPTYPE_ENUM:
2387 reflection->SetEnumValue(message, field_desc, value.GetEnumValue());
2388 return;
2389 case FieldDescriptor::CPPTYPE_MESSAGE: {
2390 Message* sub_message = value.GetMessageValue().New();
2391 sub_message->CopyFrom(value.GetMessageValue());
2392 reflection->SetAllocatedMessage(message, sub_message, field_desc);
2393 return;
2394 }
2395 case FieldDescriptor::CPPTYPE_STRING:
2396 reflection->SetString(message, field_desc, value.GetStringValue());
2397 return;
2398 case FieldDescriptor::CPPTYPE_INT64:
2399 reflection->SetInt64(message, field_desc, value.GetInt64Value());
2400 return;
2401 case FieldDescriptor::CPPTYPE_INT32:
2402 reflection->SetInt32(message, field_desc, value.GetInt32Value());
2403 return;
2404 case FieldDescriptor::CPPTYPE_UINT64:
2405 reflection->SetUInt64(message, field_desc, value.GetUInt64Value());
2406 return;
2407 case FieldDescriptor::CPPTYPE_UINT32:
2408 reflection->SetUInt32(message, field_desc, value.GetUInt32Value());
2409 return;
2410 case FieldDescriptor::CPPTYPE_BOOL:
2411 reflection->SetBool(message, field_desc, value.GetBoolValue());
2412 return;
2413 }
2414}
2415} // namespace internal
2416
2417void TextFormat::Printer::PrintField(const Message& message,
2418 const Reflection* reflection,
2419 const FieldDescriptor* field,
2420 TextGenerator* generator) const {
2421 if (use_short_repeated_primitives_ && field->is_repeated() &&
2422 field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
2423 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
2424 PrintShortRepeatedField(message, reflection, field, generator);
2425 return;
2426 }
2427
2428 int count = 0;
2429
2430 if (field->is_repeated()) {
2431 count = reflection->FieldSize(message, field);
2432 } else if (reflection->HasField(message, field) ||
2433 field->containing_type()->options().map_entry()) {
2434 count = 1;
2435 }
2436
2437 std::vector<const Message*> sorted_map_field;
2438 bool need_release = false;
2439 bool is_map = field->is_map();
2440 if (is_map) {
2441 need_release = internal::MapFieldPrinterHelper::SortMap(
2442 message, reflection, field, &sorted_map_field);
2443 }
2444
2445 for (int j = 0; j < count; ++j) {
2446 const int field_index = field->is_repeated() ? j : -1;
2447
2448 PrintFieldName(message, field_index, count, reflection, field, generator);
2449
2450 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2451 const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2452 const Message& sub_message =
2453 field->is_repeated()
2454 ? (is_map ? *sorted_map_field[j]
2455 : reflection->GetRepeatedMessage(message, field, j))
2456 : reflection->GetMessage(message, field);
2457 printer->PrintMessageStart(sub_message, field_index, count,
2458 single_line_mode_, generator);
2459 generator->Indent();
2460 if (!printer->PrintMessageContent(sub_message, field_index, count,
2461 single_line_mode_, generator)) {
2462 Print(sub_message, generator);
2463 }
2464 generator->Outdent();
2465 printer->PrintMessageEnd(sub_message, field_index, count,
2466 single_line_mode_, generator);
2467 } else {
2468 generator->PrintMaybeWithMarker(": ");
2469 // Write the field value.
2470 PrintFieldValue(message, reflection, field, field_index, generator);
2471 if (single_line_mode_) {
2472 generator->PrintLiteral(" ");
2473 } else {
2474 generator->PrintLiteral("\n");
2475 }
2476 }
2477 }
2478
2479 if (need_release) {
2480 for (const Message* message_to_delete : sorted_map_field) {
2481 delete message_to_delete;
2482 }
2483 }
2484}
2485
2486void TextFormat::Printer::PrintShortRepeatedField(
2487 const Message& message, const Reflection* reflection,
2488 const FieldDescriptor* field, TextGenerator* generator) const {
2489 // Print primitive repeated field in short form.
2490 int size = reflection->FieldSize(message, field);
2491 PrintFieldName(message, /*field_index=*/-1, /*field_count=*/size, reflection,
2492 field, generator);
2493 generator->PrintMaybeWithMarker(": ", "[");
2494 for (int i = 0; i < size; i++) {
2495 if (i > 0) generator->PrintLiteral(", ");
2496 PrintFieldValue(message, reflection, field, i, generator);
2497 }
2498 if (single_line_mode_) {
2499 generator->PrintLiteral("] ");
2500 } else {
2501 generator->PrintLiteral("]\n");
2502 }
2503}
2504
2505void TextFormat::Printer::PrintFieldName(const Message& message,
2506 int field_index, int field_count,
2507 const Reflection* reflection,
2508 const FieldDescriptor* field,
2509 TextGenerator* generator) const {
2510 // if use_field_number_ is true, prints field number instead
2511 // of field name.
2512 if (use_field_number_) {
2513 generator->PrintString(StrCat(field->number()));
2514 return;
2515 }
2516
2517 const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2518 printer->PrintFieldName(message, field_index, field_count, reflection, field,
2519 generator);
2520}
2521
2522void TextFormat::Printer::PrintFieldValue(const Message& message,
2523 const Reflection* reflection,
2524 const FieldDescriptor* field,
2525 int index,
2526 TextGenerator* generator) const {
2527 GOOGLE_DCHECK(field->is_repeated() || (index == -1))
2528 << "Index must be -1 for non-repeated fields";
2529
2530 const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2531
2532 switch (field->cpp_type()) {
2533#define OUTPUT_FIELD(CPPTYPE, METHOD) \
2534 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
2535 printer->Print##METHOD( \
2536 field->is_repeated() \
2537 ? reflection->GetRepeated##METHOD(message, field, index) \
2538 : reflection->Get##METHOD(message, field), \
2539 generator); \
2540 break
2541
2542 OUTPUT_FIELD(INT32, Int32);
2543 OUTPUT_FIELD(INT64, Int64);
2544 OUTPUT_FIELD(UINT32, UInt32);
2545 OUTPUT_FIELD(UINT64, UInt64);
2546 OUTPUT_FIELD(FLOAT, Float);
2547 OUTPUT_FIELD(DOUBLE, Double);
2548 OUTPUT_FIELD(BOOL, Bool);
2549#undef OUTPUT_FIELD
2550
2551 case FieldDescriptor::CPPTYPE_STRING: {
2552 std::string scratch;
2553 const std::string& value =
2554 field->is_repeated()
2555 ? reflection->GetRepeatedStringReference(message, field, index,
2556 &scratch)
2557 : reflection->GetStringReference(message, field, &scratch);
2558 const std::string* value_to_print = &value;
2559 std::string truncated_value;
2560 if (truncate_string_field_longer_than_ > 0 &&
2561 static_cast<size_t>(truncate_string_field_longer_than_) <
2562 value.size()) {
2563 truncated_value = value.substr(0, truncate_string_field_longer_than_) +
2564 "...<truncated>...";
2565 value_to_print = &truncated_value;
2566 }
2567 if (field->type() == FieldDescriptor::TYPE_STRING) {
2568 printer->PrintString(*value_to_print, generator);
2569 } else {
2570 GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
2571 printer->PrintBytes(*value_to_print, generator);
2572 }
2573 break;
2574 }
2575
2576 case FieldDescriptor::CPPTYPE_ENUM: {
2577 int enum_value =
2578 field->is_repeated()
2579 ? reflection->GetRepeatedEnumValue(message, field, index)
2580 : reflection->GetEnumValue(message, field);
2581 const EnumValueDescriptor* enum_desc =
2582 field->enum_type()->FindValueByNumber(enum_value);
2583 if (enum_desc != nullptr) {
2584 printer->PrintEnum(enum_value, enum_desc->name(), generator);
2585 } else {
2586 // Ordinarily, enum_desc should not be null, because proto2 has the
2587 // invariant that set enum field values must be in-range, but with the
2588 // new integer-based API for enums (or the RepeatedField<int> loophole),
2589 // it is possible for the user to force an unknown integer value. So we
2590 // simply use the integer value itself as the enum value name in this
2591 // case.
2592 printer->PrintEnum(enum_value, StrCat(enum_value), generator);
2593 }
2594 break;
2595 }
2596
2597 case FieldDescriptor::CPPTYPE_MESSAGE:
2598 Print(field->is_repeated()
2599 ? reflection->GetRepeatedMessage(message, field, index)
2600 : reflection->GetMessage(message, field),
2601 generator);
2602 break;
2603 }
2604}
2605
2606/* static */ bool TextFormat::Print(const Message& message,
2607 io::ZeroCopyOutputStream* output) {
2608 return Printer().Print(message, output);
2609}
2610
2611/* static */ bool TextFormat::PrintUnknownFields(
2612 const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) {
2613 return Printer().PrintUnknownFields(unknown_fields, output);
2614}
2615
2616/* static */ bool TextFormat::PrintToString(const Message& message,
2617 std::string* output) {
2618 return Printer().PrintToString(message, output);
2619}
2620
2621/* static */ bool TextFormat::PrintUnknownFieldsToString(
2622 const UnknownFieldSet& unknown_fields, std::string* output) {
2623 return Printer().PrintUnknownFieldsToString(unknown_fields, output);
2624}
2625
2626/* static */ void TextFormat::PrintFieldValueToString(
2627 const Message& message, const FieldDescriptor* field, int index,
2628 std::string* output) {
2629 return Printer().PrintFieldValueToString(message, field, index, output);
2630}
2631
2632/* static */ bool TextFormat::ParseFieldValueFromString(
2633 const std::string& input, const FieldDescriptor* field, Message* message) {
2634 return Parser().ParseFieldValueFromString(input, field, message);
2635}
2636
2637void TextFormat::Printer::PrintUnknownFields(
2638 const UnknownFieldSet& unknown_fields, TextGenerator* generator,
2639 int recursion_budget) const {
2640 for (int i = 0; i < unknown_fields.field_count(); i++) {
2641 const UnknownField& field = unknown_fields.field(i);
2642 std::string field_number = StrCat(field.number());
2643
2644 switch (field.type()) {
2645 case UnknownField::TYPE_VARINT:
2646 generator->PrintString(field_number);
2647 generator->PrintMaybeWithMarker(": ");
2648 generator->PrintString(StrCat(field.varint()));
2649 if (single_line_mode_) {
2650 generator->PrintLiteral(" ");
2651 } else {
2652 generator->PrintLiteral("\n");
2653 }
2654 break;
2655 case UnknownField::TYPE_FIXED32: {
2656 generator->PrintString(field_number);
2657 generator->PrintMaybeWithMarker(": ", "0x");
2658 generator->PrintString(
2659 StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8)));
2660 if (single_line_mode_) {
2661 generator->PrintLiteral(" ");
2662 } else {
2663 generator->PrintLiteral("\n");
2664 }
2665 break;
2666 }
2667 case UnknownField::TYPE_FIXED64: {
2668 generator->PrintString(field_number);
2669 generator->PrintMaybeWithMarker(": ", "0x");
2670 generator->PrintString(
2671 StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16)));
2672 if (single_line_mode_) {
2673 generator->PrintLiteral(" ");
2674 } else {
2675 generator->PrintLiteral("\n");
2676 }
2677 break;
2678 }
2679 case UnknownField::TYPE_LENGTH_DELIMITED: {
2680 generator->PrintString(field_number);
2681 const std::string& value = field.length_delimited();
2682 // We create a CodedInputStream so that we can adhere to our recursion
2683 // budget when we attempt to parse the data. UnknownFieldSet parsing is
2684 // recursive because of groups.
2685 io::CodedInputStream input_stream(
2686 reinterpret_cast<const uint8_t*>(value.data()), value.size());
2687 input_stream.SetRecursionLimit(recursion_budget);
2688 UnknownFieldSet embedded_unknown_fields;
2689 if (!value.empty() && recursion_budget > 0 &&
2690 embedded_unknown_fields.ParseFromCodedStream(&input_stream)) {
2691 // This field is parseable as a Message.
2692 // So it is probably an embedded message.
2693 if (single_line_mode_) {
2694 generator->PrintMaybeWithMarker(" ", "{ ");
2695 } else {
2696 generator->PrintMaybeWithMarker(" ", "{\n");
2697 generator->Indent();
2698 }
2699 PrintUnknownFields(embedded_unknown_fields, generator,
2700 recursion_budget - 1);
2701 if (single_line_mode_) {
2702 generator->PrintLiteral("} ");
2703 } else {
2704 generator->Outdent();
2705 generator->PrintLiteral("}\n");
2706 }
2707 } else {
2708 // This field is not parseable as a Message (or we ran out of
2709 // recursion budget). So it is probably just a plain string.
2710 generator->PrintMaybeWithMarker(": ", "\"");
2711 generator->PrintString(CEscape(value));
2712 if (single_line_mode_) {
2713 generator->PrintLiteral("\" ");
2714 } else {
2715 generator->PrintLiteral("\"\n");
2716 }
2717 }
2718 break;
2719 }
2720 case UnknownField::TYPE_GROUP:
2721 generator->PrintString(field_number);
2722 if (single_line_mode_) {
2723 generator->PrintMaybeWithMarker(" ", "{ ");
2724 } else {
2725 generator->PrintMaybeWithMarker(" ", "{\n");
2726 generator->Indent();
2727 }
2728 // For groups, we recurse without checking the budget. This is OK,
2729 // because if the groups were too deeply nested then we would have
2730 // already rejected the message when we originally parsed it.
2731 PrintUnknownFields(field.group(), generator, recursion_budget - 1);
2732 if (single_line_mode_) {
2733 generator->PrintLiteral("} ");
2734 } else {
2735 generator->Outdent();
2736 generator->PrintLiteral("}\n");
2737 }
2738 break;
2739 }
2740 }
2741}
2742
2743} // namespace protobuf
2744} // namespace google
2745
2746#include <google/protobuf/port_undef.inc>