xref: /aosp_15_r20/external/cronet/third_party/protobuf/src/google/protobuf/text_format.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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: [email protected] (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 internal {
64 PROTOBUF_EXPORT extern const char kDebugStringSilentMarker[1];
65 PROTOBUF_EXPORT extern const char kDebugStringSilentMarkerForDetection[3];
66 }  // namespace internal
67 
68 namespace io {
69 class 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.
77 class 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 
Indent()111     virtual void Indent() {}
Outdent()112     virtual void Outdent() {}
113     // Returns the current indentation size in characters.
GetCurrentIndentationSize()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 
PrintString(const std::string & str)119     void PrintString(const std::string& str) { Print(str.data(), str.size()); }
120 
121     template <size_t n>
PrintLiteral(const char (& text)[n])122     void PrintLiteral(const char (&text)[n]) {
123       Print(text, 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:
MessagePrinter()207     MessagePrinter() {}
~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.
SetInitialIndentLevel(int indent_level)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.
SetSingleLineMode(bool single_line_mode)278     void SetSingleLineMode(bool single_line_mode) {
279       single_line_mode_ = single_line_mode;
280     }
281 
IsInSingleLineMode()282     bool IsInSingleLineMode() const { return single_line_mode_; }
283 
284     // If use_field_number is true, uses field number instead of field name.
SetUseFieldNumber(bool use_field_number)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.
SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives)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).
SetHideUnknownFields(bool hide)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.
SetPrintMessageFieldsInIndexOrder(bool print_message_fields_in_index_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"
SetExpandAny(bool expand)338     void SetExpandAny(bool expand) { expand_any_ = expand; }
339 
340     // Set how parser finds message for Any payloads.
SetFinder(const Finder * finder)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.
SetTruncateStringFieldLongerThan(const int64_t truncate_string_field_longer_than)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.
SetInsertSilentMarker(bool v)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 
GetFieldPrinter(const FieldDescriptor * field)433     const FastFieldValuePrinter* GetFieldPrinter(
434         const FieldDescriptor* field) const {
435       auto it = custom_printers_.find(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 
ParseLocationParseLocation499     ParseLocation() : line(-1), column(-1) {}
ParseLocationParseLocation500     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;
ParseLocationRangeParseLocationRange509     ParseLocationRange() : start(), end() {}
ParseLocationRangeParseLocationRange510     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.
GetLocation(const FieldDescriptor * field,int index)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.
RecordErrorsTo(io::ErrorCollector * error_collector)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.
SetFinder(const Finder * finder)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.
WriteLocationsTo(ParseInfoTree * tree)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.
AllowPartialMessage(bool allow)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.
AllowCaseInsensitiveField(bool allow)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.
AllowUnknownExtension(bool allow)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.
AllowUnknownField(bool allow)629     void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; }
630 
631 
AllowFieldNumber(bool allow)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.
SetRecursionLimit(int limit)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 
RecordLocation(ParseInfoTree * info_tree,const FieldDescriptor * field,ParseLocationRange location)677 inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
678                                        const FieldDescriptor* field,
679                                        ParseLocationRange location) {
680   info_tree->RecordLocation(field, location);
681 }
682 
CreateNested(ParseInfoTree * info_tree,const FieldDescriptor * field)683 inline 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