1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: jschorr@google.com (Joseph Schorr)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <float.h>
36 #include <math.h>
37 #include <stdio.h>
38 #include <stack>
39 #include <limits>
40 #include <vector>
41
42 #include <google/protobuf/text_format.h>
43
44 #include <google/protobuf/descriptor.h>
45 #include <google/protobuf/io/coded_stream.h>
46 #include <google/protobuf/io/zero_copy_stream.h>
47 #include <google/protobuf/io/zero_copy_stream_impl.h>
48 #include <google/protobuf/unknown_field_set.h>
49 #include <google/protobuf/descriptor.pb.h>
50 #include <google/protobuf/io/tokenizer.h>
51 #include <google/protobuf/stubs/strutil.h>
52 #include <google/protobuf/stubs/map-util.h>
53 #include <google/protobuf/stubs/stl_util.h>
54
55 namespace google {
56 namespace protobuf {
57
DebugString() const58 string Message::DebugString() const {
59 string debug_string;
60
61 TextFormat::PrintToString(*this, &debug_string);
62
63 return debug_string;
64 }
65
ShortDebugString() const66 string Message::ShortDebugString() const {
67 string debug_string;
68
69 TextFormat::Printer printer;
70 printer.SetSingleLineMode(true);
71
72 printer.PrintToString(*this, &debug_string);
73 // Single line mode currently might have an extra space at the end.
74 if (debug_string.size() > 0 &&
75 debug_string[debug_string.size() - 1] == ' ') {
76 debug_string.resize(debug_string.size() - 1);
77 }
78
79 return debug_string;
80 }
81
Utf8DebugString() const82 string Message::Utf8DebugString() const {
83 string debug_string;
84
85 TextFormat::Printer printer;
86 printer.SetUseUtf8StringEscaping(true);
87
88 printer.PrintToString(*this, &debug_string);
89
90 return debug_string;
91 }
92
PrintDebugString() const93 void Message::PrintDebugString() const {
94 printf("%s", DebugString().c_str());
95 }
96
97
98 // ===========================================================================
99 // Implementation of the parse information tree class.
ParseInfoTree()100 TextFormat::ParseInfoTree::ParseInfoTree() { }
101
~ParseInfoTree()102 TextFormat::ParseInfoTree::~ParseInfoTree() {
103 // Remove any nested information trees, as they are owned by this tree.
104 for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) {
105 STLDeleteElements(&(it->second));
106 }
107 }
108
RecordLocation(const FieldDescriptor * field,TextFormat::ParseLocation location)109 void TextFormat::ParseInfoTree::RecordLocation(
110 const FieldDescriptor* field,
111 TextFormat::ParseLocation location) {
112 locations_[field].push_back(location);
113 }
114
CreateNested(const FieldDescriptor * field)115 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
116 const FieldDescriptor* field) {
117 // Owned by us in the map.
118 TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
119 vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
120 GOOGLE_CHECK(trees);
121 trees->push_back(instance);
122 return instance;
123 }
124
CheckFieldIndex(const FieldDescriptor * field,int index)125 void CheckFieldIndex(const FieldDescriptor* field, int index) {
126 if (field == NULL) { return; }
127
128 if (field->is_repeated() && index == -1) {
129 GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
130 << "Field: " << field->name();
131 } else if (!field->is_repeated() && index != -1) {
132 GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
133 << "Field: " << field->name();
134 }
135 }
136
GetLocation(const FieldDescriptor * field,int index) const137 TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
138 const FieldDescriptor* field, int index) const {
139 CheckFieldIndex(field, index);
140 if (index == -1) { index = 0; }
141
142 const vector<TextFormat::ParseLocation>* locations =
143 FindOrNull(locations_, field);
144 if (locations == NULL || index >= locations->size()) {
145 return TextFormat::ParseLocation();
146 }
147
148 return (*locations)[index];
149 }
150
GetTreeForNested(const FieldDescriptor * field,int index) const151 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
152 const FieldDescriptor* field, int index) const {
153 CheckFieldIndex(field, index);
154 if (index == -1) { index = 0; }
155
156 const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field);
157 if (trees == NULL || index >= trees->size()) {
158 return NULL;
159 }
160
161 return (*trees)[index];
162 }
163
164
165 // ===========================================================================
166 // Internal class for parsing an ASCII representation of a Protocol Message.
167 // This class makes use of the Protocol Message compiler's tokenizer found
168 // in //google/protobuf/io/tokenizer.h. Note that class's Parse
169 // method is *not* thread-safe and should only be used in a single thread at
170 // a time.
171
172 // Makes code slightly more readable. The meaning of "DO(foo)" is
173 // "Execute foo and fail if it fails.", where failure is indicated by
174 // returning false. Borrowed from parser.cc (Thanks Kenton!).
175 #define DO(STATEMENT) if (STATEMENT) {} else return false
176
177 class TextFormat::Parser::ParserImpl {
178 public:
179
180 // Determines if repeated values for a non-repeated field are
181 // permitted, e.g., the string "foo: 1 foo: 2" for a
182 // required/optional field named "foo".
183 enum SingularOverwritePolicy {
184 ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
185 FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
186 };
187
ParserImpl(const Descriptor * root_message_type,io::ZeroCopyInputStream * input_stream,io::ErrorCollector * error_collector,TextFormat::Finder * finder,ParseInfoTree * parse_info_tree,SingularOverwritePolicy singular_overwrite_policy,bool allow_unknown_field)188 ParserImpl(const Descriptor* root_message_type,
189 io::ZeroCopyInputStream* input_stream,
190 io::ErrorCollector* error_collector,
191 TextFormat::Finder* finder,
192 ParseInfoTree* parse_info_tree,
193 SingularOverwritePolicy singular_overwrite_policy,
194 bool allow_unknown_field)
195 : error_collector_(error_collector),
196 finder_(finder),
197 parse_info_tree_(parse_info_tree),
198 tokenizer_error_collector_(this),
199 tokenizer_(input_stream, &tokenizer_error_collector_),
200 root_message_type_(root_message_type),
201 singular_overwrite_policy_(singular_overwrite_policy),
202 allow_unknown_field_(allow_unknown_field),
203 had_errors_(false) {
204 // For backwards-compatibility with proto1, we need to allow the 'f' suffix
205 // for floats.
206 tokenizer_.set_allow_f_after_float(true);
207
208 // '#' starts a comment.
209 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
210
211 // Consume the starting token.
212 tokenizer_.Next();
213 }
~ParserImpl()214 ~ParserImpl() { }
215
216 // Parses the ASCII representation specified in input and saves the
217 // information into the output pointer (a Message). Returns
218 // false if an error occurs (an error will also be logged to
219 // GOOGLE_LOG(ERROR)).
Parse(Message * output)220 bool Parse(Message* output) {
221 // Consume fields until we cannot do so anymore.
222 while(true) {
223 if (LookingAtType(io::Tokenizer::TYPE_END)) {
224 return !had_errors_;
225 }
226
227 DO(ConsumeField(output));
228 }
229 }
230
ParseField(const FieldDescriptor * field,Message * output)231 bool ParseField(const FieldDescriptor* field, Message* output) {
232 bool suc;
233 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
234 suc = ConsumeFieldMessage(output, output->GetReflection(), field);
235 } else {
236 suc = ConsumeFieldValue(output, output->GetReflection(), field);
237 }
238 return suc && LookingAtType(io::Tokenizer::TYPE_END);
239 }
240
ReportError(int line,int col,const string & message)241 void ReportError(int line, int col, const string& message) {
242 had_errors_ = true;
243 if (error_collector_ == NULL) {
244 if (line >= 0) {
245 GOOGLE_LOG(ERROR) << "Error parsing text-format "
246 << root_message_type_->full_name()
247 << ": " << (line + 1) << ":"
248 << (col + 1) << ": " << message;
249 } else {
250 GOOGLE_LOG(ERROR) << "Error parsing text-format "
251 << root_message_type_->full_name()
252 << ": " << message;
253 }
254 } else {
255 error_collector_->AddError(line, col, message);
256 }
257 }
258
ReportWarning(int line,int col,const string & message)259 void ReportWarning(int line, int col, const string& message) {
260 if (error_collector_ == NULL) {
261 if (line >= 0) {
262 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
263 << root_message_type_->full_name()
264 << ": " << (line + 1) << ":"
265 << (col + 1) << ": " << message;
266 } else {
267 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
268 << root_message_type_->full_name()
269 << ": " << message;
270 }
271 } else {
272 error_collector_->AddWarning(line, col, message);
273 }
274 }
275
276 private:
277 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
278
279 // Reports an error with the given message with information indicating
280 // the position (as derived from the current token).
ReportError(const string & message)281 void ReportError(const string& message) {
282 ReportError(tokenizer_.current().line, tokenizer_.current().column,
283 message);
284 }
285
286 // Reports a warning with the given message with information indicating
287 // the position (as derived from the current token).
ReportWarning(const string & message)288 void ReportWarning(const string& message) {
289 ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
290 message);
291 }
292
293 // Consumes the specified message with the given starting delimeter.
294 // This method checks to see that the end delimeter at the conclusion of
295 // the consumption matches the starting delimeter passed in here.
ConsumeMessage(Message * message,const string delimeter)296 bool ConsumeMessage(Message* message, const string delimeter) {
297 while (!LookingAt(">") && !LookingAt("}")) {
298 DO(ConsumeField(message));
299 }
300
301 // Confirm that we have a valid ending delimeter.
302 DO(Consume(delimeter));
303
304 return true;
305 }
306
307 // Consumes the current field (as returned by the tokenizer) on the
308 // passed in message.
ConsumeField(Message * message)309 bool ConsumeField(Message* message) {
310 const Reflection* reflection = message->GetReflection();
311 const Descriptor* descriptor = message->GetDescriptor();
312
313 string field_name;
314
315 const FieldDescriptor* field = NULL;
316 int start_line = tokenizer_.current().line;
317 int start_column = tokenizer_.current().column;
318
319 if (TryConsume("[")) {
320 // Extension.
321 DO(ConsumeIdentifier(&field_name));
322 while (TryConsume(".")) {
323 string part;
324 DO(ConsumeIdentifier(&part));
325 field_name += ".";
326 field_name += part;
327 }
328 DO(Consume("]"));
329
330 field = (finder_ != NULL
331 ? finder_->FindExtension(message, field_name)
332 : reflection->FindKnownExtensionByName(field_name));
333
334 if (field == NULL) {
335 if (!allow_unknown_field_) {
336 ReportError("Extension \"" + field_name + "\" is not defined or "
337 "is not an extension of \"" +
338 descriptor->full_name() + "\".");
339 return false;
340 } else {
341 ReportWarning("Extension \"" + field_name + "\" is not defined or "
342 "is not an extension of \"" +
343 descriptor->full_name() + "\".");
344 }
345 }
346 } else {
347 DO(ConsumeIdentifier(&field_name));
348
349 field = descriptor->FindFieldByName(field_name);
350 // Group names are expected to be capitalized as they appear in the
351 // .proto file, which actually matches their type names, not their field
352 // names.
353 if (field == NULL) {
354 string lower_field_name = field_name;
355 LowerString(&lower_field_name);
356 field = descriptor->FindFieldByName(lower_field_name);
357 // If the case-insensitive match worked but the field is NOT a group,
358 if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
359 field = NULL;
360 }
361 }
362 // Again, special-case group names as described above.
363 if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
364 && field->message_type()->name() != field_name) {
365 field = NULL;
366 }
367
368 if (field == NULL) {
369 if (!allow_unknown_field_) {
370 ReportError("Message type \"" + descriptor->full_name() +
371 "\" has no field named \"" + field_name + "\".");
372 return false;
373 } else {
374 ReportWarning("Message type \"" + descriptor->full_name() +
375 "\" has no field named \"" + field_name + "\".");
376 }
377 }
378 }
379
380 // Skips unknown field.
381 if (field == NULL) {
382 GOOGLE_CHECK(allow_unknown_field_);
383 // Try to guess the type of this field.
384 // If this field is not a message, there should be a ":" between the
385 // field name and the field value and also the field value should not
386 // start with "{" or "<" which indicates the begining of a message body.
387 // If there is no ":" or there is a "{" or "<" after ":", this field has
388 // to be a message or the input is ill-formed.
389 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
390 return SkipFieldValue();
391 } else {
392 return SkipFieldMessage();
393 }
394 }
395
396 // Fail if the field is not repeated and it has already been specified.
397 if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) &&
398 !field->is_repeated() && reflection->HasField(*message, field)) {
399 ReportError("Non-repeated field \"" + field_name +
400 "\" is specified multiple times.");
401 return false;
402 }
403
404 // Perform special handling for embedded message types.
405 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
406 // ':' is optional here.
407 TryConsume(":");
408 DO(ConsumeFieldMessage(message, reflection, field));
409 } else {
410 DO(Consume(":"));
411 if (field->is_repeated() && TryConsume("[")) {
412 // Short repeated format, e.g. "foo: [1, 2, 3]"
413 while (true) {
414 DO(ConsumeFieldValue(message, reflection, field));
415 if (TryConsume("]")) {
416 break;
417 }
418 DO(Consume(","));
419 }
420 } else {
421 DO(ConsumeFieldValue(message, reflection, field));
422 }
423 }
424
425 // For historical reasons, fields may optionally be separated by commas or
426 // semicolons.
427 TryConsume(";") || TryConsume(",");
428
429 if (field->options().deprecated()) {
430 ReportWarning("text format contains deprecated field \""
431 + field_name + "\"");
432 }
433
434 // If a parse info tree exists, add the location for the parsed
435 // field.
436 if (parse_info_tree_ != NULL) {
437 RecordLocation(parse_info_tree_, field,
438 ParseLocation(start_line, start_column));
439 }
440
441 return true;
442 }
443
444 // Skips the next field including the field's name and value.
SkipField()445 bool SkipField() {
446 string field_name;
447 if (TryConsume("[")) {
448 // Extension name.
449 DO(ConsumeIdentifier(&field_name));
450 while (TryConsume(".")) {
451 string part;
452 DO(ConsumeIdentifier(&part));
453 field_name += ".";
454 field_name += part;
455 }
456 DO(Consume("]"));
457 } else {
458 DO(ConsumeIdentifier(&field_name));
459 }
460
461 // Try to guess the type of this field.
462 // If this field is not a message, there should be a ":" between the
463 // field name and the field value and also the field value should not
464 // start with "{" or "<" which indicates the begining of a message body.
465 // If there is no ":" or there is a "{" or "<" after ":", this field has
466 // to be a message or the input is ill-formed.
467 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
468 DO(SkipFieldValue());
469 } else {
470 DO(SkipFieldMessage());
471 }
472 // For historical reasons, fields may optionally be separated by commas or
473 // semicolons.
474 TryConsume(";") || TryConsume(",");
475 return true;
476 }
477
ConsumeFieldMessage(Message * message,const Reflection * reflection,const FieldDescriptor * field)478 bool ConsumeFieldMessage(Message* message,
479 const Reflection* reflection,
480 const FieldDescriptor* field) {
481
482 // If the parse information tree is not NULL, create a nested one
483 // for the nested message.
484 ParseInfoTree* parent = parse_info_tree_;
485 if (parent != NULL) {
486 parse_info_tree_ = CreateNested(parent, field);
487 }
488
489 string delimeter;
490 if (TryConsume("<")) {
491 delimeter = ">";
492 } else {
493 DO(Consume("{"));
494 delimeter = "}";
495 }
496
497 if (field->is_repeated()) {
498 DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
499 } else {
500 DO(ConsumeMessage(reflection->MutableMessage(message, field),
501 delimeter));
502 }
503
504 // Reset the parse information tree.
505 parse_info_tree_ = parent;
506 return true;
507 }
508
509 // Skips the whole body of a message including the begining delimeter and
510 // the ending delimeter.
SkipFieldMessage()511 bool SkipFieldMessage() {
512 string delimeter;
513 if (TryConsume("<")) {
514 delimeter = ">";
515 } else {
516 DO(Consume("{"));
517 delimeter = "}";
518 }
519 while (!LookingAt(">") && !LookingAt("}")) {
520 DO(SkipField());
521 }
522 DO(Consume(delimeter));
523 return true;
524 }
525
ConsumeFieldValue(Message * message,const Reflection * reflection,const FieldDescriptor * field)526 bool ConsumeFieldValue(Message* message,
527 const Reflection* reflection,
528 const FieldDescriptor* field) {
529
530 // Define an easy to use macro for setting fields. This macro checks
531 // to see if the field is repeated (in which case we need to use the Add
532 // methods or not (in which case we need to use the Set methods).
533 #define SET_FIELD(CPPTYPE, VALUE) \
534 if (field->is_repeated()) { \
535 reflection->Add##CPPTYPE(message, field, VALUE); \
536 } else { \
537 reflection->Set##CPPTYPE(message, field, VALUE); \
538 } \
539
540 switch(field->cpp_type()) {
541 case FieldDescriptor::CPPTYPE_INT32: {
542 int64 value;
543 DO(ConsumeSignedInteger(&value, kint32max));
544 SET_FIELD(Int32, static_cast<int32>(value));
545 break;
546 }
547
548 case FieldDescriptor::CPPTYPE_UINT32: {
549 uint64 value;
550 DO(ConsumeUnsignedInteger(&value, kuint32max));
551 SET_FIELD(UInt32, static_cast<uint32>(value));
552 break;
553 }
554
555 case FieldDescriptor::CPPTYPE_INT64: {
556 int64 value;
557 DO(ConsumeSignedInteger(&value, kint64max));
558 SET_FIELD(Int64, value);
559 break;
560 }
561
562 case FieldDescriptor::CPPTYPE_UINT64: {
563 uint64 value;
564 DO(ConsumeUnsignedInteger(&value, kuint64max));
565 SET_FIELD(UInt64, value);
566 break;
567 }
568
569 case FieldDescriptor::CPPTYPE_FLOAT: {
570 double value;
571 DO(ConsumeDouble(&value));
572 SET_FIELD(Float, static_cast<float>(value));
573 break;
574 }
575
576 case FieldDescriptor::CPPTYPE_DOUBLE: {
577 double value;
578 DO(ConsumeDouble(&value));
579 SET_FIELD(Double, value);
580 break;
581 }
582
583 case FieldDescriptor::CPPTYPE_STRING: {
584 string value;
585 DO(ConsumeString(&value));
586 SET_FIELD(String, value);
587 break;
588 }
589
590 case FieldDescriptor::CPPTYPE_BOOL: {
591 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
592 uint64 value;
593 DO(ConsumeUnsignedInteger(&value, 1));
594 SET_FIELD(Bool, value);
595 } else {
596 string value;
597 DO(ConsumeIdentifier(&value));
598 if (value == "true" || value == "t") {
599 SET_FIELD(Bool, true);
600 } else if (value == "false" || value == "f") {
601 SET_FIELD(Bool, false);
602 } else {
603 ReportError("Invalid value for boolean field \"" + field->name()
604 + "\". Value: \"" + value + "\".");
605 return false;
606 }
607 }
608 break;
609 }
610
611 case FieldDescriptor::CPPTYPE_ENUM: {
612 string value;
613 const EnumDescriptor* enum_type = field->enum_type();
614 const EnumValueDescriptor* enum_value = NULL;
615
616 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
617 DO(ConsumeIdentifier(&value));
618 // Find the enumeration value.
619 enum_value = enum_type->FindValueByName(value);
620
621 } else if (LookingAt("-") ||
622 LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
623 int64 int_value;
624 DO(ConsumeSignedInteger(&int_value, kint32max));
625 value = SimpleItoa(int_value); // for error reporting
626 enum_value = enum_type->FindValueByNumber(int_value);
627 } else {
628 ReportError("Expected integer or identifier.");
629 return false;
630 }
631
632 if (enum_value == NULL) {
633 ReportError("Unknown enumeration value of \"" + value + "\" for "
634 "field \"" + field->name() + "\".");
635 return false;
636 }
637
638 SET_FIELD(Enum, enum_value);
639 break;
640 }
641
642 case FieldDescriptor::CPPTYPE_MESSAGE: {
643 // We should never get here. Put here instead of a default
644 // so that if new types are added, we get a nice compiler warning.
645 GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
646 break;
647 }
648 }
649 #undef SET_FIELD
650 return true;
651 }
652
SkipFieldValue()653 bool SkipFieldValue() {
654 if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
655 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
656 tokenizer_.Next();
657 }
658 return true;
659 }
660 // Possible field values other than string:
661 // 12345 => TYPE_INTEGER
662 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
663 // 1.2345 => TYPE_FLOAT
664 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
665 // inf => TYPE_IDENTIFIER
666 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
667 // TYPE_INTEGER => TYPE_IDENTIFIER
668 // Divides them into two group, one with TYPE_SYMBOL
669 // and the other without:
670 // Group one:
671 // 12345 => TYPE_INTEGER
672 // 1.2345 => TYPE_FLOAT
673 // inf => TYPE_IDENTIFIER
674 // TYPE_INTEGER => TYPE_IDENTIFIER
675 // Group two:
676 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
677 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
678 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
679 // As we can see, the field value consists of an optional '-' and one of
680 // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
681 bool has_minus = TryConsume("-");
682 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
683 !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
684 !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
685 return false;
686 }
687 // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
688 // value while other combinations all generate valid values.
689 // We check if the value of this combination is valid here.
690 // TYPE_IDENTIFIER after a '-' should be one of the float values listed
691 // below:
692 // inf, inff, infinity, nan
693 if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
694 string text = tokenizer_.current().text;
695 LowerString(&text);
696 if (text != "inf" &&
697 text != "infinity" &&
698 text != "nan") {
699 ReportError("Invalid float number: " + text);
700 return false;
701 }
702 }
703 tokenizer_.Next();
704 return true;
705 }
706
707 // Returns true if the current token's text is equal to that specified.
LookingAt(const string & text)708 bool LookingAt(const string& text) {
709 return tokenizer_.current().text == text;
710 }
711
712 // Returns true if the current token's type is equal to that specified.
LookingAtType(io::Tokenizer::TokenType token_type)713 bool LookingAtType(io::Tokenizer::TokenType token_type) {
714 return tokenizer_.current().type == token_type;
715 }
716
717 // Consumes an identifier and saves its value in the identifier parameter.
718 // Returns false if the token is not of type IDENTFIER.
ConsumeIdentifier(string * identifier)719 bool ConsumeIdentifier(string* identifier) {
720 if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
721 ReportError("Expected identifier.");
722 return false;
723 }
724
725 *identifier = tokenizer_.current().text;
726
727 tokenizer_.Next();
728 return true;
729 }
730
731 // Consumes a string and saves its value in the text parameter.
732 // Returns false if the token is not of type STRING.
ConsumeString(string * text)733 bool ConsumeString(string* text) {
734 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
735 ReportError("Expected string.");
736 return false;
737 }
738
739 text->clear();
740 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
741 io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
742
743 tokenizer_.Next();
744 }
745
746 return true;
747 }
748
749 // Consumes a uint64 and saves its value in the value parameter.
750 // Returns false if the token is not of type INTEGER.
ConsumeUnsignedInteger(uint64 * value,uint64 max_value)751 bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
752 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
753 ReportError("Expected integer.");
754 return false;
755 }
756
757 if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
758 max_value, value)) {
759 ReportError("Integer out of range.");
760 return false;
761 }
762
763 tokenizer_.Next();
764 return true;
765 }
766
767 // Consumes an int64 and saves its value in the value parameter.
768 // Note that since the tokenizer does not support negative numbers,
769 // we actually may consume an additional token (for the minus sign) in this
770 // method. Returns false if the token is not an integer
771 // (signed or otherwise).
ConsumeSignedInteger(int64 * value,uint64 max_value)772 bool ConsumeSignedInteger(int64* value, uint64 max_value) {
773 bool negative = false;
774
775 if (TryConsume("-")) {
776 negative = true;
777 // Two's complement always allows one more negative integer than
778 // positive.
779 ++max_value;
780 }
781
782 uint64 unsigned_value;
783
784 DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
785
786 *value = static_cast<int64>(unsigned_value);
787
788 if (negative) {
789 *value = -*value;
790 }
791
792 return true;
793 }
794
795 // Consumes a double and saves its value in the value parameter.
796 // Note that since the tokenizer does not support negative numbers,
797 // we actually may consume an additional token (for the minus sign) in this
798 // method. Returns false if the token is not a double
799 // (signed or otherwise).
ConsumeDouble(double * value)800 bool ConsumeDouble(double* value) {
801 bool negative = false;
802
803 if (TryConsume("-")) {
804 negative = true;
805 }
806
807 // A double can actually be an integer, according to the tokenizer.
808 // Therefore, we must check both cases here.
809 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
810 // We have found an integer value for the double.
811 uint64 integer_value;
812 DO(ConsumeUnsignedInteger(&integer_value, kuint64max));
813
814 *value = static_cast<double>(integer_value);
815 } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
816 // We have found a float value for the double.
817 *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
818
819 // Mark the current token as consumed.
820 tokenizer_.Next();
821 } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
822 string text = tokenizer_.current().text;
823 LowerString(&text);
824 if (text == "inf" ||
825 text == "infinity") {
826 *value = std::numeric_limits<double>::infinity();
827 tokenizer_.Next();
828 } else if (text == "nan") {
829 *value = std::numeric_limits<double>::quiet_NaN();
830 tokenizer_.Next();
831 } else {
832 ReportError("Expected double.");
833 return false;
834 }
835 } else {
836 ReportError("Expected double.");
837 return false;
838 }
839
840 if (negative) {
841 *value = -*value;
842 }
843
844 return true;
845 }
846
847 // Consumes a token and confirms that it matches that specified in the
848 // value parameter. Returns false if the token found does not match that
849 // which was specified.
Consume(const string & value)850 bool Consume(const string& value) {
851 const string& current_value = tokenizer_.current().text;
852
853 if (current_value != value) {
854 ReportError("Expected \"" + value + "\", found \"" + current_value
855 + "\".");
856 return false;
857 }
858
859 tokenizer_.Next();
860
861 return true;
862 }
863
864 // Attempts to consume the supplied value. Returns false if a the
865 // token found does not match the value specified.
TryConsume(const string & value)866 bool TryConsume(const string& value) {
867 if (tokenizer_.current().text == value) {
868 tokenizer_.Next();
869 return true;
870 } else {
871 return false;
872 }
873 }
874
875 // An internal instance of the Tokenizer's error collector, used to
876 // collect any base-level parse errors and feed them to the ParserImpl.
877 class ParserErrorCollector : public io::ErrorCollector {
878 public:
ParserErrorCollector(TextFormat::Parser::ParserImpl * parser)879 explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
880 parser_(parser) { }
881
~ParserErrorCollector()882 virtual ~ParserErrorCollector() { };
883
AddError(int line,int column,const string & message)884 virtual void AddError(int line, int column, const string& message) {
885 parser_->ReportError(line, column, message);
886 }
887
AddWarning(int line,int column,const string & message)888 virtual void AddWarning(int line, int column, const string& message) {
889 parser_->ReportWarning(line, column, message);
890 }
891
892 private:
893 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
894 TextFormat::Parser::ParserImpl* parser_;
895 };
896
897 io::ErrorCollector* error_collector_;
898 TextFormat::Finder* finder_;
899 ParseInfoTree* parse_info_tree_;
900 ParserErrorCollector tokenizer_error_collector_;
901 io::Tokenizer tokenizer_;
902 const Descriptor* root_message_type_;
903 SingularOverwritePolicy singular_overwrite_policy_;
904 bool allow_unknown_field_;
905 bool had_errors_;
906 };
907
908 #undef DO
909
910 // ===========================================================================
911 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
912 // from the Printer found in //google/protobuf/io/printer.h
913 class TextFormat::Printer::TextGenerator {
914 public:
TextGenerator(io::ZeroCopyOutputStream * output,int initial_indent_level)915 explicit TextGenerator(io::ZeroCopyOutputStream* output,
916 int initial_indent_level)
917 : output_(output),
918 buffer_(NULL),
919 buffer_size_(0),
920 at_start_of_line_(true),
921 failed_(false),
922 indent_(""),
923 initial_indent_level_(initial_indent_level) {
924 indent_.resize(initial_indent_level_ * 2, ' ');
925 }
926
~TextGenerator()927 ~TextGenerator() {
928 // Only BackUp() if we're sure we've successfully called Next() at least
929 // once.
930 if (!failed_ && buffer_size_ > 0) {
931 output_->BackUp(buffer_size_);
932 }
933 }
934
935 // Indent text by two spaces. After calling Indent(), two spaces will be
936 // inserted at the beginning of each line of text. Indent() may be called
937 // multiple times to produce deeper indents.
Indent()938 void Indent() {
939 indent_ += " ";
940 }
941
942 // Reduces the current indent level by two spaces, or crashes if the indent
943 // level is zero.
Outdent()944 void Outdent() {
945 if (indent_.empty() ||
946 indent_.size() < initial_indent_level_ * 2) {
947 GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
948 return;
949 }
950
951 indent_.resize(indent_.size() - 2);
952 }
953
954 // Print text to the output stream.
Print(const string & str)955 void Print(const string& str) {
956 Print(str.data(), str.size());
957 }
958
959 // Print text to the output stream.
Print(const char * text)960 void Print(const char* text) {
961 Print(text, strlen(text));
962 }
963
964 // Print text to the output stream.
Print(const char * text,int size)965 void Print(const char* text, int size) {
966 int pos = 0; // The number of bytes we've written so far.
967
968 for (int i = 0; i < size; i++) {
969 if (text[i] == '\n') {
970 // Saw newline. If there is more text, we may need to insert an indent
971 // here. So, write what we have so far, including the '\n'.
972 Write(text + pos, i - pos + 1);
973 pos = i + 1;
974
975 // Setting this true will cause the next Write() to insert an indent
976 // first.
977 at_start_of_line_ = true;
978 }
979 }
980
981 // Write the rest.
982 Write(text + pos, size - pos);
983 }
984
985 // True if any write to the underlying stream failed. (We don't just
986 // crash in this case because this is an I/O failure, not a programming
987 // error.)
failed() const988 bool failed() const { return failed_; }
989
990 private:
991 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
992
Write(const char * data,int size)993 void Write(const char* data, int size) {
994 if (failed_) return;
995 if (size == 0) return;
996
997 if (at_start_of_line_) {
998 // Insert an indent.
999 at_start_of_line_ = false;
1000 Write(indent_.data(), indent_.size());
1001 if (failed_) return;
1002 }
1003
1004 while (size > buffer_size_) {
1005 // Data exceeds space in the buffer. Copy what we can and request a
1006 // new buffer.
1007 memcpy(buffer_, data, buffer_size_);
1008 data += buffer_size_;
1009 size -= buffer_size_;
1010 void* void_buffer;
1011 failed_ = !output_->Next(&void_buffer, &buffer_size_);
1012 if (failed_) return;
1013 buffer_ = reinterpret_cast<char*>(void_buffer);
1014 }
1015
1016 // Buffer is big enough to receive the data; copy it.
1017 memcpy(buffer_, data, size);
1018 buffer_ += size;
1019 buffer_size_ -= size;
1020 }
1021
1022 io::ZeroCopyOutputStream* const output_;
1023 char* buffer_;
1024 int buffer_size_;
1025 bool at_start_of_line_;
1026 bool failed_;
1027
1028 string indent_;
1029 int initial_indent_level_;
1030 };
1031
1032 // ===========================================================================
1033
~Finder()1034 TextFormat::Finder::~Finder() {
1035 }
1036
Parser()1037 TextFormat::Parser::Parser()
1038 : error_collector_(NULL),
1039 finder_(NULL),
1040 parse_info_tree_(NULL),
1041 allow_partial_(false),
1042 allow_unknown_field_(false) {
1043 }
1044
~Parser()1045 TextFormat::Parser::~Parser() {}
1046
Parse(io::ZeroCopyInputStream * input,Message * output)1047 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
1048 Message* output) {
1049 output->Clear();
1050 ParserImpl parser(output->GetDescriptor(), input, error_collector_,
1051 finder_, parse_info_tree_,
1052 ParserImpl::FORBID_SINGULAR_OVERWRITES,
1053 allow_unknown_field_);
1054 return MergeUsingImpl(input, output, &parser);
1055 }
1056
ParseFromString(const string & input,Message * output)1057 bool TextFormat::Parser::ParseFromString(const string& input,
1058 Message* output) {
1059 io::ArrayInputStream input_stream(input.data(), input.size());
1060 return Parse(&input_stream, output);
1061 }
1062
Merge(io::ZeroCopyInputStream * input,Message * output)1063 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
1064 Message* output) {
1065 ParserImpl parser(output->GetDescriptor(), input, error_collector_,
1066 finder_, parse_info_tree_,
1067 ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1068 allow_unknown_field_);
1069 return MergeUsingImpl(input, output, &parser);
1070 }
1071
MergeFromString(const string & input,Message * output)1072 bool TextFormat::Parser::MergeFromString(const string& input,
1073 Message* output) {
1074 io::ArrayInputStream input_stream(input.data(), input.size());
1075 return Merge(&input_stream, output);
1076 }
1077
MergeUsingImpl(io::ZeroCopyInputStream * input,Message * output,ParserImpl * parser_impl)1078 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
1079 Message* output,
1080 ParserImpl* parser_impl) {
1081 if (!parser_impl->Parse(output)) return false;
1082 if (!allow_partial_ && !output->IsInitialized()) {
1083 vector<string> missing_fields;
1084 output->FindInitializationErrors(&missing_fields);
1085 parser_impl->ReportError(-1, 0, "Message missing required fields: " +
1086 JoinStrings(missing_fields, ", "));
1087 return false;
1088 }
1089 return true;
1090 }
1091
ParseFieldValueFromString(const string & input,const FieldDescriptor * field,Message * output)1092 bool TextFormat::Parser::ParseFieldValueFromString(
1093 const string& input,
1094 const FieldDescriptor* field,
1095 Message* output) {
1096 io::ArrayInputStream input_stream(input.data(), input.size());
1097 ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
1098 finder_, parse_info_tree_,
1099 ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1100 allow_unknown_field_);
1101 return parser.ParseField(field, output);
1102 }
1103
Parse(io::ZeroCopyInputStream * input,Message * output)1104 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1105 Message* output) {
1106 return Parser().Parse(input, output);
1107 }
1108
Merge(io::ZeroCopyInputStream * input,Message * output)1109 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1110 Message* output) {
1111 return Parser().Merge(input, output);
1112 }
1113
ParseFromString(const string & input,Message * output)1114 /* static */ bool TextFormat::ParseFromString(const string& input,
1115 Message* output) {
1116 return Parser().ParseFromString(input, output);
1117 }
1118
MergeFromString(const string & input,Message * output)1119 /* static */ bool TextFormat::MergeFromString(const string& input,
1120 Message* output) {
1121 return Parser().MergeFromString(input, output);
1122 }
1123
1124 // ===========================================================================
1125
Printer()1126 TextFormat::Printer::Printer()
1127 : initial_indent_level_(0),
1128 single_line_mode_(false),
1129 use_short_repeated_primitives_(false),
1130 utf8_string_escaping_(false) {}
1131
~Printer()1132 TextFormat::Printer::~Printer() {}
1133
PrintToString(const Message & message,string * output) const1134 bool TextFormat::Printer::PrintToString(const Message& message,
1135 string* output) const {
1136 GOOGLE_DCHECK(output) << "output specified is NULL";
1137
1138 output->clear();
1139 io::StringOutputStream output_stream(output);
1140
1141 bool result = Print(message, &output_stream);
1142
1143 return result;
1144 }
1145
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,string * output) const1146 bool TextFormat::Printer::PrintUnknownFieldsToString(
1147 const UnknownFieldSet& unknown_fields,
1148 string* output) const {
1149 GOOGLE_DCHECK(output) << "output specified is NULL";
1150
1151 output->clear();
1152 io::StringOutputStream output_stream(output);
1153 return PrintUnknownFields(unknown_fields, &output_stream);
1154 }
1155
Print(const Message & message,io::ZeroCopyOutputStream * output) const1156 bool TextFormat::Printer::Print(const Message& message,
1157 io::ZeroCopyOutputStream* output) const {
1158 TextGenerator generator(output, initial_indent_level_);
1159
1160 Print(message, generator);
1161
1162 // Output false if the generator failed internally.
1163 return !generator.failed();
1164 }
1165
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output) const1166 bool TextFormat::Printer::PrintUnknownFields(
1167 const UnknownFieldSet& unknown_fields,
1168 io::ZeroCopyOutputStream* output) const {
1169 TextGenerator generator(output, initial_indent_level_);
1170
1171 PrintUnknownFields(unknown_fields, generator);
1172
1173 // Output false if the generator failed internally.
1174 return !generator.failed();
1175 }
1176
Print(const Message & message,TextGenerator & generator) const1177 void TextFormat::Printer::Print(const Message& message,
1178 TextGenerator& generator) const {
1179 const Reflection* reflection = message.GetReflection();
1180 vector<const FieldDescriptor*> fields;
1181 reflection->ListFields(message, &fields);
1182 for (int i = 0; i < fields.size(); i++) {
1183 PrintField(message, reflection, fields[i], generator);
1184 }
1185 PrintUnknownFields(reflection->GetUnknownFields(message), generator);
1186 }
1187
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,string * output) const1188 void TextFormat::Printer::PrintFieldValueToString(
1189 const Message& message,
1190 const FieldDescriptor* field,
1191 int index,
1192 string* output) const {
1193
1194 GOOGLE_DCHECK(output) << "output specified is NULL";
1195
1196 output->clear();
1197 io::StringOutputStream output_stream(output);
1198 TextGenerator generator(&output_stream, initial_indent_level_);
1199
1200 PrintFieldValue(message, message.GetReflection(), field, index, generator);
1201 }
1202
PrintField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1203 void TextFormat::Printer::PrintField(const Message& message,
1204 const Reflection* reflection,
1205 const FieldDescriptor* field,
1206 TextGenerator& generator) const {
1207 if (use_short_repeated_primitives_ &&
1208 field->is_repeated() &&
1209 field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
1210 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
1211 PrintShortRepeatedField(message, reflection, field, generator);
1212 return;
1213 }
1214
1215 int count = 0;
1216
1217 if (field->is_repeated()) {
1218 count = reflection->FieldSize(message, field);
1219 } else if (reflection->HasField(message, field)) {
1220 count = 1;
1221 }
1222
1223 for (int j = 0; j < count; ++j) {
1224 PrintFieldName(message, reflection, field, generator);
1225
1226 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1227 if (single_line_mode_) {
1228 generator.Print(" { ");
1229 } else {
1230 generator.Print(" {\n");
1231 generator.Indent();
1232 }
1233 } else {
1234 generator.Print(": ");
1235 }
1236
1237 // Write the field value.
1238 int field_index = j;
1239 if (!field->is_repeated()) {
1240 field_index = -1;
1241 }
1242
1243 PrintFieldValue(message, reflection, field, field_index, generator);
1244
1245 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1246 if (single_line_mode_) {
1247 generator.Print("} ");
1248 } else {
1249 generator.Outdent();
1250 generator.Print("}\n");
1251 }
1252 } else {
1253 if (single_line_mode_) {
1254 generator.Print(" ");
1255 } else {
1256 generator.Print("\n");
1257 }
1258 }
1259 }
1260 }
1261
PrintShortRepeatedField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1262 void TextFormat::Printer::PrintShortRepeatedField(
1263 const Message& message,
1264 const Reflection* reflection,
1265 const FieldDescriptor* field,
1266 TextGenerator& generator) const {
1267 // Print primitive repeated field in short form.
1268 PrintFieldName(message, reflection, field, generator);
1269
1270 int size = reflection->FieldSize(message, field);
1271 generator.Print(": [");
1272 for (int i = 0; i < size; i++) {
1273 if (i > 0) generator.Print(", ");
1274 PrintFieldValue(message, reflection, field, i, generator);
1275 }
1276 if (single_line_mode_) {
1277 generator.Print("] ");
1278 } else {
1279 generator.Print("]\n");
1280 }
1281 }
1282
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1283 void TextFormat::Printer::PrintFieldName(const Message& message,
1284 const Reflection* reflection,
1285 const FieldDescriptor* field,
1286 TextGenerator& generator) const {
1287 if (field->is_extension()) {
1288 generator.Print("[");
1289 // We special-case MessageSet elements for compatibility with proto1.
1290 if (field->containing_type()->options().message_set_wire_format()
1291 && field->type() == FieldDescriptor::TYPE_MESSAGE
1292 && field->is_optional()
1293 && field->extension_scope() == field->message_type()) {
1294 generator.Print(field->message_type()->full_name());
1295 } else {
1296 generator.Print(field->full_name());
1297 }
1298 generator.Print("]");
1299 } else {
1300 if (field->type() == FieldDescriptor::TYPE_GROUP) {
1301 // Groups must be serialized with their original capitalization.
1302 generator.Print(field->message_type()->name());
1303 } else {
1304 generator.Print(field->name());
1305 }
1306 }
1307 }
1308
PrintFieldValue(const Message & message,const Reflection * reflection,const FieldDescriptor * field,int index,TextGenerator & generator) const1309 void TextFormat::Printer::PrintFieldValue(
1310 const Message& message,
1311 const Reflection* reflection,
1312 const FieldDescriptor* field,
1313 int index,
1314 TextGenerator& generator) const {
1315 GOOGLE_DCHECK(field->is_repeated() || (index == -1))
1316 << "Index must be -1 for non-repeated fields";
1317
1318 switch (field->cpp_type()) {
1319 #define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \
1320 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
1321 generator.Print(TO_STRING(field->is_repeated() ? \
1322 reflection->GetRepeated##METHOD(message, field, index) : \
1323 reflection->Get##METHOD(message, field))); \
1324 break; \
1325
1326 OUTPUT_FIELD( INT32, Int32, SimpleItoa);
1327 OUTPUT_FIELD( INT64, Int64, SimpleItoa);
1328 OUTPUT_FIELD(UINT32, UInt32, SimpleItoa);
1329 OUTPUT_FIELD(UINT64, UInt64, SimpleItoa);
1330 OUTPUT_FIELD( FLOAT, Float, SimpleFtoa);
1331 OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa);
1332 #undef OUTPUT_FIELD
1333
1334 case FieldDescriptor::CPPTYPE_STRING: {
1335 string scratch;
1336 const string& value = field->is_repeated() ?
1337 reflection->GetRepeatedStringReference(
1338 message, field, index, &scratch) :
1339 reflection->GetStringReference(message, field, &scratch);
1340
1341 generator.Print("\"");
1342 if (utf8_string_escaping_) {
1343 generator.Print(strings::Utf8SafeCEscape(value));
1344 } else {
1345 generator.Print(CEscape(value));
1346 }
1347 generator.Print("\"");
1348
1349 break;
1350 }
1351
1352 case FieldDescriptor::CPPTYPE_BOOL:
1353 if (field->is_repeated()) {
1354 generator.Print(reflection->GetRepeatedBool(message, field, index)
1355 ? "true" : "false");
1356 } else {
1357 generator.Print(reflection->GetBool(message, field)
1358 ? "true" : "false");
1359 }
1360 break;
1361
1362 case FieldDescriptor::CPPTYPE_ENUM:
1363 generator.Print(field->is_repeated() ?
1364 reflection->GetRepeatedEnum(message, field, index)->name() :
1365 reflection->GetEnum(message, field)->name());
1366 break;
1367
1368 case FieldDescriptor::CPPTYPE_MESSAGE:
1369 Print(field->is_repeated() ?
1370 reflection->GetRepeatedMessage(message, field, index) :
1371 reflection->GetMessage(message, field),
1372 generator);
1373 break;
1374 }
1375 }
1376
Print(const Message & message,io::ZeroCopyOutputStream * output)1377 /* static */ bool TextFormat::Print(const Message& message,
1378 io::ZeroCopyOutputStream* output) {
1379 return Printer().Print(message, output);
1380 }
1381
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output)1382 /* static */ bool TextFormat::PrintUnknownFields(
1383 const UnknownFieldSet& unknown_fields,
1384 io::ZeroCopyOutputStream* output) {
1385 return Printer().PrintUnknownFields(unknown_fields, output);
1386 }
1387
PrintToString(const Message & message,string * output)1388 /* static */ bool TextFormat::PrintToString(
1389 const Message& message, string* output) {
1390 return Printer().PrintToString(message, output);
1391 }
1392
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,string * output)1393 /* static */ bool TextFormat::PrintUnknownFieldsToString(
1394 const UnknownFieldSet& unknown_fields, string* output) {
1395 return Printer().PrintUnknownFieldsToString(unknown_fields, output);
1396 }
1397
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,string * output)1398 /* static */ void TextFormat::PrintFieldValueToString(
1399 const Message& message,
1400 const FieldDescriptor* field,
1401 int index,
1402 string* output) {
1403 return Printer().PrintFieldValueToString(message, field, index, output);
1404 }
1405
ParseFieldValueFromString(const string & input,const FieldDescriptor * field,Message * message)1406 /* static */ bool TextFormat::ParseFieldValueFromString(
1407 const string& input,
1408 const FieldDescriptor* field,
1409 Message* message) {
1410 return Parser().ParseFieldValueFromString(input, field, message);
1411 }
1412
1413 // Prints an integer as hex with a fixed number of digits dependent on the
1414 // integer type.
1415 template<typename IntType>
PaddedHex(IntType value)1416 static string PaddedHex(IntType value) {
1417 string result;
1418 result.reserve(sizeof(value) * 2);
1419 for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
1420 result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
1421 }
1422 return result;
1423 }
1424
PrintUnknownFields(const UnknownFieldSet & unknown_fields,TextGenerator & generator) const1425 void TextFormat::Printer::PrintUnknownFields(
1426 const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
1427 for (int i = 0; i < unknown_fields.field_count(); i++) {
1428 const UnknownField& field = unknown_fields.field(i);
1429 string field_number = SimpleItoa(field.number());
1430
1431 switch (field.type()) {
1432 case UnknownField::TYPE_VARINT:
1433 generator.Print(field_number);
1434 generator.Print(": ");
1435 generator.Print(SimpleItoa(field.varint()));
1436 if (single_line_mode_) {
1437 generator.Print(" ");
1438 } else {
1439 generator.Print("\n");
1440 }
1441 break;
1442 case UnknownField::TYPE_FIXED32: {
1443 generator.Print(field_number);
1444 generator.Print(": 0x");
1445 char buffer[kFastToBufferSize];
1446 generator.Print(FastHex32ToBuffer(field.fixed32(), buffer));
1447 if (single_line_mode_) {
1448 generator.Print(" ");
1449 } else {
1450 generator.Print("\n");
1451 }
1452 break;
1453 }
1454 case UnknownField::TYPE_FIXED64: {
1455 generator.Print(field_number);
1456 generator.Print(": 0x");
1457 char buffer[kFastToBufferSize];
1458 generator.Print(FastHex64ToBuffer(field.fixed64(), buffer));
1459 if (single_line_mode_) {
1460 generator.Print(" ");
1461 } else {
1462 generator.Print("\n");
1463 }
1464 break;
1465 }
1466 case UnknownField::TYPE_LENGTH_DELIMITED: {
1467 generator.Print(field_number);
1468 const string& value = field.length_delimited();
1469 UnknownFieldSet embedded_unknown_fields;
1470 if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
1471 // This field is parseable as a Message.
1472 // So it is probably an embedded message.
1473 if (single_line_mode_) {
1474 generator.Print(" { ");
1475 } else {
1476 generator.Print(" {\n");
1477 generator.Indent();
1478 }
1479 PrintUnknownFields(embedded_unknown_fields, generator);
1480 if (single_line_mode_) {
1481 generator.Print("} ");
1482 } else {
1483 generator.Outdent();
1484 generator.Print("}\n");
1485 }
1486 } else {
1487 // This field is not parseable as a Message.
1488 // So it is probably just a plain string.
1489 generator.Print(": \"");
1490 generator.Print(CEscape(value));
1491 generator.Print("\"");
1492 if (single_line_mode_) {
1493 generator.Print(" ");
1494 } else {
1495 generator.Print("\n");
1496 }
1497 }
1498 break;
1499 }
1500 case UnknownField::TYPE_GROUP:
1501 generator.Print(field_number);
1502 if (single_line_mode_) {
1503 generator.Print(" { ");
1504 } else {
1505 generator.Print(" {\n");
1506 generator.Indent();
1507 }
1508 PrintUnknownFields(field.group(), generator);
1509 if (single_line_mode_) {
1510 generator.Print("} ");
1511 } else {
1512 generator.Outdent();
1513 generator.Print("}\n");
1514 }
1515 break;
1516 }
1517 }
1518 }
1519
1520 } // namespace protobuf
1521 } // namespace google
1522