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