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