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