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