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 // Utilities for printing and parsing protocol messages in a human-readable,
36 // text-based format.
37
38 #ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
39 #define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
40
41 #include <map>
42 #include <memory>
43 #include <string>
44 #include <vector>
45
46 #include <google/protobuf/stubs/common.h>
47 #include <google/protobuf/descriptor.h>
48 #include <google/protobuf/message.h>
49 #include <google/protobuf/message_lite.h>
50 #include <google/protobuf/port.h>
51
52 #include <google/protobuf/port_def.inc>
53
54 #ifdef SWIG
55 #error "You cannot SWIG proto headers"
56 #endif
57
58 namespace google {
59 namespace protobuf {
60
61 namespace io {
62 class ErrorCollector; // tokenizer.h
63 }
64
65 // This class implements protocol buffer text format. Printing and parsing
66 // protocol messages in text format is useful for debugging and human editing
67 // of messages.
68 //
69 // This class is really a namespace that contains only static methods.
70 class PROTOBUF_EXPORT TextFormat {
71 public:
72 // Outputs a textual representation of the given message to the given
73 // output stream. Returns false if printing fails.
74 static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
75
76 // Print the fields in an UnknownFieldSet. They are printed by tag number
77 // only. Embedded messages are heuristically identified by attempting to
78 // parse them. Returns false if printing fails.
79 static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
80 io::ZeroCopyOutputStream* output);
81
82 // Like Print(), but outputs directly to a string.
83 // Note: output will be cleared prior to printing, and will be left empty
84 // even if printing fails. Returns false if printing fails.
85 static bool PrintToString(const Message& message, std::string* output);
86
87 // Like PrintUnknownFields(), but outputs directly to a string. Returns
88 // false if printing fails.
89 static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
90 std::string* output);
91
92 // Outputs a textual representation of the value of the field supplied on
93 // the message supplied. For non-repeated fields, an index of -1 must
94 // be supplied. Note that this method will print the default value for a
95 // field if it is not set.
96 static void PrintFieldValueToString(const Message& message,
97 const FieldDescriptor* field, int index,
98 std::string* output);
99
100 class PROTOBUF_EXPORT BaseTextGenerator {
101 public:
102 virtual ~BaseTextGenerator();
103
Indent()104 virtual void Indent() {}
Outdent()105 virtual void Outdent() {}
106 // Returns the current indentation size in characters.
GetCurrentIndentationSize()107 virtual size_t GetCurrentIndentationSize() const { return 0; }
108
109 // Print text to the output stream.
110 virtual void Print(const char* text, size_t size) = 0;
111
PrintString(const std::string & str)112 void PrintString(const std::string& str) { Print(str.data(), str.size()); }
113
114 template <size_t n>
PrintLiteral(const char (& text)[n])115 void PrintLiteral(const char (&text)[n]) {
116 Print(text, n - 1); // n includes the terminating zero character.
117 }
118 };
119
120 // The default printer that converts scalar values from fields into their
121 // string representation.
122 // You can derive from this FastFieldValuePrinter if you want to have fields
123 // to be printed in a different way and register it at the Printer.
124 class PROTOBUF_EXPORT FastFieldValuePrinter {
125 public:
126 FastFieldValuePrinter();
127 virtual ~FastFieldValuePrinter();
128 virtual void PrintBool(bool val, BaseTextGenerator* generator) const;
129 virtual void PrintInt32(int32 val, BaseTextGenerator* generator) const;
130 virtual void PrintUInt32(uint32 val, BaseTextGenerator* generator) const;
131 virtual void PrintInt64(int64 val, BaseTextGenerator* generator) const;
132 virtual void PrintUInt64(uint64 val, BaseTextGenerator* generator) const;
133 virtual void PrintFloat(float val, BaseTextGenerator* generator) const;
134 virtual void PrintDouble(double val, BaseTextGenerator* generator) const;
135 virtual void PrintString(const std::string& val,
136 BaseTextGenerator* generator) const;
137 virtual void PrintBytes(const std::string& val,
138 BaseTextGenerator* generator) const;
139 virtual void PrintEnum(int32 val, const std::string& name,
140 BaseTextGenerator* generator) const;
141 virtual void PrintFieldName(const Message& message, int field_index,
142 int field_count, const Reflection* reflection,
143 const FieldDescriptor* field,
144 BaseTextGenerator* generator) const;
145 virtual void PrintFieldName(const Message& message,
146 const Reflection* reflection,
147 const FieldDescriptor* field,
148 BaseTextGenerator* generator) const;
149 virtual void PrintMessageStart(const Message& message, int field_index,
150 int field_count, bool single_line_mode,
151 BaseTextGenerator* generator) const;
152 // Allows to override the logic on how to print the content of a message.
153 // Return false to use the default printing logic. Note that it is legal for
154 // this function to print something and then return false to use the default
155 // content printing (although at that point it would behave similarly to
156 // PrintMessageStart).
157 virtual bool PrintMessageContent(const Message& message, int field_index,
158 int field_count, bool single_line_mode,
159 BaseTextGenerator* generator) const;
160 virtual void PrintMessageEnd(const Message& message, int field_index,
161 int field_count, bool single_line_mode,
162 BaseTextGenerator* generator) const;
163
164 private:
165 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter);
166 };
167
168 // Deprecated: please use FastFieldValuePrinter instead.
169 class PROTOBUF_EXPORT FieldValuePrinter {
170 public:
171 FieldValuePrinter();
172 virtual ~FieldValuePrinter();
173 virtual std::string PrintBool(bool val) const;
174 virtual std::string PrintInt32(int32 val) const;
175 virtual std::string PrintUInt32(uint32 val) const;
176 virtual std::string PrintInt64(int64 val) const;
177 virtual std::string PrintUInt64(uint64 val) const;
178 virtual std::string PrintFloat(float val) const;
179 virtual std::string PrintDouble(double val) const;
180 virtual std::string PrintString(const std::string& val) const;
181 virtual std::string PrintBytes(const std::string& val) const;
182 virtual std::string PrintEnum(int32 val, const std::string& name) const;
183 virtual std::string PrintFieldName(const Message& message,
184 const Reflection* reflection,
185 const FieldDescriptor* field) const;
186 virtual std::string PrintMessageStart(const Message& message,
187 int field_index, int field_count,
188 bool single_line_mode) const;
189 virtual std::string PrintMessageEnd(const Message& message, int field_index,
190 int field_count,
191 bool single_line_mode) const;
192
193 private:
194 FastFieldValuePrinter delegate_;
195 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
196 };
197
198 class PROTOBUF_EXPORT MessagePrinter {
199 public:
MessagePrinter()200 MessagePrinter() {}
~MessagePrinter()201 virtual ~MessagePrinter() {}
202 virtual void Print(const Message& message, bool single_line_mode,
203 BaseTextGenerator* generator) const = 0;
204
205 private:
206 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessagePrinter);
207 };
208
209 // Interface that Printers or Parsers can use to find extensions, or types
210 // referenced in Any messages.
211 class PROTOBUF_EXPORT Finder {
212 public:
213 virtual ~Finder();
214
215 // Try to find an extension of *message by fully-qualified field
216 // name. Returns NULL if no extension is known for this name or number.
217 // The base implementation uses the extensions already known by the message.
218 virtual const FieldDescriptor* FindExtension(Message* message,
219 const std::string& name) const;
220
221 // Similar to FindExtension, but uses a Descriptor and the extension number
222 // instead of using a Message and the name when doing the look up.
223 virtual const FieldDescriptor* FindExtensionByNumber(
224 const Descriptor* descriptor, int number) const;
225
226 // Find the message type for an Any proto.
227 // Returns NULL if no message is known for this name.
228 // The base implementation only accepts prefixes of type.googleprod.com/ or
229 // type.googleapis.com/, and searches the DescriptorPool of the parent
230 // message.
231 virtual const Descriptor* FindAnyType(const Message& message,
232 const std::string& prefix,
233 const std::string& name) const;
234
235 // Find the message factory for the given extension field. This can be used
236 // to generalize the Parser to add extension fields to a message in the same
237 // way as the "input" message for the Parser.
238 virtual MessageFactory* FindExtensionFactory(
239 const FieldDescriptor* field) const;
240 };
241
242 // Class for those users which require more fine-grained control over how
243 // a protobuffer message is printed out.
244 class PROTOBUF_EXPORT Printer {
245 public:
246 Printer();
247
248 // Like TextFormat::Print
249 bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
250 // Like TextFormat::PrintUnknownFields
251 bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
252 io::ZeroCopyOutputStream* output) const;
253 // Like TextFormat::PrintToString
254 bool PrintToString(const Message& message, std::string* output) const;
255 // Like TextFormat::PrintUnknownFieldsToString
256 bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
257 std::string* output) const;
258 // Like TextFormat::PrintFieldValueToString
259 void PrintFieldValueToString(const Message& message,
260 const FieldDescriptor* field, int index,
261 std::string* output) const;
262
263 // Adjust the initial indent level of all output. Each indent level is
264 // equal to two spaces.
SetInitialIndentLevel(int indent_level)265 void SetInitialIndentLevel(int indent_level) {
266 initial_indent_level_ = indent_level;
267 }
268
269 // If printing in single line mode, then the entire message will be output
270 // on a single line with no line breaks.
SetSingleLineMode(bool single_line_mode)271 void SetSingleLineMode(bool single_line_mode) {
272 single_line_mode_ = single_line_mode;
273 }
274
IsInSingleLineMode()275 bool IsInSingleLineMode() const { return single_line_mode_; }
276
277 // If use_field_number is true, uses field number instead of field name.
SetUseFieldNumber(bool use_field_number)278 void SetUseFieldNumber(bool use_field_number) {
279 use_field_number_ = use_field_number;
280 }
281
282 // Set true to print repeated primitives in a format like:
283 // field_name: [1, 2, 3, 4]
284 // instead of printing each value on its own line. Short format applies
285 // only to primitive values -- i.e. everything except strings and
286 // sub-messages/groups.
SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives)287 void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
288 use_short_repeated_primitives_ = use_short_repeated_primitives;
289 }
290
291 // Set true to output UTF-8 instead of ASCII. The only difference
292 // is that bytes >= 0x80 in string fields will not be escaped,
293 // because they are assumed to be part of UTF-8 multi-byte
294 // sequences. This will change the default FastFieldValuePrinter.
295 void SetUseUtf8StringEscaping(bool as_utf8);
296
297 // Set the default FastFieldValuePrinter that is used for all fields that
298 // don't have a field-specific printer registered.
299 // Takes ownership of the printer.
300 void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer);
301
302 PROTOBUF_DEPRECATED_MSG("Please use FastFieldValuePrinter")
303 void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
304
305 // Sets whether we want to hide unknown fields or not.
306 // Usually unknown fields are printed in a generic way that includes the
307 // tag number of the field instead of field name. However, sometimes it
308 // is useful to be able to print the message without unknown fields (e.g.
309 // for the python protobuf version to maintain consistency between its pure
310 // python and c++ implementations).
SetHideUnknownFields(bool hide)311 void SetHideUnknownFields(bool hide) { hide_unknown_fields_ = hide; }
312
313 // If print_message_fields_in_index_order is true, fields of a proto message
314 // will be printed using the order defined in source code instead of the
315 // field number, extensions will be printed at the end of the message
316 // and their relative order is determined by the extension number.
317 // By default, use the field number order.
SetPrintMessageFieldsInIndexOrder(bool print_message_fields_in_index_order)318 void SetPrintMessageFieldsInIndexOrder(
319 bool print_message_fields_in_index_order) {
320 print_message_fields_in_index_order_ =
321 print_message_fields_in_index_order;
322 }
323
324 // If expand==true, expand google.protobuf.Any payloads. The output
325 // will be of form
326 // [type_url] { <value_printed_in_text> }
327 //
328 // If expand==false, print Any using the default printer. The output will
329 // look like
330 // type_url: "<type_url>" value: "serialized_content"
SetExpandAny(bool expand)331 void SetExpandAny(bool expand) { expand_any_ = expand; }
332
333 // Set how parser finds message for Any payloads.
SetFinder(const Finder * finder)334 void SetFinder(const Finder* finder) { finder_ = finder; }
335
336 // If non-zero, we truncate all string fields that are longer than
337 // this threshold. This is useful when the proto message has very long
338 // strings, e.g., dump of encoded image file.
339 //
340 // NOTE(hfgong): Setting a non-zero value breaks round-trip safe
341 // property of TextFormat::Printer. That is, from the printed message, we
342 // cannot fully recover the original string field any more.
SetTruncateStringFieldLongerThan(const int64 truncate_string_field_longer_than)343 void SetTruncateStringFieldLongerThan(
344 const int64 truncate_string_field_longer_than) {
345 truncate_string_field_longer_than_ = truncate_string_field_longer_than;
346 }
347
348 // Register a custom field-specific FastFieldValuePrinter for fields
349 // with a particular FieldDescriptor.
350 // Returns "true" if the registration succeeded, or "false", if there is
351 // already a printer for that FieldDescriptor.
352 // Takes ownership of the printer on successful registration.
353 bool RegisterFieldValuePrinter(const FieldDescriptor* field,
354 const FastFieldValuePrinter* printer);
355
356 PROTOBUF_DEPRECATED_MSG("Please use FastFieldValuePrinter")
357 bool RegisterFieldValuePrinter(const FieldDescriptor* field,
358 const FieldValuePrinter* printer);
359
360 // Register a custom message-specific MessagePrinter for messages with a
361 // particular Descriptor.
362 // Returns "true" if the registration succeeded, or "false" if there is
363 // already a printer for that Descriptor.
364 bool RegisterMessagePrinter(const Descriptor* descriptor,
365 const MessagePrinter* printer);
366
367 private:
368 // Forward declaration of an internal class used to print the text
369 // output to the OutputStream (see text_format.cc for implementation).
370 class TextGenerator;
371
372 static const char* const kDoNotParse;
373
374 // Internal Print method, used for writing to the OutputStream via
375 // the TextGenerator class.
376 void Print(const Message& message, TextGenerator* generator) const;
377
378 // Print a single field.
379 void PrintField(const Message& message, const Reflection* reflection,
380 const FieldDescriptor* field,
381 TextGenerator* generator) const;
382
383 // Print a repeated primitive field in short form.
384 void PrintShortRepeatedField(const Message& message,
385 const Reflection* reflection,
386 const FieldDescriptor* field,
387 TextGenerator* generator) const;
388
389 // Print the name of a field -- i.e. everything that comes before the
390 // ':' for a single name/value pair.
391 void PrintFieldName(const Message& message, int field_index,
392 int field_count, const Reflection* reflection,
393 const FieldDescriptor* field,
394 TextGenerator* generator) const;
395
396 // Outputs a textual representation of the value of the field supplied on
397 // the message supplied or the default value if not set.
398 void PrintFieldValue(const Message& message, const Reflection* reflection,
399 const FieldDescriptor* field, int index,
400 TextGenerator* generator) const;
401
402 // Print the fields in an UnknownFieldSet. They are printed by tag number
403 // only. Embedded messages are heuristically identified by attempting to
404 // parse them (subject to the recursion budget).
405 void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
406 TextGenerator* generator,
407 int recursion_budget) const;
408
409 bool PrintAny(const Message& message, TextGenerator* generator) const;
410
GetFieldPrinter(const FieldDescriptor * field)411 const FastFieldValuePrinter* GetFieldPrinter(
412 const FieldDescriptor* field) const {
413 auto it = custom_printers_.find(field);
414 return it == custom_printers_.end() ? default_field_value_printer_.get()
415 : it->second.get();
416 }
417
418 int initial_indent_level_;
419 bool single_line_mode_;
420 bool use_field_number_;
421 bool use_short_repeated_primitives_;
422 bool hide_unknown_fields_;
423 bool print_message_fields_in_index_order_;
424 bool expand_any_;
425 int64 truncate_string_field_longer_than_;
426
427 std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_;
428 typedef std::map<const FieldDescriptor*,
429 std::unique_ptr<const FastFieldValuePrinter>>
430 CustomPrinterMap;
431 CustomPrinterMap custom_printers_;
432
433 typedef std::map<const Descriptor*, std::unique_ptr<const MessagePrinter>>
434 CustomMessagePrinterMap;
435 CustomMessagePrinterMap custom_message_printers_;
436
437 const Finder* finder_;
438 };
439
440 // Parses a text-format protocol message from the given input stream to
441 // the given message object. This function parses the human-readable format
442 // written by Print(). Returns true on success. The message is cleared first,
443 // even if the function fails -- See Merge() to avoid this behavior.
444 //
445 // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}"
446 //
447 // One use for this function is parsing handwritten strings in test code.
448 // Another use is to parse the output from google::protobuf::Message::DebugString()
449 // (or ShortDebugString()), because these functions output using
450 // google::protobuf::TextFormat::Print().
451 //
452 // If you would like to read a protocol buffer serialized in the
453 // (non-human-readable) binary wire format, see
454 // google::protobuf::MessageLite::ParseFromString().
455 static bool Parse(io::ZeroCopyInputStream* input, Message* output);
456 // Like Parse(), but reads directly from a string.
457 static bool ParseFromString(const std::string& input, Message* output);
458
459 // Like Parse(), but the data is merged into the given message, as if
460 // using Message::MergeFrom().
461 static bool Merge(io::ZeroCopyInputStream* input, Message* output);
462 // Like Merge(), but reads directly from a string.
463 static bool MergeFromString(const std::string& input, Message* output);
464
465 // Parse the given text as a single field value and store it into the
466 // given field of the given message. If the field is a repeated field,
467 // the new value will be added to the end
468 static bool ParseFieldValueFromString(const std::string& input,
469 const FieldDescriptor* field,
470 Message* message);
471
472 // A location in the parsed text.
473 struct ParseLocation {
474 int line;
475 int column;
476
ParseLocationParseLocation477 ParseLocation() : line(-1), column(-1) {}
ParseLocationParseLocation478 ParseLocation(int line_param, int column_param)
479 : line(line_param), column(column_param) {}
480 };
481
482 // Data structure which is populated with the locations of each field
483 // value parsed from the text.
484 class PROTOBUF_EXPORT ParseInfoTree {
485 public:
486 ParseInfoTree() = default;
487 ParseInfoTree(const ParseInfoTree&) = delete;
488 ParseInfoTree& operator=(const ParseInfoTree&) = delete;
489
490 // Returns the parse location for index-th value of the field in the parsed
491 // text. If none exists, returns a location with line = -1. Index should be
492 // -1 for not-repeated fields.
493 ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
494
495 // Returns the parse info tree for the given field, which must be a message
496 // type. The nested information tree is owned by the root tree and will be
497 // deleted when it is deleted.
498 ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
499 int index) const;
500
501 private:
502 // Allow the text format parser to record information into the tree.
503 friend class TextFormat;
504
505 // Records the starting location of a single value for a field.
506 void RecordLocation(const FieldDescriptor* field, ParseLocation location);
507
508 // Create and records a nested tree for a nested message field.
509 ParseInfoTree* CreateNested(const FieldDescriptor* field);
510
511 // Defines the map from the index-th field descriptor to its parse location.
512 typedef std::map<const FieldDescriptor*, std::vector<ParseLocation> >
513 LocationMap;
514
515 // Defines the map from the index-th field descriptor to the nested parse
516 // info tree.
517 typedef std::map<const FieldDescriptor*,
518 std::vector<std::unique_ptr<ParseInfoTree>>>
519 NestedMap;
520
521 LocationMap locations_;
522 NestedMap nested_;
523 };
524
525 // For more control over parsing, use this class.
526 class PROTOBUF_EXPORT Parser {
527 public:
528 Parser();
529 ~Parser();
530
531 // Like TextFormat::Parse().
532 bool Parse(io::ZeroCopyInputStream* input, Message* output);
533 // Like TextFormat::ParseFromString().
534 bool ParseFromString(const std::string& input, Message* output);
535 // Like TextFormat::Merge().
536 bool Merge(io::ZeroCopyInputStream* input, Message* output);
537 // Like TextFormat::MergeFromString().
538 bool MergeFromString(const std::string& input, Message* output);
539
540 // Set where to report parse errors. If NULL (the default), errors will
541 // be printed to stderr.
RecordErrorsTo(io::ErrorCollector * error_collector)542 void RecordErrorsTo(io::ErrorCollector* error_collector) {
543 error_collector_ = error_collector;
544 }
545
546 // Set how parser finds extensions. If NULL (the default), the
547 // parser will use the standard Reflection object associated with
548 // the message being parsed.
SetFinder(const Finder * finder)549 void SetFinder(const Finder* finder) { finder_ = finder; }
550
551 // Sets where location information about the parse will be written. If NULL
552 // (the default), then no location will be written.
WriteLocationsTo(ParseInfoTree * tree)553 void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; }
554
555 // Normally parsing fails if, after parsing, output->IsInitialized()
556 // returns false. Call AllowPartialMessage(true) to skip this check.
AllowPartialMessage(bool allow)557 void AllowPartialMessage(bool allow) { allow_partial_ = allow; }
558
559 // Allow field names to be matched case-insensitively.
560 // This is not advisable if there are fields that only differ in case, or
561 // if you want to enforce writing in the canonical form.
562 // This is 'false' by default.
AllowCaseInsensitiveField(bool allow)563 void AllowCaseInsensitiveField(bool allow) {
564 allow_case_insensitive_field_ = allow;
565 }
566
567 // Like TextFormat::ParseFieldValueFromString
568 bool ParseFieldValueFromString(const std::string& input,
569 const FieldDescriptor* field,
570 Message* output);
571
572 // When an unknown extension is met, parsing will fail if this option is set
573 // to false (the default). If true, unknown extensions will be ignored and
574 // a warning message will be generated.
AllowUnknownExtension(bool allow)575 void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; }
576
577 // When an unknown field is met, parsing will fail if this option is set
578 // to false(the default). If true, unknown fields will be ignored and
579 // a warning message will be generated.
580 // Please aware that set this option true may hide some errors (e.g.
581 // spelling error on field name). Avoid to use this option if possible.
AllowUnknownField(bool allow)582 void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; }
583
584
AllowFieldNumber(bool allow)585 void AllowFieldNumber(bool allow) { allow_field_number_ = allow; }
586
587 // Sets maximum recursion depth which parser can use. This is effectively
588 // the maximum allowed nesting of proto messages.
SetRecursionLimit(int limit)589 void SetRecursionLimit(int limit) { recursion_limit_ = limit; }
590
591 private:
592 // Forward declaration of an internal class used to parse text
593 // representations (see text_format.cc for implementation).
594 class ParserImpl;
595
596 // Like TextFormat::Merge(). The provided implementation is used
597 // to do the parsing.
598 bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output,
599 ParserImpl* parser_impl);
600
601 io::ErrorCollector* error_collector_;
602 const Finder* finder_;
603 ParseInfoTree* parse_info_tree_;
604 bool allow_partial_;
605 bool allow_case_insensitive_field_;
606 bool allow_unknown_field_;
607 bool allow_unknown_extension_;
608 bool allow_unknown_enum_;
609 bool allow_field_number_;
610 bool allow_relaxed_whitespace_;
611 bool allow_singular_overwrites_;
612 int recursion_limit_;
613 };
614
615
616 private:
617 // Hack: ParseInfoTree declares TextFormat as a friend which should extend
618 // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
619 // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
620 // helpers for ParserImpl to call methods of ParseInfoTree.
621 static inline void RecordLocation(ParseInfoTree* info_tree,
622 const FieldDescriptor* field,
623 ParseLocation location);
624 static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
625 const FieldDescriptor* field);
626
627 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
628 };
629
RecordLocation(ParseInfoTree * info_tree,const FieldDescriptor * field,ParseLocation location)630 inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
631 const FieldDescriptor* field,
632 ParseLocation location) {
633 info_tree->RecordLocation(field, location);
634 }
635
CreateNested(ParseInfoTree * info_tree,const FieldDescriptor * field)636 inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
637 ParseInfoTree* info_tree, const FieldDescriptor* field) {
638 return info_tree->CreateNested(field);
639 }
640
641 } // namespace protobuf
642 } // namespace google
643
644 #include <google/protobuf/port_undef.inc>
645
646 #endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
647