• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
45 namespace google {
46 namespace protobuf {
47 
48 namespace 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.
57 class 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.
SetInitialIndentLevel(int indent_level)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.
SetSingleLineMode(bool single_line_mode)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.
SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives)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.
SetUseUtf8StringEscaping(bool as_utf8)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.
RecordErrorsTo(io::ErrorCollector * error_collector)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.
AllowPartialMessage(bool allow)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