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 <algorithm>
36 #include <float.h>
37 #include <math.h>
38 #include <stdio.h>
39 #include <stack>
40 #include <limits>
41 #include <vector>
42
43 #include <google/protobuf/text_format.h>
44
45 #include <google/protobuf/descriptor.h>
46 #include <google/protobuf/dynamic_message.h>
47 #include <google/protobuf/repeated_field.h>
48 #include <google/protobuf/wire_format_lite.h>
49 #include <google/protobuf/io/strtod.h>
50 #include <google/protobuf/io/coded_stream.h>
51 #include <google/protobuf/io/zero_copy_stream.h>
52 #include <google/protobuf/io/zero_copy_stream_impl.h>
53 #include <google/protobuf/unknown_field_set.h>
54 #include <google/protobuf/descriptor.pb.h>
55 #include <google/protobuf/io/tokenizer.h>
56 #include <google/protobuf/any.h>
57 #include <google/protobuf/stubs/stringprintf.h>
58 #include <google/protobuf/stubs/strutil.h>
59 #include <google/protobuf/stubs/map_util.h>
60 #include <google/protobuf/stubs/stl_util.h>
61
62 namespace google {
63 namespace protobuf {
64
65 namespace {
66
IsHexNumber(const string & str)67 inline bool IsHexNumber(const string& str) {
68 return (str.length() >= 2 && str[0] == '0' &&
69 (str[1] == 'x' || str[1] == 'X'));
70 }
71
IsOctNumber(const string & str)72 inline bool IsOctNumber(const string& str) {
73 return (str.length() >= 2 && str[0] == '0' &&
74 (str[1] >= '0' && str[1] < '8'));
75 }
76
GetAnyFieldDescriptors(const Message & message,const FieldDescriptor ** type_url_field,const FieldDescriptor ** value_field)77 inline bool GetAnyFieldDescriptors(const Message& message,
78 const FieldDescriptor** type_url_field,
79 const FieldDescriptor** value_field) {
80 const Descriptor* descriptor = message.GetDescriptor();
81 *type_url_field = descriptor->FindFieldByNumber(1);
82 *value_field = descriptor->FindFieldByNumber(2);
83 return (*type_url_field != NULL &&
84 (*type_url_field)->type() == FieldDescriptor::TYPE_STRING &&
85 *value_field != NULL &&
86 (*value_field)->type() == FieldDescriptor::TYPE_BYTES);
87 }
88
89 } // namespace
90
DebugString() const91 string Message::DebugString() const {
92 string debug_string;
93
94 TextFormat::Printer printer;
95 printer.SetExpandAny(true);
96
97 printer.PrintToString(*this, &debug_string);
98
99 return debug_string;
100 }
101
ShortDebugString() const102 string Message::ShortDebugString() const {
103 string debug_string;
104
105 TextFormat::Printer printer;
106 printer.SetSingleLineMode(true);
107 printer.SetExpandAny(true);
108
109 printer.PrintToString(*this, &debug_string);
110 // Single line mode currently might have an extra space at the end.
111 if (debug_string.size() > 0 &&
112 debug_string[debug_string.size() - 1] == ' ') {
113 debug_string.resize(debug_string.size() - 1);
114 }
115
116 return debug_string;
117 }
118
Utf8DebugString() const119 string Message::Utf8DebugString() const {
120 string debug_string;
121
122 TextFormat::Printer printer;
123 printer.SetUseUtf8StringEscaping(true);
124 printer.SetExpandAny(true);
125
126 printer.PrintToString(*this, &debug_string);
127
128 return debug_string;
129 }
130
PrintDebugString() const131 void Message::PrintDebugString() const {
132 printf("%s", DebugString().c_str());
133 }
134
135
136 // ===========================================================================
137 // Implementation of the parse information tree class.
ParseInfoTree()138 TextFormat::ParseInfoTree::ParseInfoTree() { }
139
~ParseInfoTree()140 TextFormat::ParseInfoTree::~ParseInfoTree() {
141 // Remove any nested information trees, as they are owned by this tree.
142 for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) {
143 STLDeleteElements(&(it->second));
144 }
145 }
146
RecordLocation(const FieldDescriptor * field,TextFormat::ParseLocation location)147 void TextFormat::ParseInfoTree::RecordLocation(
148 const FieldDescriptor* field,
149 TextFormat::ParseLocation location) {
150 locations_[field].push_back(location);
151 }
152
CreateNested(const FieldDescriptor * field)153 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
154 const FieldDescriptor* field) {
155 // Owned by us in the map.
156 TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
157 vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
158 GOOGLE_CHECK(trees);
159 trees->push_back(instance);
160 return instance;
161 }
162
CheckFieldIndex(const FieldDescriptor * field,int index)163 void CheckFieldIndex(const FieldDescriptor* field, int index) {
164 if (field == NULL) { return; }
165
166 if (field->is_repeated() && index == -1) {
167 GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
168 << "Field: " << field->name();
169 } else if (!field->is_repeated() && index != -1) {
170 GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
171 << "Field: " << field->name();
172 }
173 }
174
GetLocation(const FieldDescriptor * field,int index) const175 TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
176 const FieldDescriptor* field, int index) const {
177 CheckFieldIndex(field, index);
178 if (index == -1) { index = 0; }
179
180 const vector<TextFormat::ParseLocation>* locations =
181 FindOrNull(locations_, field);
182 if (locations == NULL || index >= locations->size()) {
183 return TextFormat::ParseLocation();
184 }
185
186 return (*locations)[index];
187 }
188
GetTreeForNested(const FieldDescriptor * field,int index) const189 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
190 const FieldDescriptor* field, int index) const {
191 CheckFieldIndex(field, index);
192 if (index == -1) { index = 0; }
193
194 const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field);
195 if (trees == NULL || index >= trees->size()) {
196 return NULL;
197 }
198
199 return (*trees)[index];
200 }
201
202
203 // ===========================================================================
204 // Internal class for parsing an ASCII representation of a Protocol Message.
205 // This class makes use of the Protocol Message compiler's tokenizer found
206 // in //google/protobuf/io/tokenizer.h. Note that class's Parse
207 // method is *not* thread-safe and should only be used in a single thread at
208 // a time.
209
210 // Makes code slightly more readable. The meaning of "DO(foo)" is
211 // "Execute foo and fail if it fails.", where failure is indicated by
212 // returning false. Borrowed from parser.cc (Thanks Kenton!).
213 #define DO(STATEMENT) if (STATEMENT) {} else return false
214
215 class TextFormat::Parser::ParserImpl {
216 public:
217
218 // Determines if repeated values for non-repeated fields and
219 // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
220 // required/optional field named "foo", or "baz: 1 qux: 2"
221 // where "baz" and "qux" are members of the same oneof.
222 enum SingularOverwritePolicy {
223 ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
224 FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
225 };
226
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_case_insensitive_field,bool allow_unknown_field,bool allow_unknown_enum,bool allow_field_number,bool allow_relaxed_whitespace,bool allow_partial)227 ParserImpl(const Descriptor* root_message_type,
228 io::ZeroCopyInputStream* input_stream,
229 io::ErrorCollector* error_collector,
230 TextFormat::Finder* finder,
231 ParseInfoTree* parse_info_tree,
232 SingularOverwritePolicy singular_overwrite_policy,
233 bool allow_case_insensitive_field,
234 bool allow_unknown_field,
235 bool allow_unknown_enum,
236 bool allow_field_number,
237 bool allow_relaxed_whitespace,
238 bool allow_partial)
239 : error_collector_(error_collector),
240 finder_(finder),
241 parse_info_tree_(parse_info_tree),
242 tokenizer_error_collector_(this),
243 tokenizer_(input_stream, &tokenizer_error_collector_),
244 root_message_type_(root_message_type),
245 singular_overwrite_policy_(singular_overwrite_policy),
246 allow_case_insensitive_field_(allow_case_insensitive_field),
247 allow_unknown_field_(allow_unknown_field),
248 allow_unknown_enum_(allow_unknown_enum),
249 allow_field_number_(allow_field_number),
250 allow_partial_(allow_partial),
251 had_errors_(false) {
252 // For backwards-compatibility with proto1, we need to allow the 'f' suffix
253 // for floats.
254 tokenizer_.set_allow_f_after_float(true);
255
256 // '#' starts a comment.
257 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
258
259 if (allow_relaxed_whitespace) {
260 tokenizer_.set_require_space_after_number(false);
261 tokenizer_.set_allow_multiline_strings(true);
262 }
263
264 // Consume the starting token.
265 tokenizer_.Next();
266 }
~ParserImpl()267 ~ParserImpl() { }
268
269 // Parses the ASCII representation specified in input and saves the
270 // information into the output pointer (a Message). Returns
271 // false if an error occurs (an error will also be logged to
272 // GOOGLE_LOG(ERROR)).
Parse(Message * output)273 bool Parse(Message* output) {
274 // Consume fields until we cannot do so anymore.
275 while (true) {
276 if (LookingAtType(io::Tokenizer::TYPE_END)) {
277 return !had_errors_;
278 }
279
280 DO(ConsumeField(output));
281 }
282 }
283
ParseField(const FieldDescriptor * field,Message * output)284 bool ParseField(const FieldDescriptor* field, Message* output) {
285 bool suc;
286 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
287 suc = ConsumeFieldMessage(output, output->GetReflection(), field);
288 } else {
289 suc = ConsumeFieldValue(output, output->GetReflection(), field);
290 }
291 return suc && LookingAtType(io::Tokenizer::TYPE_END);
292 }
293
ReportError(int line,int col,const string & message)294 void ReportError(int line, int col, const string& message) {
295 had_errors_ = true;
296 if (error_collector_ == NULL) {
297 if (line >= 0) {
298 GOOGLE_LOG(ERROR) << "Error parsing text-format "
299 << root_message_type_->full_name()
300 << ": " << (line + 1) << ":"
301 << (col + 1) << ": " << message;
302 } else {
303 GOOGLE_LOG(ERROR) << "Error parsing text-format "
304 << root_message_type_->full_name()
305 << ": " << message;
306 }
307 } else {
308 error_collector_->AddError(line, col, message);
309 }
310 }
311
ReportWarning(int line,int col,const string & message)312 void ReportWarning(int line, int col, const string& message) {
313 if (error_collector_ == NULL) {
314 if (line >= 0) {
315 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
316 << root_message_type_->full_name()
317 << ": " << (line + 1) << ":"
318 << (col + 1) << ": " << message;
319 } else {
320 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
321 << root_message_type_->full_name()
322 << ": " << message;
323 }
324 } else {
325 error_collector_->AddWarning(line, col, message);
326 }
327 }
328
329 private:
330 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
331
332 // Reports an error with the given message with information indicating
333 // the position (as derived from the current token).
ReportError(const string & message)334 void ReportError(const string& message) {
335 ReportError(tokenizer_.current().line, tokenizer_.current().column,
336 message);
337 }
338
339 // Reports a warning with the given message with information indicating
340 // the position (as derived from the current token).
ReportWarning(const string & message)341 void ReportWarning(const string& message) {
342 ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
343 message);
344 }
345
346 // Consumes the specified message with the given starting delimiter.
347 // This method checks to see that the end delimiter at the conclusion of
348 // the consumption matches the starting delimiter passed in here.
ConsumeMessage(Message * message,const string delimiter)349 bool ConsumeMessage(Message* message, const string delimiter) {
350 while (!LookingAt(">") && !LookingAt("}")) {
351 DO(ConsumeField(message));
352 }
353
354 // Confirm that we have a valid ending delimiter.
355 DO(Consume(delimiter));
356 return true;
357 }
358
359 // Consume either "<" or "{".
ConsumeMessageDelimiter(string * delimiter)360 bool ConsumeMessageDelimiter(string* delimiter) {
361 if (TryConsume("<")) {
362 *delimiter = ">";
363 } else {
364 DO(Consume("{"));
365 *delimiter = "}";
366 }
367 return true;
368 }
369
370
371 // Consumes the current field (as returned by the tokenizer) on the
372 // passed in message.
ConsumeField(Message * message)373 bool ConsumeField(Message* message) {
374 const Reflection* reflection = message->GetReflection();
375 const Descriptor* descriptor = message->GetDescriptor();
376
377 string field_name;
378
379 const FieldDescriptor* field = NULL;
380 int start_line = tokenizer_.current().line;
381 int start_column = tokenizer_.current().column;
382
383 const FieldDescriptor* any_type_url_field;
384 const FieldDescriptor* any_value_field;
385 if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field,
386 &any_value_field) &&
387 TryConsume("[")) {
388 string full_type_name, prefix;
389 DO(ConsumeAnyTypeUrl(&full_type_name, &prefix));
390 DO(Consume("]"));
391 TryConsume(":"); // ':' is optional between message labels and values.
392 string serialized_value;
393 DO(ConsumeAnyValue(full_type_name,
394 message->GetDescriptor()->file()->pool(),
395 &serialized_value));
396 reflection->SetString(
397 message, any_type_url_field,
398 string(prefix + full_type_name));
399 reflection->SetString(message, any_value_field, serialized_value);
400 return true;
401 }
402 if (TryConsume("[")) {
403 // Extension.
404 DO(ConsumeFullTypeName(&field_name));
405 DO(Consume("]"));
406
407 field = (finder_ != NULL
408 ? finder_->FindExtension(message, field_name)
409 : reflection->FindKnownExtensionByName(field_name));
410
411 if (field == NULL) {
412 if (!allow_unknown_field_) {
413 ReportError("Extension \"" + field_name + "\" is not defined or "
414 "is not an extension of \"" +
415 descriptor->full_name() + "\".");
416 return false;
417 } else {
418 ReportWarning("Extension \"" + field_name + "\" is not defined or "
419 "is not an extension of \"" +
420 descriptor->full_name() + "\".");
421 }
422 }
423 } else {
424 DO(ConsumeIdentifier(&field_name));
425
426 int32 field_number;
427 if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
428 if (descriptor->IsExtensionNumber(field_number)) {
429 field = reflection->FindKnownExtensionByNumber(field_number);
430 } else {
431 field = descriptor->FindFieldByNumber(field_number);
432 }
433 } else {
434 field = descriptor->FindFieldByName(field_name);
435 // Group names are expected to be capitalized as they appear in the
436 // .proto file, which actually matches their type names, not their
437 // field names.
438 if (field == NULL) {
439 string lower_field_name = field_name;
440 LowerString(&lower_field_name);
441 field = descriptor->FindFieldByName(lower_field_name);
442 // If the case-insensitive match worked but the field is NOT a group,
443 if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
444 field = NULL;
445 }
446 }
447 // Again, special-case group names as described above.
448 if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
449 && field->message_type()->name() != field_name) {
450 field = NULL;
451 }
452
453 if (field == NULL && allow_case_insensitive_field_) {
454 string lower_field_name = field_name;
455 LowerString(&lower_field_name);
456 field = descriptor->FindFieldByLowercaseName(lower_field_name);
457 }
458 }
459
460 if (field == NULL) {
461 if (!allow_unknown_field_) {
462 ReportError("Message type \"" + descriptor->full_name() +
463 "\" has no field named \"" + field_name + "\".");
464 return false;
465 } else {
466 ReportWarning("Message type \"" + descriptor->full_name() +
467 "\" has no field named \"" + field_name + "\".");
468 }
469 }
470 }
471
472 // Skips unknown field.
473 if (field == NULL) {
474 GOOGLE_CHECK(allow_unknown_field_);
475 // Try to guess the type of this field.
476 // If this field is not a message, there should be a ":" between the
477 // field name and the field value and also the field value should not
478 // start with "{" or "<" which indicates the beginning of a message body.
479 // If there is no ":" or there is a "{" or "<" after ":", this field has
480 // to be a message or the input is ill-formed.
481 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
482 return SkipFieldValue();
483 } else {
484 return SkipFieldMessage();
485 }
486 }
487
488 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
489 // Fail if the field is not repeated and it has already been specified.
490 if (!field->is_repeated() && reflection->HasField(*message, field)) {
491 ReportError("Non-repeated field \"" + field_name +
492 "\" is specified multiple times.");
493 return false;
494 }
495 // Fail if the field is a member of a oneof and another member has already
496 // been specified.
497 const OneofDescriptor* oneof = field->containing_oneof();
498 if (oneof != NULL && reflection->HasOneof(*message, oneof)) {
499 const FieldDescriptor* other_field =
500 reflection->GetOneofFieldDescriptor(*message, oneof);
501 ReportError("Field \"" + field_name + "\" is specified along with "
502 "field \"" + other_field->name() + "\", another member "
503 "of oneof \"" + oneof->name() + "\".");
504 return false;
505 }
506 }
507
508 // Perform special handling for embedded message types.
509 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
510 // ':' is optional here.
511 TryConsume(":");
512 } else {
513 // ':' is required here.
514 DO(Consume(":"));
515 }
516
517 if (field->is_repeated() && TryConsume("[")) {
518 // Short repeated format, e.g. "foo: [1, 2, 3]"
519 while (true) {
520 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
521 // Perform special handling for embedded message types.
522 DO(ConsumeFieldMessage(message, reflection, field));
523 } else {
524 DO(ConsumeFieldValue(message, reflection, field));
525 }
526 if (TryConsume("]")) {
527 break;
528 }
529 DO(Consume(","));
530 }
531 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
532 DO(ConsumeFieldMessage(message, reflection, field));
533 } else {
534 DO(ConsumeFieldValue(message, reflection, field));
535 }
536
537 // For historical reasons, fields may optionally be separated by commas or
538 // semicolons.
539 TryConsume(";") || TryConsume(",");
540
541 if (field->options().deprecated()) {
542 ReportWarning("text format contains deprecated field \""
543 + field_name + "\"");
544 }
545
546 // If a parse info tree exists, add the location for the parsed
547 // field.
548 if (parse_info_tree_ != NULL) {
549 RecordLocation(parse_info_tree_, field,
550 ParseLocation(start_line, start_column));
551 }
552
553 return true;
554 }
555
556 // Skips the next field including the field's name and value.
SkipField()557 bool SkipField() {
558 string field_name;
559 if (TryConsume("[")) {
560 // Extension name.
561 DO(ConsumeFullTypeName(&field_name));
562 DO(Consume("]"));
563 } else {
564 DO(ConsumeIdentifier(&field_name));
565 }
566
567 // Try to guess the type of this field.
568 // If this field is not a message, there should be a ":" between the
569 // field name and the field value and also the field value should not
570 // start with "{" or "<" which indicates the beginning of a message body.
571 // If there is no ":" or there is a "{" or "<" after ":", this field has
572 // to be a message or the input is ill-formed.
573 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
574 DO(SkipFieldValue());
575 } else {
576 DO(SkipFieldMessage());
577 }
578 // For historical reasons, fields may optionally be separated by commas or
579 // semicolons.
580 TryConsume(";") || TryConsume(",");
581 return true;
582 }
583
ConsumeFieldMessage(Message * message,const Reflection * reflection,const FieldDescriptor * field)584 bool ConsumeFieldMessage(Message* message,
585 const Reflection* reflection,
586 const FieldDescriptor* field) {
587
588 // If the parse information tree is not NULL, create a nested one
589 // for the nested message.
590 ParseInfoTree* parent = parse_info_tree_;
591 if (parent != NULL) {
592 parse_info_tree_ = CreateNested(parent, field);
593 }
594
595 string delimiter;
596 DO(ConsumeMessageDelimiter(&delimiter));
597 if (field->is_repeated()) {
598 DO(ConsumeMessage(reflection->AddMessage(message, field), delimiter));
599 } else {
600 DO(ConsumeMessage(reflection->MutableMessage(message, field),
601 delimiter));
602 }
603
604 // Reset the parse information tree.
605 parse_info_tree_ = parent;
606 return true;
607 }
608
609 // Skips the whole body of a message including the beginning delimiter and
610 // the ending delimiter.
SkipFieldMessage()611 bool SkipFieldMessage() {
612 string delimiter;
613 DO(ConsumeMessageDelimiter(&delimiter));
614 while (!LookingAt(">") && !LookingAt("}")) {
615 DO(SkipField());
616 }
617 DO(Consume(delimiter));
618 return true;
619 }
620
ConsumeFieldValue(Message * message,const Reflection * reflection,const FieldDescriptor * field)621 bool ConsumeFieldValue(Message* message,
622 const Reflection* reflection,
623 const FieldDescriptor* field) {
624
625 // Define an easy to use macro for setting fields. This macro checks
626 // to see if the field is repeated (in which case we need to use the Add
627 // methods or not (in which case we need to use the Set methods).
628 #define SET_FIELD(CPPTYPE, VALUE) \
629 if (field->is_repeated()) { \
630 reflection->Add##CPPTYPE(message, field, VALUE); \
631 } else { \
632 reflection->Set##CPPTYPE(message, field, VALUE); \
633 } \
634
635 switch(field->cpp_type()) {
636 case FieldDescriptor::CPPTYPE_INT32: {
637 int64 value;
638 DO(ConsumeSignedInteger(&value, kint32max));
639 SET_FIELD(Int32, static_cast<int32>(value));
640 break;
641 }
642
643 case FieldDescriptor::CPPTYPE_UINT32: {
644 uint64 value;
645 DO(ConsumeUnsignedInteger(&value, kuint32max));
646 SET_FIELD(UInt32, static_cast<uint32>(value));
647 break;
648 }
649
650 case FieldDescriptor::CPPTYPE_INT64: {
651 int64 value;
652 DO(ConsumeSignedInteger(&value, kint64max));
653 SET_FIELD(Int64, value);
654 break;
655 }
656
657 case FieldDescriptor::CPPTYPE_UINT64: {
658 uint64 value;
659 DO(ConsumeUnsignedInteger(&value, kuint64max));
660 SET_FIELD(UInt64, value);
661 break;
662 }
663
664 case FieldDescriptor::CPPTYPE_FLOAT: {
665 double value;
666 DO(ConsumeDouble(&value));
667 SET_FIELD(Float, io::SafeDoubleToFloat(value));
668 break;
669 }
670
671 case FieldDescriptor::CPPTYPE_DOUBLE: {
672 double value;
673 DO(ConsumeDouble(&value));
674 SET_FIELD(Double, value);
675 break;
676 }
677
678 case FieldDescriptor::CPPTYPE_STRING: {
679 string value;
680 DO(ConsumeString(&value));
681 SET_FIELD(String, value);
682 break;
683 }
684
685 case FieldDescriptor::CPPTYPE_BOOL: {
686 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
687 uint64 value;
688 DO(ConsumeUnsignedInteger(&value, 1));
689 SET_FIELD(Bool, value);
690 } else {
691 string value;
692 DO(ConsumeIdentifier(&value));
693 if (value == "true" || value == "True" || value == "t") {
694 SET_FIELD(Bool, true);
695 } else if (value == "false" || value == "False" || value == "f") {
696 SET_FIELD(Bool, false);
697 } else {
698 ReportError("Invalid value for boolean field \"" + field->name()
699 + "\". Value: \"" + value + "\".");
700 return false;
701 }
702 }
703 break;
704 }
705
706 case FieldDescriptor::CPPTYPE_ENUM: {
707 string value;
708 const EnumDescriptor* enum_type = field->enum_type();
709 const EnumValueDescriptor* enum_value = NULL;
710
711 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
712 DO(ConsumeIdentifier(&value));
713 // Find the enumeration value.
714 enum_value = enum_type->FindValueByName(value);
715
716 } else if (LookingAt("-") ||
717 LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
718 int64 int_value;
719 DO(ConsumeSignedInteger(&int_value, kint32max));
720 value = SimpleItoa(int_value); // for error reporting
721 enum_value = enum_type->FindValueByNumber(int_value);
722 } else {
723 ReportError("Expected integer or identifier, got: " +
724 tokenizer_.current().text);
725 return false;
726 }
727
728 if (enum_value == NULL) {
729 if (!allow_unknown_enum_) {
730 ReportError("Unknown enumeration value of \"" + value + "\" for "
731 "field \"" + field->name() + "\".");
732 return false;
733 } else {
734 ReportWarning("Unknown enumeration value of \"" + value + "\" for "
735 "field \"" + field->name() + "\".");
736 return true;
737 }
738 }
739
740 SET_FIELD(Enum, enum_value);
741 break;
742 }
743
744 case FieldDescriptor::CPPTYPE_MESSAGE: {
745 // We should never get here. Put here instead of a default
746 // so that if new types are added, we get a nice compiler warning.
747 GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
748 break;
749 }
750 }
751 #undef SET_FIELD
752 return true;
753 }
754
SkipFieldValue()755 bool SkipFieldValue() {
756 if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
757 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
758 tokenizer_.Next();
759 }
760 return true;
761 }
762 if (TryConsume("[")) {
763 while (true) {
764 if (!LookingAt("{") && !LookingAt("<")) {
765 DO(SkipFieldValue());
766 } else {
767 DO(SkipFieldMessage());
768 }
769 if (TryConsume("]")) {
770 break;
771 }
772 DO(Consume(","));
773 }
774 return true;
775 }
776 // Possible field values other than string:
777 // 12345 => TYPE_INTEGER
778 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
779 // 1.2345 => TYPE_FLOAT
780 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
781 // inf => TYPE_IDENTIFIER
782 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
783 // TYPE_INTEGER => TYPE_IDENTIFIER
784 // Divides them into two group, one with TYPE_SYMBOL
785 // and the other without:
786 // Group one:
787 // 12345 => TYPE_INTEGER
788 // 1.2345 => TYPE_FLOAT
789 // inf => TYPE_IDENTIFIER
790 // TYPE_INTEGER => TYPE_IDENTIFIER
791 // Group two:
792 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
793 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
794 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
795 // As we can see, the field value consists of an optional '-' and one of
796 // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
797 bool has_minus = TryConsume("-");
798 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
799 !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
800 !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
801 return false;
802 }
803 // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
804 // value while other combinations all generate valid values.
805 // We check if the value of this combination is valid here.
806 // TYPE_IDENTIFIER after a '-' should be one of the float values listed
807 // below:
808 // inf, inff, infinity, nan
809 if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
810 string text = tokenizer_.current().text;
811 LowerString(&text);
812 if (text != "inf" &&
813 text != "infinity" &&
814 text != "nan") {
815 ReportError("Invalid float number: " + text);
816 return false;
817 }
818 }
819 tokenizer_.Next();
820 return true;
821 }
822
823 // Returns true if the current token's text is equal to that specified.
LookingAt(const string & text)824 bool LookingAt(const string& text) {
825 return tokenizer_.current().text == text;
826 }
827
828 // Returns true if the current token's type is equal to that specified.
LookingAtType(io::Tokenizer::TokenType token_type)829 bool LookingAtType(io::Tokenizer::TokenType token_type) {
830 return tokenizer_.current().type == token_type;
831 }
832
833 // Consumes an identifier and saves its value in the identifier parameter.
834 // Returns false if the token is not of type IDENTFIER.
ConsumeIdentifier(string * identifier)835 bool ConsumeIdentifier(string* identifier) {
836 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
837 *identifier = tokenizer_.current().text;
838 tokenizer_.Next();
839 return true;
840 }
841
842 // If allow_field_numer_ or allow_unknown_field_ is true, we should able
843 // to parse integer identifiers.
844 if ((allow_field_number_ || allow_unknown_field_)
845 && LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
846 *identifier = tokenizer_.current().text;
847 tokenizer_.Next();
848 return true;
849 }
850
851 ReportError("Expected identifier, got: " + tokenizer_.current().text);
852 return false;
853 }
854
855 // Consume a string of form "<id1>.<id2>....<idN>".
ConsumeFullTypeName(string * name)856 bool ConsumeFullTypeName(string* name) {
857 DO(ConsumeIdentifier(name));
858 while (TryConsume(".")) {
859 string part;
860 DO(ConsumeIdentifier(&part));
861 *name += ".";
862 *name += part;
863 }
864 return true;
865 }
866
867 // Consumes a string and saves its value in the text parameter.
868 // Returns false if the token is not of type STRING.
ConsumeString(string * text)869 bool ConsumeString(string* text) {
870 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
871 ReportError("Expected string, got: " + tokenizer_.current().text);
872 return false;
873 }
874
875 text->clear();
876 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
877 io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
878
879 tokenizer_.Next();
880 }
881
882 return true;
883 }
884
885 // Consumes a uint64 and saves its value in the value parameter.
886 // Returns false if the token is not of type INTEGER.
ConsumeUnsignedInteger(uint64 * value,uint64 max_value)887 bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
888 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
889 ReportError("Expected integer, got: " + tokenizer_.current().text);
890 return false;
891 }
892
893 if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
894 max_value, value)) {
895 ReportError("Integer out of range (" + tokenizer_.current().text + ")");
896 return false;
897 }
898
899 tokenizer_.Next();
900 return true;
901 }
902
903 // Consumes an int64 and saves its value in the value parameter.
904 // Note that since the tokenizer does not support negative numbers,
905 // we actually may consume an additional token (for the minus sign) in this
906 // method. Returns false if the token is not an integer
907 // (signed or otherwise).
ConsumeSignedInteger(int64 * value,uint64 max_value)908 bool ConsumeSignedInteger(int64* value, uint64 max_value) {
909 bool negative = false;
910
911 if (TryConsume("-")) {
912 negative = true;
913 // Two's complement always allows one more negative integer than
914 // positive.
915 ++max_value;
916 }
917
918 uint64 unsigned_value;
919
920 DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
921
922 if (negative) {
923 if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) {
924 *value = kint64min;
925 } else {
926 *value = -static_cast<int64>(unsigned_value);
927 }
928 } else {
929 *value = static_cast<int64>(unsigned_value);
930 }
931
932 return true;
933 }
934
935 // Consumes a uint64 and saves its value in the value parameter.
936 // Accepts decimal numbers only, rejects hex or oct numbers.
ConsumeUnsignedDecimalInteger(uint64 * value,uint64 max_value)937 bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) {
938 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
939 ReportError("Expected integer, got: " + tokenizer_.current().text);
940 return false;
941 }
942
943 const string& text = tokenizer_.current().text;
944 if (IsHexNumber(text) || IsOctNumber(text)) {
945 ReportError("Expect a decimal number, got: " + text);
946 return false;
947 }
948
949 if (!io::Tokenizer::ParseInteger(text, max_value, value)) {
950 ReportError("Integer out of range (" + text + ")");
951 return false;
952 }
953
954 tokenizer_.Next();
955 return true;
956 }
957
958 // Consumes a double and saves its value in the value parameter.
959 // Note that since the tokenizer does not support negative numbers,
960 // we actually may consume an additional token (for the minus sign) in this
961 // method. Returns false if the token is not a double
962 // (signed or otherwise).
ConsumeDouble(double * value)963 bool ConsumeDouble(double* value) {
964 bool negative = false;
965
966 if (TryConsume("-")) {
967 negative = true;
968 }
969
970 // A double can actually be an integer, according to the tokenizer.
971 // Therefore, we must check both cases here.
972 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
973 // We have found an integer value for the double.
974 uint64 integer_value;
975 DO(ConsumeUnsignedDecimalInteger(&integer_value, kuint64max));
976
977 *value = static_cast<double>(integer_value);
978 } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
979 // We have found a float value for the double.
980 *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
981
982 // Mark the current token as consumed.
983 tokenizer_.Next();
984 } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
985 string text = tokenizer_.current().text;
986 LowerString(&text);
987 if (text == "inf" ||
988 text == "infinity") {
989 *value = std::numeric_limits<double>::infinity();
990 tokenizer_.Next();
991 } else if (text == "nan") {
992 *value = std::numeric_limits<double>::quiet_NaN();
993 tokenizer_.Next();
994 } else {
995 ReportError("Expected double, got: " + text);
996 return false;
997 }
998 } else {
999 ReportError("Expected double, got: " + tokenizer_.current().text);
1000 return false;
1001 }
1002
1003 if (negative) {
1004 *value = -*value;
1005 }
1006
1007 return true;
1008 }
1009
1010 // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name"
1011 // or "type.googleprod.com/full.type.Name"
ConsumeAnyTypeUrl(string * full_type_name,string * prefix)1012 bool ConsumeAnyTypeUrl(string* full_type_name, string* prefix) {
1013 // TODO(saito) Extend Consume() to consume multiple tokens at once, so that
1014 // this code can be written as just DO(Consume(kGoogleApisTypePrefix)).
1015 string url1, url2, url3;
1016 DO(ConsumeIdentifier(&url1)); // type
1017 DO(Consume("."));
1018 DO(ConsumeIdentifier(&url2)); // googleapis
1019 DO(Consume("."));
1020 DO(ConsumeIdentifier(&url3)); // com
1021 DO(Consume("/"));
1022 DO(ConsumeFullTypeName(full_type_name));
1023
1024 *prefix = url1 + "." + url2 + "." + url3 + "/";
1025 if (*prefix != internal::kTypeGoogleApisComPrefix &&
1026 *prefix != internal::kTypeGoogleProdComPrefix) {
1027 ReportError("TextFormat::Parser for Any supports only "
1028 "type.googleapis.com and type.googleprod.com, "
1029 "but found \"" + *prefix + "\"");
1030 return false;
1031 }
1032 return true;
1033 }
1034
1035 // A helper function for reconstructing Any::value. Consumes a text of
1036 // full_type_name, then serializes it into serialized_value. "pool" is used to
1037 // look up and create a temporary object with full_type_name.
ConsumeAnyValue(const string & full_type_name,const DescriptorPool * pool,string * serialized_value)1038 bool ConsumeAnyValue(const string& full_type_name, const DescriptorPool* pool,
1039 string* serialized_value) {
1040 const Descriptor* value_descriptor =
1041 pool->FindMessageTypeByName(full_type_name);
1042 if (value_descriptor == NULL) {
1043 ReportError("Could not find type \"" + full_type_name +
1044 "\" stored in google.protobuf.Any.");
1045 return false;
1046 }
1047 DynamicMessageFactory factory;
1048 const Message* value_prototype = factory.GetPrototype(value_descriptor);
1049 if (value_prototype == NULL) {
1050 return false;
1051 }
1052 google::protobuf::scoped_ptr<Message> value(value_prototype->New());
1053 string sub_delimiter;
1054 DO(ConsumeMessageDelimiter(&sub_delimiter));
1055 DO(ConsumeMessage(value.get(), sub_delimiter));
1056
1057 if (allow_partial_) {
1058 value->AppendPartialToString(serialized_value);
1059 } else {
1060 if (!value->IsInitialized()) {
1061 ReportError(
1062 "Value of type \"" + full_type_name +
1063 "\" stored in google.protobuf.Any has missing required fields");
1064 return false;
1065 }
1066 value->AppendToString(serialized_value);
1067 }
1068 return true;
1069 }
1070
1071 // Consumes a token and confirms that it matches that specified in the
1072 // value parameter. Returns false if the token found does not match that
1073 // which was specified.
Consume(const string & value)1074 bool Consume(const string& value) {
1075 const string& current_value = tokenizer_.current().text;
1076
1077 if (current_value != value) {
1078 ReportError("Expected \"" + value + "\", found \"" + current_value
1079 + "\".");
1080 return false;
1081 }
1082
1083 tokenizer_.Next();
1084
1085 return true;
1086 }
1087
1088 // Attempts to consume the supplied value. Returns false if a the
1089 // token found does not match the value specified.
TryConsume(const string & value)1090 bool TryConsume(const string& value) {
1091 if (tokenizer_.current().text == value) {
1092 tokenizer_.Next();
1093 return true;
1094 } else {
1095 return false;
1096 }
1097 }
1098
1099 // An internal instance of the Tokenizer's error collector, used to
1100 // collect any base-level parse errors and feed them to the ParserImpl.
1101 class ParserErrorCollector : public io::ErrorCollector {
1102 public:
ParserErrorCollector(TextFormat::Parser::ParserImpl * parser)1103 explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
1104 parser_(parser) { }
1105
~ParserErrorCollector()1106 virtual ~ParserErrorCollector() { }
1107
AddError(int line,int column,const string & message)1108 virtual void AddError(int line, int column, const string& message) {
1109 parser_->ReportError(line, column, message);
1110 }
1111
AddWarning(int line,int column,const string & message)1112 virtual void AddWarning(int line, int column, const string& message) {
1113 parser_->ReportWarning(line, column, message);
1114 }
1115
1116 private:
1117 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
1118 TextFormat::Parser::ParserImpl* parser_;
1119 };
1120
1121 io::ErrorCollector* error_collector_;
1122 TextFormat::Finder* finder_;
1123 ParseInfoTree* parse_info_tree_;
1124 ParserErrorCollector tokenizer_error_collector_;
1125 io::Tokenizer tokenizer_;
1126 const Descriptor* root_message_type_;
1127 SingularOverwritePolicy singular_overwrite_policy_;
1128 const bool allow_case_insensitive_field_;
1129 const bool allow_unknown_field_;
1130 const bool allow_unknown_enum_;
1131 const bool allow_field_number_;
1132 const bool allow_partial_;
1133 bool had_errors_;
1134 };
1135
1136 #undef DO
1137
1138 // ===========================================================================
1139 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
1140 // from the Printer found in //google/protobuf/io/printer.h
1141 class TextFormat::Printer::TextGenerator {
1142 public:
TextGenerator(io::ZeroCopyOutputStream * output,int initial_indent_level)1143 explicit TextGenerator(io::ZeroCopyOutputStream* output,
1144 int initial_indent_level)
1145 : output_(output),
1146 buffer_(NULL),
1147 buffer_size_(0),
1148 at_start_of_line_(true),
1149 failed_(false),
1150 indent_(""),
1151 initial_indent_level_(initial_indent_level) {
1152 indent_.resize(initial_indent_level_ * 2, ' ');
1153 }
1154
~TextGenerator()1155 ~TextGenerator() {
1156 // Only BackUp() if we're sure we've successfully called Next() at least
1157 // once.
1158 if (!failed_ && buffer_size_ > 0) {
1159 output_->BackUp(buffer_size_);
1160 }
1161 }
1162
1163 // Indent text by two spaces. After calling Indent(), two spaces will be
1164 // inserted at the beginning of each line of text. Indent() may be called
1165 // multiple times to produce deeper indents.
Indent()1166 void Indent() {
1167 indent_ += " ";
1168 }
1169
1170 // Reduces the current indent level by two spaces, or crashes if the indent
1171 // level is zero.
Outdent()1172 void Outdent() {
1173 if (indent_.empty() ||
1174 indent_.size() < initial_indent_level_ * 2) {
1175 GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
1176 return;
1177 }
1178
1179 indent_.resize(indent_.size() - 2);
1180 }
1181
1182 // Print text to the output stream.
Print(const string & str)1183 void Print(const string& str) {
1184 Print(str.data(), str.size());
1185 }
1186
1187 // Print text to the output stream.
Print(const char * text)1188 void Print(const char* text) {
1189 Print(text, strlen(text));
1190 }
1191
1192 // Print text to the output stream.
Print(const char * text,size_t size)1193 void Print(const char* text, size_t size) {
1194 size_t pos = 0; // The number of bytes we've written so far.
1195
1196 for (size_t i = 0; i < size; i++) {
1197 if (text[i] == '\n') {
1198 // Saw newline. If there is more text, we may need to insert an indent
1199 // here. So, write what we have so far, including the '\n'.
1200 Write(text + pos, i - pos + 1);
1201 pos = i + 1;
1202
1203 // Setting this true will cause the next Write() to insert an indent
1204 // first.
1205 at_start_of_line_ = true;
1206 }
1207 }
1208
1209 // Write the rest.
1210 Write(text + pos, size - pos);
1211 }
1212
1213 // True if any write to the underlying stream failed. (We don't just
1214 // crash in this case because this is an I/O failure, not a programming
1215 // error.)
failed() const1216 bool failed() const { return failed_; }
1217
1218 private:
1219 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
1220
Write(const char * data,size_t size)1221 void Write(const char* data, size_t size) {
1222 if (failed_) return;
1223 if (size == 0) return;
1224
1225 if (at_start_of_line_) {
1226 // Insert an indent.
1227 at_start_of_line_ = false;
1228 Write(indent_.data(), indent_.size());
1229 if (failed_) return;
1230 }
1231
1232 while (size > buffer_size_) {
1233 // Data exceeds space in the buffer. Copy what we can and request a
1234 // new buffer.
1235 memcpy(buffer_, data, buffer_size_);
1236 data += buffer_size_;
1237 size -= buffer_size_;
1238 void* void_buffer;
1239 failed_ = !output_->Next(&void_buffer, &buffer_size_);
1240 if (failed_) return;
1241 buffer_ = reinterpret_cast<char*>(void_buffer);
1242 }
1243
1244 // Buffer is big enough to receive the data; copy it.
1245 memcpy(buffer_, data, size);
1246 buffer_ += size;
1247 buffer_size_ -= size;
1248 }
1249
1250 io::ZeroCopyOutputStream* const output_;
1251 char* buffer_;
1252 int buffer_size_;
1253 bool at_start_of_line_;
1254 bool failed_;
1255
1256 string indent_;
1257 int initial_indent_level_;
1258 };
1259
1260 // ===========================================================================
1261
~Finder()1262 TextFormat::Finder::~Finder() {
1263 }
1264
Parser()1265 TextFormat::Parser::Parser()
1266 : error_collector_(NULL),
1267 finder_(NULL),
1268 parse_info_tree_(NULL),
1269 allow_partial_(false),
1270 allow_case_insensitive_field_(false),
1271 allow_unknown_field_(false),
1272 allow_unknown_enum_(false),
1273 allow_field_number_(false),
1274 allow_relaxed_whitespace_(false),
1275 allow_singular_overwrites_(false) {
1276 }
1277
~Parser()1278 TextFormat::Parser::~Parser() {}
1279
Parse(io::ZeroCopyInputStream * input,Message * output)1280 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
1281 Message* output) {
1282 output->Clear();
1283
1284 ParserImpl::SingularOverwritePolicy overwrites_policy =
1285 allow_singular_overwrites_
1286 ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
1287 : ParserImpl::FORBID_SINGULAR_OVERWRITES;
1288
1289 ParserImpl parser(output->GetDescriptor(), input, error_collector_,
1290 finder_, parse_info_tree_,
1291 overwrites_policy,
1292 allow_case_insensitive_field_, allow_unknown_field_,
1293 allow_unknown_enum_, allow_field_number_,
1294 allow_relaxed_whitespace_, allow_partial_);
1295 return MergeUsingImpl(input, output, &parser);
1296 }
1297
ParseFromString(const string & input,Message * output)1298 bool TextFormat::Parser::ParseFromString(const string& input,
1299 Message* output) {
1300 io::ArrayInputStream input_stream(input.data(), input.size());
1301 return Parse(&input_stream, output);
1302 }
1303
Merge(io::ZeroCopyInputStream * input,Message * output)1304 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
1305 Message* output) {
1306 ParserImpl parser(output->GetDescriptor(), input, error_collector_,
1307 finder_, parse_info_tree_,
1308 ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1309 allow_case_insensitive_field_, allow_unknown_field_,
1310 allow_unknown_enum_, allow_field_number_,
1311 allow_relaxed_whitespace_, allow_partial_);
1312 return MergeUsingImpl(input, output, &parser);
1313 }
1314
MergeFromString(const string & input,Message * output)1315 bool TextFormat::Parser::MergeFromString(const string& input,
1316 Message* output) {
1317 io::ArrayInputStream input_stream(input.data(), input.size());
1318 return Merge(&input_stream, output);
1319 }
1320
MergeUsingImpl(io::ZeroCopyInputStream *,Message * output,ParserImpl * parser_impl)1321 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
1322 Message* output,
1323 ParserImpl* parser_impl) {
1324 if (!parser_impl->Parse(output)) return false;
1325 if (!allow_partial_ && !output->IsInitialized()) {
1326 vector<string> missing_fields;
1327 output->FindInitializationErrors(&missing_fields);
1328 parser_impl->ReportError(-1, 0, "Message missing required fields: " +
1329 Join(missing_fields, ", "));
1330 return false;
1331 }
1332 return true;
1333 }
1334
ParseFieldValueFromString(const string & input,const FieldDescriptor * field,Message * output)1335 bool TextFormat::Parser::ParseFieldValueFromString(
1336 const string& input,
1337 const FieldDescriptor* field,
1338 Message* output) {
1339 io::ArrayInputStream input_stream(input.data(), input.size());
1340 ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
1341 finder_, parse_info_tree_,
1342 ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1343 allow_case_insensitive_field_, allow_unknown_field_,
1344 allow_unknown_enum_, allow_field_number_,
1345 allow_relaxed_whitespace_, allow_partial_);
1346 return parser.ParseField(field, output);
1347 }
1348
Parse(io::ZeroCopyInputStream * input,Message * output)1349 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1350 Message* output) {
1351 return Parser().Parse(input, output);
1352 }
1353
Merge(io::ZeroCopyInputStream * input,Message * output)1354 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1355 Message* output) {
1356 return Parser().Merge(input, output);
1357 }
1358
ParseFromString(const string & input,Message * output)1359 /* static */ bool TextFormat::ParseFromString(const string& input,
1360 Message* output) {
1361 return Parser().ParseFromString(input, output);
1362 }
1363
MergeFromString(const string & input,Message * output)1364 /* static */ bool TextFormat::MergeFromString(const string& input,
1365 Message* output) {
1366 return Parser().MergeFromString(input, output);
1367 }
1368
1369 // ===========================================================================
1370
1371 // The default implementation for FieldValuePrinter. The base class just
1372 // does simple formatting. That way, deriving classes could decide to fallback
1373 // to that behavior.
FieldValuePrinter()1374 TextFormat::FieldValuePrinter::FieldValuePrinter() {}
~FieldValuePrinter()1375 TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
PrintBool(bool val) const1376 string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
1377 return val ? "true" : "false";
1378 }
PrintInt32(int32 val) const1379 string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const {
1380 return SimpleItoa(val);
1381 }
PrintUInt32(uint32 val) const1382 string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const {
1383 return SimpleItoa(val);
1384 }
PrintInt64(int64 val) const1385 string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const {
1386 return SimpleItoa(val);
1387 }
PrintUInt64(uint64 val) const1388 string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const {
1389 return SimpleItoa(val);
1390 }
PrintFloat(float val) const1391 string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
1392 return SimpleFtoa(val);
1393 }
PrintDouble(double val) const1394 string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
1395 return SimpleDtoa(val);
1396 }
PrintString(const string & val) const1397 string TextFormat::FieldValuePrinter::PrintString(const string& val) const {
1398 string printed("\"");
1399 CEscapeAndAppend(val, &printed);
1400 printed.push_back('\"');
1401 return printed;
1402 }
PrintBytes(const string & val) const1403 string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const {
1404 return PrintString(val);
1405 }
PrintEnum(int32 val,const string & name) const1406 string TextFormat::FieldValuePrinter::PrintEnum(int32 val,
1407 const string& name) const {
1408 return name;
1409 }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field) const1410 string TextFormat::FieldValuePrinter::PrintFieldName(
1411 const Message& message,
1412 const Reflection* reflection,
1413 const FieldDescriptor* field) const {
1414 if (field->is_extension()) {
1415 // We special-case MessageSet elements for compatibility with proto1.
1416 if (field->containing_type()->options().message_set_wire_format()
1417 && field->type() == FieldDescriptor::TYPE_MESSAGE
1418 && field->is_optional()
1419 && field->extension_scope() == field->message_type()) {
1420 return StrCat("[", field->message_type()->full_name(), "]");
1421 } else {
1422 return StrCat("[", field->full_name(), "]");
1423 }
1424 } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
1425 // Groups must be serialized with their original capitalization.
1426 return field->message_type()->name();
1427 } else {
1428 return field->name();
1429 }
1430 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode) const1431 string TextFormat::FieldValuePrinter::PrintMessageStart(
1432 const Message& message,
1433 int field_index,
1434 int field_count,
1435 bool single_line_mode) const {
1436 return single_line_mode ? " { " : " {\n";
1437 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode) const1438 string TextFormat::FieldValuePrinter::PrintMessageEnd(
1439 const Message& message,
1440 int field_index,
1441 int field_count,
1442 bool single_line_mode) const {
1443 return single_line_mode ? "} " : "}\n";
1444 }
1445
1446 namespace {
1447 // Our own specialization: for UTF8 escaped strings.
1448 class FieldValuePrinterUtf8Escaping : public TextFormat::FieldValuePrinter {
1449 public:
PrintString(const string & val) const1450 virtual string PrintString(const string& val) const {
1451 return StrCat("\"", strings::Utf8SafeCEscape(val), "\"");
1452 }
PrintBytes(const string & val) const1453 virtual string PrintBytes(const string& val) const {
1454 return TextFormat::FieldValuePrinter::PrintString(val);
1455 }
1456 };
1457
1458 } // namespace
1459
Printer()1460 TextFormat::Printer::Printer()
1461 : initial_indent_level_(0),
1462 single_line_mode_(false),
1463 use_field_number_(false),
1464 use_short_repeated_primitives_(false),
1465 hide_unknown_fields_(false),
1466 print_message_fields_in_index_order_(false),
1467 expand_any_(false),
1468 truncate_string_field_longer_than_(0LL) {
1469 SetUseUtf8StringEscaping(false);
1470 }
1471
~Printer()1472 TextFormat::Printer::~Printer() {
1473 STLDeleteValues(&custom_printers_);
1474 }
1475
SetUseUtf8StringEscaping(bool as_utf8)1476 void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
1477 SetDefaultFieldValuePrinter(as_utf8
1478 ? new FieldValuePrinterUtf8Escaping()
1479 : new FieldValuePrinter());
1480 }
1481
SetDefaultFieldValuePrinter(const FieldValuePrinter * printer)1482 void TextFormat::Printer::SetDefaultFieldValuePrinter(
1483 const FieldValuePrinter* printer) {
1484 default_field_value_printer_.reset(printer);
1485 }
1486
RegisterFieldValuePrinter(const FieldDescriptor * field,const FieldValuePrinter * printer)1487 bool TextFormat::Printer::RegisterFieldValuePrinter(
1488 const FieldDescriptor* field,
1489 const FieldValuePrinter* printer) {
1490 return field != NULL && printer != NULL &&
1491 custom_printers_.insert(std::make_pair(field, printer)).second;
1492 }
1493
PrintToString(const Message & message,string * output) const1494 bool TextFormat::Printer::PrintToString(const Message& message,
1495 string* output) const {
1496 GOOGLE_DCHECK(output) << "output specified is NULL";
1497
1498 output->clear();
1499 io::StringOutputStream output_stream(output);
1500
1501 return Print(message, &output_stream);
1502 }
1503
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,string * output) const1504 bool TextFormat::Printer::PrintUnknownFieldsToString(
1505 const UnknownFieldSet& unknown_fields,
1506 string* output) const {
1507 GOOGLE_DCHECK(output) << "output specified is NULL";
1508
1509 output->clear();
1510 io::StringOutputStream output_stream(output);
1511 return PrintUnknownFields(unknown_fields, &output_stream);
1512 }
1513
Print(const Message & message,io::ZeroCopyOutputStream * output) const1514 bool TextFormat::Printer::Print(const Message& message,
1515 io::ZeroCopyOutputStream* output) const {
1516 TextGenerator generator(output, initial_indent_level_);
1517
1518 Print(message, generator);
1519
1520 // Output false if the generator failed internally.
1521 return !generator.failed();
1522 }
1523
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output) const1524 bool TextFormat::Printer::PrintUnknownFields(
1525 const UnknownFieldSet& unknown_fields,
1526 io::ZeroCopyOutputStream* output) const {
1527 TextGenerator generator(output, initial_indent_level_);
1528
1529 PrintUnknownFields(unknown_fields, generator);
1530
1531 // Output false if the generator failed internally.
1532 return !generator.failed();
1533 }
1534
1535 namespace {
1536 // Comparison functor for sorting FieldDescriptors by field index.
1537 struct FieldIndexSorter {
operator ()google::protobuf::__anon9839723e0311::FieldIndexSorter1538 bool operator()(const FieldDescriptor* left,
1539 const FieldDescriptor* right) const {
1540 return left->index() < right->index();
1541 }
1542 };
1543
1544 } // namespace
1545
PrintAny(const Message & message,TextGenerator & generator) const1546 bool TextFormat::Printer::PrintAny(const Message& message,
1547 TextGenerator& generator) const {
1548 const FieldDescriptor* type_url_field;
1549 const FieldDescriptor* value_field;
1550 if (!internal::GetAnyFieldDescriptors(message, &type_url_field,
1551 &value_field)) {
1552 return false;
1553 }
1554
1555 const Reflection* reflection = message.GetReflection();
1556
1557 // Extract the full type name from the type_url field.
1558 const string& type_url = reflection->GetString(message, type_url_field);
1559 string full_type_name;
1560 if (!internal::ParseAnyTypeUrl(type_url, &full_type_name)) {
1561 return false;
1562 }
1563
1564 // Print the "value" in text.
1565 const google::protobuf::Descriptor* value_descriptor =
1566 message.GetDescriptor()->file()->pool()->FindMessageTypeByName(
1567 full_type_name);
1568 if (value_descriptor == NULL) {
1569 GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found";
1570 return false;
1571 }
1572 DynamicMessageFactory factory;
1573 google::protobuf::scoped_ptr<google::protobuf::Message> value_message(
1574 factory.GetPrototype(value_descriptor)->New());
1575 string serialized_value = reflection->GetString(message, value_field);
1576 if (!value_message->ParseFromString(serialized_value)) {
1577 GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents";
1578 return false;
1579 }
1580 generator.Print(StrCat("[", type_url, "]"));
1581 const FieldValuePrinter* printer = FindWithDefault(
1582 custom_printers_, value_field, default_field_value_printer_.get());
1583 generator.Print(
1584 printer->PrintMessageStart(message, -1, 0, single_line_mode_));
1585 generator.Indent();
1586 Print(*value_message, generator);
1587 generator.Outdent();
1588 generator.Print(printer->PrintMessageEnd(message, -1, 0, single_line_mode_));
1589 return true;
1590 }
1591
Print(const Message & message,TextGenerator & generator) const1592 void TextFormat::Printer::Print(const Message& message,
1593 TextGenerator& generator) const {
1594 const Descriptor* descriptor = message.GetDescriptor();
1595 const Reflection* reflection = message.GetReflection();
1596 if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ &&
1597 PrintAny(message, generator)) {
1598 return;
1599 }
1600 vector<const FieldDescriptor*> fields;
1601 reflection->ListFields(message, &fields);
1602 if (print_message_fields_in_index_order_) {
1603 std::sort(fields.begin(), fields.end(), FieldIndexSorter());
1604 }
1605 for (int i = 0; i < fields.size(); i++) {
1606 PrintField(message, reflection, fields[i], generator);
1607 }
1608 if (!hide_unknown_fields_) {
1609 PrintUnknownFields(reflection->GetUnknownFields(message), generator);
1610 }
1611 }
1612
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,string * output) const1613 void TextFormat::Printer::PrintFieldValueToString(
1614 const Message& message,
1615 const FieldDescriptor* field,
1616 int index,
1617 string* output) const {
1618
1619 GOOGLE_DCHECK(output) << "output specified is NULL";
1620
1621 output->clear();
1622 io::StringOutputStream output_stream(output);
1623 TextGenerator generator(&output_stream, initial_indent_level_);
1624
1625 PrintFieldValue(message, message.GetReflection(), field, index, generator);
1626 }
1627
1628 class MapEntryMessageComparator {
1629 public:
MapEntryMessageComparator(const Descriptor * descriptor)1630 explicit MapEntryMessageComparator(const Descriptor* descriptor)
1631 : field_(descriptor->field(0)) {}
1632
operator ()(const Message * a,const Message * b)1633 bool operator()(const Message* a, const Message* b) {
1634 const Reflection* reflection = a->GetReflection();
1635 switch (field_->cpp_type()) {
1636 case FieldDescriptor::CPPTYPE_BOOL: {
1637 bool first = reflection->GetBool(*a, field_);
1638 bool second = reflection->GetBool(*b, field_);
1639 return first < second;
1640 }
1641 case FieldDescriptor::CPPTYPE_INT32: {
1642 int32 first = reflection->GetInt32(*a, field_);
1643 int32 second = reflection->GetInt32(*b, field_);
1644 return first < second;
1645 }
1646 case FieldDescriptor::CPPTYPE_INT64: {
1647 int64 first = reflection->GetInt64(*a, field_);
1648 int64 second = reflection->GetInt64(*b, field_);
1649 return first < second;
1650 }
1651 case FieldDescriptor::CPPTYPE_UINT32: {
1652 uint32 first = reflection->GetUInt32(*a, field_);
1653 uint32 second = reflection->GetUInt32(*b, field_);
1654 return first < second;
1655 }
1656 case FieldDescriptor::CPPTYPE_UINT64: {
1657 uint64 first = reflection->GetUInt64(*a, field_);
1658 uint64 second = reflection->GetUInt64(*b, field_);
1659 return first < second;
1660 }
1661 case FieldDescriptor::CPPTYPE_STRING: {
1662 string first = reflection->GetString(*a, field_);
1663 string second = reflection->GetString(*b, field_);
1664 return first < second;
1665 }
1666 default:
1667 GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
1668 return true;
1669 }
1670 }
1671
1672 private:
1673 const FieldDescriptor* field_;
1674 };
1675
PrintField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1676 void TextFormat::Printer::PrintField(const Message& message,
1677 const Reflection* reflection,
1678 const FieldDescriptor* field,
1679 TextGenerator& generator) const {
1680 if (use_short_repeated_primitives_ &&
1681 field->is_repeated() &&
1682 field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
1683 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
1684 PrintShortRepeatedField(message, reflection, field, generator);
1685 return;
1686 }
1687
1688 int count = 0;
1689
1690 if (field->is_repeated()) {
1691 count = reflection->FieldSize(message, field);
1692 } else if (reflection->HasField(message, field)) {
1693 count = 1;
1694 }
1695
1696 std::vector<const Message*> sorted_map_field;
1697 if (field->is_map()) {
1698 const RepeatedPtrField<Message>& map_field =
1699 reflection->GetRepeatedPtrField<Message>(message, field);
1700 for (RepeatedPtrField<Message>::const_pointer_iterator it =
1701 map_field.pointer_begin();
1702 it != map_field.pointer_end(); ++it) {
1703 sorted_map_field.push_back(*it);
1704 }
1705
1706 MapEntryMessageComparator comparator(field->message_type());
1707 std::stable_sort(sorted_map_field.begin(), sorted_map_field.end(),
1708 comparator);
1709 }
1710
1711 for (int j = 0; j < count; ++j) {
1712 const int field_index = field->is_repeated() ? j : -1;
1713
1714 PrintFieldName(message, reflection, field, generator);
1715
1716 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1717 const FieldValuePrinter* printer = FindWithDefault(
1718 custom_printers_, field, default_field_value_printer_.get());
1719 const Message& sub_message =
1720 field->is_repeated()
1721 ? (field->is_map()
1722 ? *sorted_map_field[j]
1723 : reflection->GetRepeatedMessage(message, field, j))
1724 : reflection->GetMessage(message, field);
1725 generator.Print(
1726 printer->PrintMessageStart(
1727 sub_message, field_index, count, single_line_mode_));
1728 generator.Indent();
1729 Print(sub_message, generator);
1730 generator.Outdent();
1731 generator.Print(
1732 printer->PrintMessageEnd(
1733 sub_message, field_index, count, single_line_mode_));
1734 } else {
1735 generator.Print(": ");
1736 // Write the field value.
1737 PrintFieldValue(message, reflection, field, field_index, generator);
1738 if (single_line_mode_) {
1739 generator.Print(" ");
1740 } else {
1741 generator.Print("\n");
1742 }
1743 }
1744 }
1745 }
1746
PrintShortRepeatedField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1747 void TextFormat::Printer::PrintShortRepeatedField(
1748 const Message& message,
1749 const Reflection* reflection,
1750 const FieldDescriptor* field,
1751 TextGenerator& generator) const {
1752 // Print primitive repeated field in short form.
1753 PrintFieldName(message, reflection, field, generator);
1754
1755 int size = reflection->FieldSize(message, field);
1756 generator.Print(": [");
1757 for (int i = 0; i < size; i++) {
1758 if (i > 0) generator.Print(", ");
1759 PrintFieldValue(message, reflection, field, i, generator);
1760 }
1761 if (single_line_mode_) {
1762 generator.Print("] ");
1763 } else {
1764 generator.Print("]\n");
1765 }
1766 }
1767
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1768 void TextFormat::Printer::PrintFieldName(const Message& message,
1769 const Reflection* reflection,
1770 const FieldDescriptor* field,
1771 TextGenerator& generator) const {
1772 // if use_field_number_ is true, prints field number instead
1773 // of field name.
1774 if (use_field_number_) {
1775 generator.Print(SimpleItoa(field->number()));
1776 return;
1777 }
1778
1779 const FieldValuePrinter* printer = FindWithDefault(
1780 custom_printers_, field, default_field_value_printer_.get());
1781 generator.Print(printer->PrintFieldName(message, reflection, field));
1782 }
1783
PrintFieldValue(const Message & message,const Reflection * reflection,const FieldDescriptor * field,int index,TextGenerator & generator) const1784 void TextFormat::Printer::PrintFieldValue(
1785 const Message& message,
1786 const Reflection* reflection,
1787 const FieldDescriptor* field,
1788 int index,
1789 TextGenerator& generator) const {
1790 GOOGLE_DCHECK(field->is_repeated() || (index == -1))
1791 << "Index must be -1 for non-repeated fields";
1792
1793 const FieldValuePrinter* printer
1794 = FindWithDefault(custom_printers_, field,
1795 default_field_value_printer_.get());
1796
1797 switch (field->cpp_type()) {
1798 #define OUTPUT_FIELD(CPPTYPE, METHOD) \
1799 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
1800 generator.Print(printer->Print##METHOD(field->is_repeated() \
1801 ? reflection->GetRepeated##METHOD(message, field, index) \
1802 : reflection->Get##METHOD(message, field))); \
1803 break
1804
1805 OUTPUT_FIELD( INT32, Int32);
1806 OUTPUT_FIELD( INT64, Int64);
1807 OUTPUT_FIELD(UINT32, UInt32);
1808 OUTPUT_FIELD(UINT64, UInt64);
1809 OUTPUT_FIELD( FLOAT, Float);
1810 OUTPUT_FIELD(DOUBLE, Double);
1811 OUTPUT_FIELD( BOOL, Bool);
1812 #undef OUTPUT_FIELD
1813
1814 case FieldDescriptor::CPPTYPE_STRING: {
1815 string scratch;
1816 const string& value = field->is_repeated()
1817 ? reflection->GetRepeatedStringReference(
1818 message, field, index, &scratch)
1819 : reflection->GetStringReference(message, field, &scratch);
1820 const string* value_to_print = &value;
1821 string truncated_value;
1822 if (truncate_string_field_longer_than_ > 0 &&
1823 truncate_string_field_longer_than_ < value.size()) {
1824 truncated_value = value.substr(0, truncate_string_field_longer_than_) +
1825 "...<truncated>...";
1826 value_to_print = &truncated_value;
1827 }
1828 if (field->type() == FieldDescriptor::TYPE_STRING) {
1829 generator.Print(printer->PrintString(*value_to_print));
1830 } else {
1831 GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
1832 generator.Print(printer->PrintBytes(*value_to_print));
1833 }
1834 break;
1835 }
1836
1837 case FieldDescriptor::CPPTYPE_ENUM: {
1838 int enum_value = field->is_repeated()
1839 ? reflection->GetRepeatedEnumValue(message, field, index)
1840 : reflection->GetEnumValue(message, field);
1841 const EnumValueDescriptor* enum_desc =
1842 field->enum_type()->FindValueByNumber(enum_value);
1843 if (enum_desc != NULL) {
1844 generator.Print(printer->PrintEnum(enum_value, enum_desc->name()));
1845 } else {
1846 // Ordinarily, enum_desc should not be null, because proto2 has the
1847 // invariant that set enum field values must be in-range, but with the
1848 // new integer-based API for enums (or the RepeatedField<int> loophole),
1849 // it is possible for the user to force an unknown integer value. So we
1850 // simply use the integer value itself as the enum value name in this
1851 // case.
1852 generator.Print(printer->PrintEnum(enum_value,
1853 StringPrintf("%d", enum_value)));
1854 }
1855 break;
1856 }
1857
1858 case FieldDescriptor::CPPTYPE_MESSAGE:
1859 Print(field->is_repeated()
1860 ? reflection->GetRepeatedMessage(message, field, index)
1861 : reflection->GetMessage(message, field),
1862 generator);
1863 break;
1864 }
1865 }
1866
Print(const Message & message,io::ZeroCopyOutputStream * output)1867 /* static */ bool TextFormat::Print(const Message& message,
1868 io::ZeroCopyOutputStream* output) {
1869 return Printer().Print(message, output);
1870 }
1871
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output)1872 /* static */ bool TextFormat::PrintUnknownFields(
1873 const UnknownFieldSet& unknown_fields,
1874 io::ZeroCopyOutputStream* output) {
1875 return Printer().PrintUnknownFields(unknown_fields, output);
1876 }
1877
PrintToString(const Message & message,string * output)1878 /* static */ bool TextFormat::PrintToString(
1879 const Message& message, string* output) {
1880 return Printer().PrintToString(message, output);
1881 }
1882
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,string * output)1883 /* static */ bool TextFormat::PrintUnknownFieldsToString(
1884 const UnknownFieldSet& unknown_fields, string* output) {
1885 return Printer().PrintUnknownFieldsToString(unknown_fields, output);
1886 }
1887
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,string * output)1888 /* static */ void TextFormat::PrintFieldValueToString(
1889 const Message& message,
1890 const FieldDescriptor* field,
1891 int index,
1892 string* output) {
1893 return Printer().PrintFieldValueToString(message, field, index, output);
1894 }
1895
ParseFieldValueFromString(const string & input,const FieldDescriptor * field,Message * message)1896 /* static */ bool TextFormat::ParseFieldValueFromString(
1897 const string& input,
1898 const FieldDescriptor* field,
1899 Message* message) {
1900 return Parser().ParseFieldValueFromString(input, field, message);
1901 }
1902
1903 // Prints an integer as hex with a fixed number of digits dependent on the
1904 // integer type.
1905 template<typename IntType>
PaddedHex(IntType value)1906 static string PaddedHex(IntType value) {
1907 string result;
1908 result.reserve(sizeof(value) * 2);
1909 for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
1910 result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
1911 }
1912 return result;
1913 }
1914
PrintUnknownFields(const UnknownFieldSet & unknown_fields,TextGenerator & generator) const1915 void TextFormat::Printer::PrintUnknownFields(
1916 const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
1917 for (int i = 0; i < unknown_fields.field_count(); i++) {
1918 const UnknownField& field = unknown_fields.field(i);
1919 string field_number = SimpleItoa(field.number());
1920
1921 switch (field.type()) {
1922 case UnknownField::TYPE_VARINT:
1923 generator.Print(field_number);
1924 generator.Print(": ");
1925 generator.Print(SimpleItoa(field.varint()));
1926 if (single_line_mode_) {
1927 generator.Print(" ");
1928 } else {
1929 generator.Print("\n");
1930 }
1931 break;
1932 case UnknownField::TYPE_FIXED32: {
1933 generator.Print(field_number);
1934 generator.Print(": 0x");
1935 generator.Print(
1936 StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8)));
1937 if (single_line_mode_) {
1938 generator.Print(" ");
1939 } else {
1940 generator.Print("\n");
1941 }
1942 break;
1943 }
1944 case UnknownField::TYPE_FIXED64: {
1945 generator.Print(field_number);
1946 generator.Print(": 0x");
1947 generator.Print(
1948 StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16)));
1949 if (single_line_mode_) {
1950 generator.Print(" ");
1951 } else {
1952 generator.Print("\n");
1953 }
1954 break;
1955 }
1956 case UnknownField::TYPE_LENGTH_DELIMITED: {
1957 generator.Print(field_number);
1958 const string& value = field.length_delimited();
1959 UnknownFieldSet embedded_unknown_fields;
1960 if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
1961 // This field is parseable as a Message.
1962 // So it is probably an embedded message.
1963 if (single_line_mode_) {
1964 generator.Print(" { ");
1965 } else {
1966 generator.Print(" {\n");
1967 generator.Indent();
1968 }
1969 PrintUnknownFields(embedded_unknown_fields, generator);
1970 if (single_line_mode_) {
1971 generator.Print("} ");
1972 } else {
1973 generator.Outdent();
1974 generator.Print("}\n");
1975 }
1976 } else {
1977 // This field is not parseable as a Message.
1978 // So it is probably just a plain string.
1979 string printed(": \"");
1980 CEscapeAndAppend(value, &printed);
1981 printed.append(single_line_mode_ ? "\" " : "\"\n");
1982 generator.Print(printed);
1983 }
1984 break;
1985 }
1986 case UnknownField::TYPE_GROUP:
1987 generator.Print(field_number);
1988 if (single_line_mode_) {
1989 generator.Print(" { ");
1990 } else {
1991 generator.Print(" {\n");
1992 generator.Indent();
1993 }
1994 PrintUnknownFields(field.group(), generator);
1995 if (single_line_mode_) {
1996 generator.Print("} ");
1997 } else {
1998 generator.Outdent();
1999 generator.Print("}\n");
2000 }
2001 break;
2002 }
2003 }
2004 }
2005
2006 } // namespace protobuf
2007 } // namespace google
2008