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