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