1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
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 <string>
42#include <google/protobuf/message.h>
43#include <google/protobuf/descriptor.h>
44
45namespace google {
46namespace protobuf {
47
48namespace io {
49  class ErrorCollector;      // tokenizer.h
50}
51
52// This class implements protocol buffer text format.  Printing and parsing
53// protocol messages in text format is useful for debugging and human editing
54// of messages.
55//
56// This class is really a namespace that contains only static methods.
57class LIBPROTOBUF_EXPORT TextFormat {
58 public:
59  // Outputs a textual representation of the given message to the given
60  // output stream.
61  static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
62
63  // Print the fields in an UnknownFieldSet.  They are printed by tag number
64  // only.  Embedded messages are heuristically identified by attempting to
65  // parse them.
66  static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
67                                 io::ZeroCopyOutputStream* output);
68
69  // Like Print(), but outputs directly to a string.
70  static bool PrintToString(const Message& message, string* output);
71
72  // Like PrintUnknownFields(), but outputs directly to a string.
73  static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
74                                         string* output);
75
76  // Outputs a textual representation of the value of the field supplied on
77  // the message supplied. For non-repeated fields, an index of -1 must
78  // be supplied. Note that this method will print the default value for a
79  // field if it is not set.
80  static void PrintFieldValueToString(const Message& message,
81                                      const FieldDescriptor* field,
82                                      int index,
83                                      string* output);
84
85  // Class for those users which require more fine-grained control over how
86  // a protobuffer message is printed out.
87  class LIBPROTOBUF_EXPORT Printer {
88   public:
89    Printer();
90    ~Printer();
91
92    // Like TextFormat::Print
93    bool Print(const Message& message, io::ZeroCopyOutputStream* output);
94    // Like TextFormat::PrintUnknownFields
95    bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
96                            io::ZeroCopyOutputStream* output);
97    // Like TextFormat::PrintToString
98    bool PrintToString(const Message& message, string* output);
99    // Like TextFormat::PrintUnknownFieldsToString
100    bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
101                                    string* output);
102    // Like TextFormat::PrintFieldValueToString
103    void PrintFieldValueToString(const Message& message,
104                                 const FieldDescriptor* field,
105                                 int index,
106                                 string* output);
107
108    // Adjust the initial indent level of all output.  Each indent level is
109    // equal to two spaces.
110    void SetInitialIndentLevel(int indent_level) {
111      initial_indent_level_ = indent_level;
112    }
113
114    // If printing in single line mode, then the entire message will be output
115    // on a single line with no line breaks.
116    void SetSingleLineMode(bool single_line_mode) {
117      single_line_mode_ = single_line_mode;
118    }
119
120    // Set true to print repeated primitives in a format like:
121    //   field_name: [1, 2, 3, 4]
122    // instead of printing each value on its own line.  Short format applies
123    // only to primitive values -- i.e. everything except strings and
124    // sub-messages/groups.  Note that at present this format is not recognized
125    // by the parser.
126    void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
127      use_short_repeated_primitives_ = use_short_repeated_primitives;
128    }
129
130    // Set true to output UTF-8 instead of ASCII.  The only difference
131    // is that bytes >= 0x80 in string fields will not be escaped,
132    // because they are assumed to be part of UTF-8 multi-byte
133    // sequences.
134    void SetUseUtf8StringEscaping(bool as_utf8) {
135      utf8_string_escaping_ = as_utf8;
136    }
137
138   private:
139    // Forward declaration of an internal class used to print the text
140    // output to the OutputStream (see text_format.cc for implementation).
141    class TextGenerator;
142
143    // Internal Print method, used for writing to the OutputStream via
144    // the TextGenerator class.
145    void Print(const Message& message,
146               TextGenerator& generator);
147
148    // Print a single field.
149    void PrintField(const Message& message,
150                    const Reflection* reflection,
151                    const FieldDescriptor* field,
152                    TextGenerator& generator);
153
154    // Print a repeated primitive field in short form.
155    void PrintShortRepeatedField(const Message& message,
156                                 const Reflection* reflection,
157                                 const FieldDescriptor* field,
158                                 TextGenerator& generator);
159
160    // Print the name of a field -- i.e. everything that comes before the
161    // ':' for a single name/value pair.
162    void PrintFieldName(const Message& message,
163                        const Reflection* reflection,
164                        const FieldDescriptor* field,
165                        TextGenerator& generator);
166
167    // Outputs a textual representation of the value of the field supplied on
168    // the message supplied or the default value if not set.
169    void PrintFieldValue(const Message& message,
170                         const Reflection* reflection,
171                         const FieldDescriptor* field,
172                         int index,
173                         TextGenerator& generator);
174
175    // Print the fields in an UnknownFieldSet.  They are printed by tag number
176    // only.  Embedded messages are heuristically identified by attempting to
177    // parse them.
178    void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
179                            TextGenerator& generator);
180
181    int initial_indent_level_;
182
183    bool single_line_mode_;
184
185    bool use_short_repeated_primitives_;
186
187    bool utf8_string_escaping_;
188  };
189
190  // Parses a text-format protocol message from the given input stream to
191  // the given message object.  This function parses the format written
192  // by Print().
193  static bool Parse(io::ZeroCopyInputStream* input, Message* output);
194  // Like Parse(), but reads directly from a string.
195  static bool ParseFromString(const string& input, Message* output);
196
197  // Like Parse(), but the data is merged into the given message, as if
198  // using Message::MergeFrom().
199  static bool Merge(io::ZeroCopyInputStream* input, Message* output);
200  // Like Merge(), but reads directly from a string.
201  static bool MergeFromString(const string& input, Message* output);
202
203  // Parse the given text as a single field value and store it into the
204  // given field of the given message. If the field is a repeated field,
205  // the new value will be added to the end
206  static bool ParseFieldValueFromString(const string& input,
207                                        const FieldDescriptor* field,
208                                        Message* message);
209
210  // For more control over parsing, use this class.
211  class LIBPROTOBUF_EXPORT Parser {
212   public:
213    Parser();
214    ~Parser();
215
216    // Like TextFormat::Parse().
217    bool Parse(io::ZeroCopyInputStream* input, Message* output);
218    // Like TextFormat::ParseFromString().
219    bool ParseFromString(const string& input, Message* output);
220    // Like TextFormat::Merge().
221    bool Merge(io::ZeroCopyInputStream* input, Message* output);
222    // Like TextFormat::MergeFromString().
223    bool MergeFromString(const string& input, Message* output);
224
225    // Set where to report parse errors.  If NULL (the default), errors will
226    // be printed to stderr.
227    void RecordErrorsTo(io::ErrorCollector* error_collector) {
228      error_collector_ = error_collector;
229    }
230
231    // Normally parsing fails if, after parsing, output->IsInitialized()
232    // returns false.  Call AllowPartialMessage(true) to skip this check.
233    void AllowPartialMessage(bool allow) {
234      allow_partial_ = allow;
235    }
236
237    // Like TextFormat::ParseFieldValueFromString
238    bool ParseFieldValueFromString(const string& input,
239                                   const FieldDescriptor* field,
240                                   Message* output);
241
242   private:
243    // Forward declaration of an internal class used to parse text
244    // representations (see text_format.cc for implementation).
245    class ParserImpl;
246
247    // Like TextFormat::Merge().  The provided implementation is used
248    // to do the parsing.
249    bool MergeUsingImpl(io::ZeroCopyInputStream* input,
250                        Message* output,
251                        ParserImpl* parser_impl);
252
253    io::ErrorCollector* error_collector_;
254    bool allow_partial_;
255  };
256
257 private:
258  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
259};
260
261}  // namespace protobuf
262
263}  // namespace google
264#endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
265