• 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 
50 namespace google {
51 namespace protobuf {
52 
53 namespace io {
54   class ErrorCollector;      // tokenizer.h
55 }
56 
57 // This class implements protocol buffer text format.  Printing and parsing
58 // protocol messages in text format is useful for debugging and human editing
59 // of messages.
60 //
61 // This class is really a namespace that contains only static methods.
62 class LIBPROTOBUF_EXPORT TextFormat {
63  public:
64   // Outputs a textual representation of the given message to the given
65   // output stream.
66   static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
67 
68   // Print the fields in an UnknownFieldSet.  They are printed by tag number
69   // only.  Embedded messages are heuristically identified by attempting to
70   // parse them.
71   static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
72                                  io::ZeroCopyOutputStream* output);
73 
74   // Like Print(), but outputs directly to a string.
75   static bool PrintToString(const Message& message, string* output);
76 
77   // Like PrintUnknownFields(), but outputs directly to a string.
78   static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
79                                          string* output);
80 
81   // Outputs a textual representation of the value of the field supplied on
82   // the message supplied. For non-repeated fields, an index of -1 must
83   // be supplied. Note that this method will print the default value for a
84   // field if it is not set.
85   static void PrintFieldValueToString(const Message& message,
86                                       const FieldDescriptor* field,
87                                       int index,
88                                       string* output);
89 
90   // The default printer that converts scalar values from fields into
91   // their string representation.
92   // You can derive from this FieldValuePrinter if you want to have
93   // fields to be printed in a different way and register it at the
94   // Printer.
95   class LIBPROTOBUF_EXPORT FieldValuePrinter {
96    public:
97     FieldValuePrinter();
98     virtual ~FieldValuePrinter();
99     virtual string PrintBool(bool val) const;
100     virtual string PrintInt32(int32 val) const;
101     virtual string PrintUInt32(uint32 val) const;
102     virtual string PrintInt64(int64 val) const;
103     virtual string PrintUInt64(uint64 val) const;
104     virtual string PrintFloat(float val) const;
105     virtual string PrintDouble(double val) const;
106     virtual string PrintString(const string& val) const;
107     virtual string PrintBytes(const string& val) const;
108     virtual string PrintEnum(int32 val, const string& name) const;
109     virtual string PrintFieldName(const Message& message,
110                                   const Reflection* reflection,
111                                   const FieldDescriptor* field) const;
112     virtual string PrintMessageStart(const Message& message,
113                                      int field_index,
114                                      int field_count,
115                                      bool single_line_mode) const;
116     virtual string PrintMessageEnd(const Message& message,
117                                    int field_index,
118                                    int field_count,
119                                    bool single_line_mode) const;
120 
121    private:
122     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
123   };
124 
125   // Class for those users which require more fine-grained control over how
126   // a protobuffer message is printed out.
127   class LIBPROTOBUF_EXPORT Printer {
128    public:
129     Printer();
130     ~Printer();
131 
132     // Like TextFormat::Print
133     bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
134     // Like TextFormat::PrintUnknownFields
135     bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
136                             io::ZeroCopyOutputStream* output) const;
137     // Like TextFormat::PrintToString
138     bool PrintToString(const Message& message, string* output) const;
139     // Like TextFormat::PrintUnknownFieldsToString
140     bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
141                                     string* output) const;
142     // Like TextFormat::PrintFieldValueToString
143     void PrintFieldValueToString(const Message& message,
144                                  const FieldDescriptor* field,
145                                  int index,
146                                  string* output) const;
147 
148     // Adjust the initial indent level of all output.  Each indent level is
149     // equal to two spaces.
SetInitialIndentLevel(int indent_level)150     void SetInitialIndentLevel(int indent_level) {
151       initial_indent_level_ = indent_level;
152     }
153 
154     // If printing in single line mode, then the entire message will be output
155     // on a single line with no line breaks.
SetSingleLineMode(bool single_line_mode)156     void SetSingleLineMode(bool single_line_mode) {
157       single_line_mode_ = single_line_mode;
158     }
159 
IsInSingleLineMode()160     bool IsInSingleLineMode() {
161       return single_line_mode_;
162     }
163 
164     // If use_field_number is true, uses field number instead of field name.
SetUseFieldNumber(bool use_field_number)165     void SetUseFieldNumber(bool use_field_number) {
166       use_field_number_ = use_field_number;
167     }
168 
169     // Set true to print repeated primitives in a format like:
170     //   field_name: [1, 2, 3, 4]
171     // instead of printing each value on its own line.  Short format applies
172     // only to primitive values -- i.e. everything except strings and
173     // sub-messages/groups.
SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives)174     void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
175       use_short_repeated_primitives_ = use_short_repeated_primitives;
176     }
177 
178     // Set true to output UTF-8 instead of ASCII.  The only difference
179     // is that bytes >= 0x80 in string fields will not be escaped,
180     // because they are assumed to be part of UTF-8 multi-byte
181     // sequences. This will change the default FieldValuePrinter.
182     void SetUseUtf8StringEscaping(bool as_utf8);
183 
184     // Set the default FieldValuePrinter that is used for all fields that
185     // don't have a field-specific printer registered.
186     // Takes ownership of the printer.
187     void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
188 
189     // Sets whether we want to hide unknown fields or not.
190     // Usually unknown fields are printed in a generic way that includes the
191     // tag number of the field instead of field name. However, sometimes it
192     // is useful to be able to print the message without unknown fields (e.g.
193     // for the python protobuf version to maintain consistency between its pure
194     // python and c++ implementations).
SetHideUnknownFields(bool hide)195     void SetHideUnknownFields(bool hide) {
196       hide_unknown_fields_ = hide;
197     }
198 
199     // If print_message_fields_in_index_order is true, print fields of a proto
200     // message using the order defined in source code instead of the field
201     // number. By default, use the field number order.
SetPrintMessageFieldsInIndexOrder(bool print_message_fields_in_index_order)202     void SetPrintMessageFieldsInIndexOrder(
203         bool print_message_fields_in_index_order) {
204       print_message_fields_in_index_order_ =
205           print_message_fields_in_index_order;
206     }
207 
208     // Register a custom field-specific FieldValuePrinter for fields
209     // with a particular FieldDescriptor.
210     // Returns "true" if the registration succeeded, or "false", if there is
211     // already a printer for that FieldDescriptor.
212     // Takes ownership of the printer on successful registration.
213     bool RegisterFieldValuePrinter(const FieldDescriptor* field,
214                                    const FieldValuePrinter* printer);
215 
216    private:
217     // Forward declaration of an internal class used to print the text
218     // output to the OutputStream (see text_format.cc for implementation).
219     class TextGenerator;
220 
221     // Internal Print method, used for writing to the OutputStream via
222     // the TextGenerator class.
223     void Print(const Message& message,
224                TextGenerator& generator) const;
225 
226     // Print a single field.
227     void PrintField(const Message& message,
228                     const Reflection* reflection,
229                     const FieldDescriptor* field,
230                     TextGenerator& generator) const;
231 
232     // Print a repeated primitive field in short form.
233     void PrintShortRepeatedField(const Message& message,
234                                  const Reflection* reflection,
235                                  const FieldDescriptor* field,
236                                  TextGenerator& generator) const;
237 
238     // Print the name of a field -- i.e. everything that comes before the
239     // ':' for a single name/value pair.
240     void PrintFieldName(const Message& message,
241                         const Reflection* reflection,
242                         const FieldDescriptor* field,
243                         TextGenerator& generator) const;
244 
245     // Outputs a textual representation of the value of the field supplied on
246     // the message supplied or the default value if not set.
247     void PrintFieldValue(const Message& message,
248                          const Reflection* reflection,
249                          const FieldDescriptor* field,
250                          int index,
251                          TextGenerator& generator) const;
252 
253     // Print the fields in an UnknownFieldSet.  They are printed by tag number
254     // only.  Embedded messages are heuristically identified by attempting to
255     // parse them.
256     void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
257                             TextGenerator& generator) const;
258 
259     int initial_indent_level_;
260 
261     bool single_line_mode_;
262 
263     bool use_field_number_;
264 
265     bool use_short_repeated_primitives_;
266 
267     bool hide_unknown_fields_;
268 
269     bool print_message_fields_in_index_order_;
270 
271     scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
272     typedef map<const FieldDescriptor*,
273                 const FieldValuePrinter*> CustomPrinterMap;
274     CustomPrinterMap custom_printers_;
275   };
276 
277   // Parses a text-format protocol message from the given input stream to
278   // the given message object.  This function parses the format written
279   // by Print().
280   static bool Parse(io::ZeroCopyInputStream* input, Message* output);
281   // Like Parse(), but reads directly from a string.
282   static bool ParseFromString(const string& input, Message* output);
283 
284   // Like Parse(), but the data is merged into the given message, as if
285   // using Message::MergeFrom().
286   static bool Merge(io::ZeroCopyInputStream* input, Message* output);
287   // Like Merge(), but reads directly from a string.
288   static bool MergeFromString(const string& input, Message* output);
289 
290   // Parse the given text as a single field value and store it into the
291   // given field of the given message. If the field is a repeated field,
292   // the new value will be added to the end
293   static bool ParseFieldValueFromString(const string& input,
294                                         const FieldDescriptor* field,
295                                         Message* message);
296 
297   // Interface that TextFormat::Parser can use to find extensions.
298   // This class may be extended in the future to find more information
299   // like fields, etc.
300   class LIBPROTOBUF_EXPORT Finder {
301    public:
302     virtual ~Finder();
303 
304     // Try to find an extension of *message by fully-qualified field
305     // name.  Returns NULL if no extension is known for this name or number.
306     virtual const FieldDescriptor* FindExtension(
307         Message* message,
308         const string& name) const = 0;
309   };
310 
311   // A location in the parsed text.
312   struct ParseLocation {
313     int line;
314     int column;
315 
ParseLocationParseLocation316     ParseLocation() : line(-1), column(-1) {}
ParseLocationParseLocation317     ParseLocation(int line_param, int column_param)
318         : line(line_param), column(column_param) {}
319   };
320 
321   // Data structure which is populated with the locations of each field
322   // value parsed from the text.
323   class LIBPROTOBUF_EXPORT ParseInfoTree {
324    public:
325     ParseInfoTree();
326     ~ParseInfoTree();
327 
328     // Returns the parse location for index-th value of the field in the parsed
329     // text. If none exists, returns a location with line = -1. Index should be
330     // -1 for not-repeated fields.
331     ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
332 
333     // Returns the parse info tree for the given field, which must be a message
334     // type. The nested information tree is owned by the root tree and will be
335     // deleted when it is deleted.
336     ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
337                                     int index) const;
338 
339    private:
340     // Allow the text format parser to record information into the tree.
341     friend class TextFormat;
342 
343     // Records the starting location of a single value for a field.
344     void RecordLocation(const FieldDescriptor* field, ParseLocation location);
345 
346     // Create and records a nested tree for a nested message field.
347     ParseInfoTree* CreateNested(const FieldDescriptor* field);
348 
349     // Defines the map from the index-th field descriptor to its parse location.
350     typedef map<const FieldDescriptor*, vector<ParseLocation> > LocationMap;
351 
352     // Defines the map from the index-th field descriptor to the nested parse
353     // info tree.
354     typedef map<const FieldDescriptor*, vector<ParseInfoTree*> > NestedMap;
355 
356     LocationMap locations_;
357     NestedMap nested_;
358 
359     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree);
360   };
361 
362   // For more control over parsing, use this class.
363   class LIBPROTOBUF_EXPORT Parser {
364    public:
365     Parser();
366     ~Parser();
367 
368     // Like TextFormat::Parse().
369     bool Parse(io::ZeroCopyInputStream* input, Message* output);
370     // Like TextFormat::ParseFromString().
371     bool ParseFromString(const string& input, Message* output);
372     // Like TextFormat::Merge().
373     bool Merge(io::ZeroCopyInputStream* input, Message* output);
374     // Like TextFormat::MergeFromString().
375     bool MergeFromString(const string& input, Message* output);
376 
377     // Set where to report parse errors.  If NULL (the default), errors will
378     // be printed to stderr.
RecordErrorsTo(io::ErrorCollector * error_collector)379     void RecordErrorsTo(io::ErrorCollector* error_collector) {
380       error_collector_ = error_collector;
381     }
382 
383     // Set how parser finds extensions.  If NULL (the default), the
384     // parser will use the standard Reflection object associated with
385     // the message being parsed.
SetFinder(Finder * finder)386     void SetFinder(Finder* finder) {
387       finder_ = finder;
388     }
389 
390     // Sets where location information about the parse will be written. If NULL
391     // (the default), then no location will be written.
WriteLocationsTo(ParseInfoTree * tree)392     void WriteLocationsTo(ParseInfoTree* tree) {
393       parse_info_tree_ = tree;
394     }
395 
396     // Normally parsing fails if, after parsing, output->IsInitialized()
397     // returns false.  Call AllowPartialMessage(true) to skip this check.
AllowPartialMessage(bool allow)398     void AllowPartialMessage(bool allow) {
399       allow_partial_ = allow;
400     }
401 
402     // Allow field names to be matched case-insensitively.
403     // This is not advisable if there are fields that only differ in case, or
404     // if you want to enforce writing in the canonical form.
405     // This is 'false' by default.
AllowCaseInsensitiveField(bool allow)406     void AllowCaseInsensitiveField(bool allow) {
407       allow_case_insensitive_field_ = allow;
408     }
409 
410     // Like TextFormat::ParseFieldValueFromString
411     bool ParseFieldValueFromString(const string& input,
412                                    const FieldDescriptor* field,
413                                    Message* output);
414 
415 
AllowFieldNumber(bool allow)416     void AllowFieldNumber(bool allow) {
417       allow_field_number_ = allow;
418     }
419 
420    private:
421     // Forward declaration of an internal class used to parse text
422     // representations (see text_format.cc for implementation).
423     class ParserImpl;
424 
425     // Like TextFormat::Merge().  The provided implementation is used
426     // to do the parsing.
427     bool MergeUsingImpl(io::ZeroCopyInputStream* input,
428                         Message* output,
429                         ParserImpl* parser_impl);
430 
431     io::ErrorCollector* error_collector_;
432     Finder* finder_;
433     ParseInfoTree* parse_info_tree_;
434     bool allow_partial_;
435     bool allow_case_insensitive_field_;
436     bool allow_unknown_field_;
437     bool allow_unknown_enum_;
438     bool allow_field_number_;
439     bool allow_relaxed_whitespace_;
440     bool allow_singular_overwrites_;
441   };
442 
443 
444  private:
445   // Hack: ParseInfoTree declares TextFormat as a friend which should extend
446   // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
447   // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
448   // helpers for ParserImpl to call methods of ParseInfoTree.
449   static inline void RecordLocation(ParseInfoTree* info_tree,
450                                     const FieldDescriptor* field,
451                                     ParseLocation location);
452   static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
453                                             const FieldDescriptor* field);
454 
455   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
456 };
457 
RecordLocation(ParseInfoTree * info_tree,const FieldDescriptor * field,ParseLocation location)458 inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
459                                        const FieldDescriptor* field,
460                                        ParseLocation location) {
461   info_tree->RecordLocation(field, location);
462 }
463 
464 
CreateNested(ParseInfoTree * info_tree,const FieldDescriptor * field)465 inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
466     ParseInfoTree* info_tree, const FieldDescriptor* field) {
467   return info_tree->CreateNested(field);
468 }
469 
470 }  // namespace protobuf
471 
472 }  // namespace google
473 #endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
474