• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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