| 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 | |
| 42 | #include <map> |
| 43 | #include <memory> |
| 44 | #include <string> |
| 45 | #include <vector> |
| 46 | |
| 47 | #include <google/protobuf/stubs/common.h> |
| 48 | #include <google/protobuf/port.h> |
| 49 | #include <google/protobuf/descriptor.h> |
| 50 | #include <google/protobuf/message.h> |
| 51 | #include <google/protobuf/message_lite.h> |
| 52 | |
| 53 | // Must be included last. |
| 54 | #include <google/protobuf/port_def.inc> |
| 55 | |
| 56 | #ifdef SWIG |
| 57 | #error "You cannot SWIG proto headers" |
| 58 | #endif |
| 59 | |
| 60 | namespace google { |
| 61 | namespace protobuf { |
| 62 | |
| 63 | namespace internal { |
| 64 | PROTOBUF_EXPORT extern const char kDebugStringSilentMarker[1]; |
| 65 | PROTOBUF_EXPORT extern const char kDebugStringSilentMarkerForDetection[3]; |
| 66 | } // namespace internal |
| 67 | |
| 68 | namespace io { |
| 69 | class ErrorCollector; // tokenizer.h |
| 70 | } |
| 71 | |
| 72 | // This class implements protocol buffer text format, colloquially known as text |
| 73 | // proto. Printing and parsing protocol messages in text format is useful for |
| 74 | // debugging and human editing of messages. |
| 75 | // |
| 76 | // This class is really a namespace that contains only static methods. |
| 77 | class PROTOBUF_EXPORT TextFormat { |
| 78 | public: |
| 79 | // Outputs a textual representation of the given message to the given |
| 80 | // output stream. Returns false if printing fails. |
| 81 | static bool Print(const Message& message, io::ZeroCopyOutputStream* output); |
| 82 | |
| 83 | // Print the fields in an UnknownFieldSet. They are printed by tag number |
| 84 | // only. Embedded messages are heuristically identified by attempting to |
| 85 | // parse them. Returns false if printing fails. |
| 86 | static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, |
| 87 | io::ZeroCopyOutputStream* output); |
| 88 | |
| 89 | // Like Print(), but outputs directly to a string. |
| 90 | // Note: output will be cleared prior to printing, and will be left empty |
| 91 | // even if printing fails. Returns false if printing fails. |
| 92 | static bool PrintToString(const Message& message, std::string* output); |
| 93 | |
| 94 | // Like PrintUnknownFields(), but outputs directly to a string. Returns |
| 95 | // false if printing fails. |
| 96 | static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, |
| 97 | std::string* output); |
| 98 | |
| 99 | // Outputs a textual representation of the value of the field supplied on |
| 100 | // the message supplied. For non-repeated fields, an index of -1 must |
| 101 | // be supplied. Note that this method will print the default value for a |
| 102 | // field if it is not set. |
| 103 | static void PrintFieldValueToString(const Message& message, |
| 104 | const FieldDescriptor* field, int index, |
| 105 | std::string* output); |
| 106 | |
| 107 | class PROTOBUF_EXPORT BaseTextGenerator { |
| 108 | public: |
| 109 | virtual ~BaseTextGenerator(); |
| 110 | |
| 111 | virtual void Indent() {} |
| 112 | virtual void Outdent() {} |
| 113 | // Returns the current indentation size in characters. |
| 114 | virtual size_t GetCurrentIndentationSize() const { return 0; } |
| 115 | |
| 116 | // Print text to the output stream. |
| 117 | virtual void Print(const char* text, size_t size) = 0; |
| 118 | |
| 119 | void PrintString(const std::string& str) { Print(text: str.data(), size: str.size()); } |
| 120 | |
| 121 | template <size_t n> |
| 122 | void PrintLiteral(const char (&text)[n]) { |
| 123 | Print(text, size: n - 1); // n includes the terminating zero character. |
| 124 | } |
| 125 | }; |
| 126 | |
| 127 | // The default printer that converts scalar values from fields into their |
| 128 | // string representation. |
| 129 | // You can derive from this FastFieldValuePrinter if you want to have fields |
| 130 | // to be printed in a different way and register it at the Printer. |
| 131 | class PROTOBUF_EXPORT FastFieldValuePrinter { |
| 132 | public: |
| 133 | FastFieldValuePrinter(); |
| 134 | virtual ~FastFieldValuePrinter(); |
| 135 | virtual void PrintBool(bool val, BaseTextGenerator* generator) const; |
| 136 | virtual void PrintInt32(int32_t val, BaseTextGenerator* generator) const; |
| 137 | virtual void PrintUInt32(uint32_t val, BaseTextGenerator* generator) const; |
| 138 | virtual void PrintInt64(int64_t val, BaseTextGenerator* generator) const; |
| 139 | virtual void PrintUInt64(uint64_t val, BaseTextGenerator* generator) const; |
| 140 | virtual void PrintFloat(float val, BaseTextGenerator* generator) const; |
| 141 | virtual void PrintDouble(double val, BaseTextGenerator* generator) const; |
| 142 | virtual void PrintString(const std::string& val, |
| 143 | BaseTextGenerator* generator) const; |
| 144 | virtual void PrintBytes(const std::string& val, |
| 145 | BaseTextGenerator* generator) const; |
| 146 | virtual void PrintEnum(int32_t val, const std::string& name, |
| 147 | BaseTextGenerator* generator) const; |
| 148 | virtual void PrintFieldName(const Message& message, int field_index, |
| 149 | int field_count, const Reflection* reflection, |
| 150 | const FieldDescriptor* field, |
| 151 | BaseTextGenerator* generator) const; |
| 152 | virtual void PrintFieldName(const Message& message, |
| 153 | const Reflection* reflection, |
| 154 | const FieldDescriptor* field, |
| 155 | BaseTextGenerator* generator) const; |
| 156 | virtual void PrintMessageStart(const Message& message, int field_index, |
| 157 | int field_count, bool single_line_mode, |
| 158 | BaseTextGenerator* generator) const; |
| 159 | // Allows to override the logic on how to print the content of a message. |
| 160 | // Return false to use the default printing logic. Note that it is legal for |
| 161 | // this function to print something and then return false to use the default |
| 162 | // content printing (although at that point it would behave similarly to |
| 163 | // PrintMessageStart). |
| 164 | virtual bool PrintMessageContent(const Message& message, int field_index, |
| 165 | int field_count, bool single_line_mode, |
| 166 | BaseTextGenerator* generator) const; |
| 167 | virtual void PrintMessageEnd(const Message& message, int field_index, |
| 168 | int field_count, bool single_line_mode, |
| 169 | BaseTextGenerator* generator) const; |
| 170 | |
| 171 | private: |
| 172 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter); |
| 173 | }; |
| 174 | |
| 175 | // Deprecated: please use FastFieldValuePrinter instead. |
| 176 | class PROTOBUF_EXPORT FieldValuePrinter { |
| 177 | public: |
| 178 | FieldValuePrinter(); |
| 179 | virtual ~FieldValuePrinter(); |
| 180 | virtual std::string PrintBool(bool val) const; |
| 181 | virtual std::string PrintInt32(int32_t val) const; |
| 182 | virtual std::string PrintUInt32(uint32_t val) const; |
| 183 | virtual std::string PrintInt64(int64_t val) const; |
| 184 | virtual std::string PrintUInt64(uint64_t val) const; |
| 185 | virtual std::string PrintFloat(float val) const; |
| 186 | virtual std::string PrintDouble(double val) const; |
| 187 | virtual std::string PrintString(const std::string& val) const; |
| 188 | virtual std::string PrintBytes(const std::string& val) const; |
| 189 | virtual std::string PrintEnum(int32_t val, const std::string& name) const; |
| 190 | virtual std::string PrintFieldName(const Message& message, |
| 191 | const Reflection* reflection, |
| 192 | const FieldDescriptor* field) const; |
| 193 | virtual std::string PrintMessageStart(const Message& message, |
| 194 | int field_index, int field_count, |
| 195 | bool single_line_mode) const; |
| 196 | virtual std::string PrintMessageEnd(const Message& message, int field_index, |
| 197 | int field_count, |
| 198 | bool single_line_mode) const; |
| 199 | |
| 200 | private: |
| 201 | FastFieldValuePrinter delegate_; |
| 202 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter); |
| 203 | }; |
| 204 | |
| 205 | class PROTOBUF_EXPORT MessagePrinter { |
| 206 | public: |
| 207 | MessagePrinter() {} |
| 208 | virtual ~MessagePrinter() {} |
| 209 | virtual void Print(const Message& message, bool single_line_mode, |
| 210 | BaseTextGenerator* generator) const = 0; |
| 211 | |
| 212 | private: |
| 213 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessagePrinter); |
| 214 | }; |
| 215 | |
| 216 | // Interface that Printers or Parsers can use to find extensions, or types |
| 217 | // referenced in Any messages. |
| 218 | class PROTOBUF_EXPORT Finder { |
| 219 | public: |
| 220 | virtual ~Finder(); |
| 221 | |
| 222 | // Try to find an extension of *message by fully-qualified field |
| 223 | // name. Returns nullptr if no extension is known for this name or number. |
| 224 | // The base implementation uses the extensions already known by the message. |
| 225 | virtual const FieldDescriptor* FindExtension(Message* message, |
| 226 | const std::string& name) const; |
| 227 | |
| 228 | // Similar to FindExtension, but uses a Descriptor and the extension number |
| 229 | // instead of using a Message and the name when doing the look up. |
| 230 | virtual const FieldDescriptor* FindExtensionByNumber( |
| 231 | const Descriptor* descriptor, int number) const; |
| 232 | |
| 233 | // Find the message type for an Any proto. |
| 234 | // Returns nullptr if no message is known for this name. |
| 235 | // The base implementation only accepts prefixes of type.googleprod.com/ or |
| 236 | // type.googleapis.com/, and searches the DescriptorPool of the parent |
| 237 | // message. |
| 238 | virtual const Descriptor* FindAnyType(const Message& message, |
| 239 | const std::string& prefix, |
| 240 | const std::string& name) const; |
| 241 | |
| 242 | // Find the message factory for the given extension field. This can be used |
| 243 | // to generalize the Parser to add extension fields to a message in the same |
| 244 | // way as the "input" message for the Parser. |
| 245 | virtual MessageFactory* FindExtensionFactory( |
| 246 | const FieldDescriptor* field) const; |
| 247 | }; |
| 248 | |
| 249 | // Class for those users which require more fine-grained control over how |
| 250 | // a protobuffer message is printed out. |
| 251 | class PROTOBUF_EXPORT Printer { |
| 252 | public: |
| 253 | Printer(); |
| 254 | |
| 255 | // Like TextFormat::Print |
| 256 | bool Print(const Message& message, io::ZeroCopyOutputStream* output) const; |
| 257 | // Like TextFormat::PrintUnknownFields |
| 258 | bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, |
| 259 | io::ZeroCopyOutputStream* output) const; |
| 260 | // Like TextFormat::PrintToString |
| 261 | bool PrintToString(const Message& message, std::string* output) const; |
| 262 | // Like TextFormat::PrintUnknownFieldsToString |
| 263 | bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, |
| 264 | std::string* output) const; |
| 265 | // Like TextFormat::PrintFieldValueToString |
| 266 | void PrintFieldValueToString(const Message& message, |
| 267 | const FieldDescriptor* field, int index, |
| 268 | std::string* output) const; |
| 269 | |
| 270 | // Adjust the initial indent level of all output. Each indent level is |
| 271 | // equal to two spaces. |
| 272 | void SetInitialIndentLevel(int indent_level) { |
| 273 | initial_indent_level_ = indent_level; |
| 274 | } |
| 275 | |
| 276 | // If printing in single line mode, then the entire message will be output |
| 277 | // on a single line with no line breaks. |
| 278 | void SetSingleLineMode(bool single_line_mode) { |
| 279 | single_line_mode_ = single_line_mode; |
| 280 | } |
| 281 | |
| 282 | bool IsInSingleLineMode() const { return single_line_mode_; } |
| 283 | |
| 284 | // If use_field_number is true, uses field number instead of field name. |
| 285 | void SetUseFieldNumber(bool use_field_number) { |
| 286 | use_field_number_ = use_field_number; |
| 287 | } |
| 288 | |
| 289 | // Set true to print repeated primitives in a format like: |
| 290 | // field_name: [1, 2, 3, 4] |
| 291 | // instead of printing each value on its own line. Short format applies |
| 292 | // only to primitive values -- i.e. everything except strings and |
| 293 | // sub-messages/groups. |
| 294 | void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { |
| 295 | use_short_repeated_primitives_ = use_short_repeated_primitives; |
| 296 | } |
| 297 | |
| 298 | // Set true to output UTF-8 instead of ASCII. The only difference |
| 299 | // is that bytes >= 0x80 in string fields will not be escaped, |
| 300 | // because they are assumed to be part of UTF-8 multi-byte |
| 301 | // sequences. This will change the default FastFieldValuePrinter. |
| 302 | void SetUseUtf8StringEscaping(bool as_utf8); |
| 303 | |
| 304 | // Set the default FastFieldValuePrinter that is used for all fields that |
| 305 | // don't have a field-specific printer registered. |
| 306 | // Takes ownership of the printer. |
| 307 | void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer); |
| 308 | |
| 309 | PROTOBUF_DEPRECATED_MSG("Please use FastFieldValuePrinter" ) |
| 310 | void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer); |
| 311 | |
| 312 | // Sets whether we want to hide unknown fields or not. |
| 313 | // Usually unknown fields are printed in a generic way that includes the |
| 314 | // tag number of the field instead of field name. However, sometimes it |
| 315 | // is useful to be able to print the message without unknown fields (e.g. |
| 316 | // for the python protobuf version to maintain consistency between its pure |
| 317 | // python and c++ implementations). |
| 318 | void SetHideUnknownFields(bool hide) { hide_unknown_fields_ = hide; } |
| 319 | |
| 320 | // If print_message_fields_in_index_order is true, fields of a proto message |
| 321 | // will be printed using the order defined in source code instead of the |
| 322 | // field number, extensions will be printed at the end of the message |
| 323 | // and their relative order is determined by the extension number. |
| 324 | // By default, use the field number order. |
| 325 | void SetPrintMessageFieldsInIndexOrder( |
| 326 | bool print_message_fields_in_index_order) { |
| 327 | print_message_fields_in_index_order_ = |
| 328 | print_message_fields_in_index_order; |
| 329 | } |
| 330 | |
| 331 | // If expand==true, expand google.protobuf.Any payloads. The output |
| 332 | // will be of form |
| 333 | // [type_url] { <value_printed_in_text> } |
| 334 | // |
| 335 | // If expand==false, print Any using the default printer. The output will |
| 336 | // look like |
| 337 | // type_url: "<type_url>" value: "serialized_content" |
| 338 | void SetExpandAny(bool expand) { expand_any_ = expand; } |
| 339 | |
| 340 | // Set how parser finds message for Any payloads. |
| 341 | void SetFinder(const Finder* finder) { finder_ = finder; } |
| 342 | |
| 343 | // If non-zero, we truncate all string fields that are longer than |
| 344 | // this threshold. This is useful when the proto message has very long |
| 345 | // strings, e.g., dump of encoded image file. |
| 346 | // |
| 347 | // NOTE(hfgong): Setting a non-zero value breaks round-trip safe |
| 348 | // property of TextFormat::Printer. That is, from the printed message, we |
| 349 | // cannot fully recover the original string field any more. |
| 350 | void SetTruncateStringFieldLongerThan( |
| 351 | const int64_t truncate_string_field_longer_than) { |
| 352 | truncate_string_field_longer_than_ = truncate_string_field_longer_than; |
| 353 | } |
| 354 | |
| 355 | // Register a custom field-specific FastFieldValuePrinter for fields |
| 356 | // with a particular FieldDescriptor. |
| 357 | // Returns "true" if the registration succeeded, or "false", if there is |
| 358 | // already a printer for that FieldDescriptor. |
| 359 | // Takes ownership of the printer on successful registration. |
| 360 | bool RegisterFieldValuePrinter(const FieldDescriptor* field, |
| 361 | const FastFieldValuePrinter* printer); |
| 362 | |
| 363 | PROTOBUF_DEPRECATED_MSG("Please use FastFieldValuePrinter" ) |
| 364 | bool RegisterFieldValuePrinter(const FieldDescriptor* field, |
| 365 | const FieldValuePrinter* printer); |
| 366 | |
| 367 | // Register a custom message-specific MessagePrinter for messages with a |
| 368 | // particular Descriptor. |
| 369 | // Returns "true" if the registration succeeded, or "false" if there is |
| 370 | // already a printer for that Descriptor. |
| 371 | bool RegisterMessagePrinter(const Descriptor* descriptor, |
| 372 | const MessagePrinter* printer); |
| 373 | |
| 374 | private: |
| 375 | friend std::string Message::DebugString() const; |
| 376 | friend std::string Message::ShortDebugString() const; |
| 377 | friend std::string Message::Utf8DebugString() const; |
| 378 | |
| 379 | // Sets whether *DebugString should insert a silent marker. |
| 380 | void SetInsertSilentMarker(bool v) { insert_silent_marker_ = v; } |
| 381 | |
| 382 | // Forward declaration of an internal class used to print the text |
| 383 | // output to the OutputStream (see text_format.cc for implementation). |
| 384 | class TextGenerator; |
| 385 | |
| 386 | // Forward declaration of an internal class used to print field values for |
| 387 | // DebugString APIs (see text_format.cc for implementation). |
| 388 | class DebugStringFieldValuePrinter; |
| 389 | |
| 390 | // Forward declaration of an internal class used to print UTF-8 escaped |
| 391 | // strings (see text_format.cc for implementation). |
| 392 | class FastFieldValuePrinterUtf8Escaping; |
| 393 | |
| 394 | static const char* const kDoNotParse; |
| 395 | |
| 396 | // Internal Print method, used for writing to the OutputStream via |
| 397 | // the TextGenerator class. |
| 398 | void Print(const Message& message, TextGenerator* generator) const; |
| 399 | |
| 400 | // Print a single field. |
| 401 | void PrintField(const Message& message, const Reflection* reflection, |
| 402 | const FieldDescriptor* field, |
| 403 | TextGenerator* generator) const; |
| 404 | |
| 405 | // Print a repeated primitive field in short form. |
| 406 | void PrintShortRepeatedField(const Message& message, |
| 407 | const Reflection* reflection, |
| 408 | const FieldDescriptor* field, |
| 409 | TextGenerator* generator) const; |
| 410 | |
| 411 | // Print the name of a field -- i.e. everything that comes before the |
| 412 | // ':' for a single name/value pair. |
| 413 | void PrintFieldName(const Message& message, int field_index, |
| 414 | int field_count, const Reflection* reflection, |
| 415 | const FieldDescriptor* field, |
| 416 | TextGenerator* generator) const; |
| 417 | |
| 418 | // Outputs a textual representation of the value of the field supplied on |
| 419 | // the message supplied or the default value if not set. |
| 420 | void PrintFieldValue(const Message& message, const Reflection* reflection, |
| 421 | const FieldDescriptor* field, int index, |
| 422 | TextGenerator* generator) const; |
| 423 | |
| 424 | // Print the fields in an UnknownFieldSet. They are printed by tag number |
| 425 | // only. Embedded messages are heuristically identified by attempting to |
| 426 | // parse them (subject to the recursion budget). |
| 427 | void PrintUnknownFields(const UnknownFieldSet& unknown_fields, |
| 428 | TextGenerator* generator, |
| 429 | int recursion_budget) const; |
| 430 | |
| 431 | bool PrintAny(const Message& message, TextGenerator* generator) const; |
| 432 | |
| 433 | const FastFieldValuePrinter* GetFieldPrinter( |
| 434 | const FieldDescriptor* field) const { |
| 435 | auto it = custom_printers_.find(x: field); |
| 436 | return it == custom_printers_.end() ? default_field_value_printer_.get() |
| 437 | : it->second.get(); |
| 438 | } |
| 439 | |
| 440 | int initial_indent_level_; |
| 441 | bool single_line_mode_; |
| 442 | bool use_field_number_; |
| 443 | bool use_short_repeated_primitives_; |
| 444 | bool insert_silent_marker_; |
| 445 | bool hide_unknown_fields_; |
| 446 | bool print_message_fields_in_index_order_; |
| 447 | bool expand_any_; |
| 448 | int64_t truncate_string_field_longer_than_; |
| 449 | |
| 450 | std::unique_ptr<const FastFieldValuePrinter> default_field_value_printer_; |
| 451 | typedef std::map<const FieldDescriptor*, |
| 452 | std::unique_ptr<const FastFieldValuePrinter>> |
| 453 | CustomPrinterMap; |
| 454 | CustomPrinterMap custom_printers_; |
| 455 | |
| 456 | typedef std::map<const Descriptor*, std::unique_ptr<const MessagePrinter>> |
| 457 | CustomMessagePrinterMap; |
| 458 | CustomMessagePrinterMap custom_message_printers_; |
| 459 | |
| 460 | const Finder* finder_; |
| 461 | }; |
| 462 | |
| 463 | // Parses a text-format protocol message from the given input stream to |
| 464 | // the given message object. This function parses the human-readable |
| 465 | // serialization format written by Print(). Returns true on success. The |
| 466 | // message is cleared first, even if the function fails -- See Merge() to |
| 467 | // avoid this behavior. |
| 468 | // |
| 469 | // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}" |
| 470 | // |
| 471 | // One common use for this function is parsing handwritten strings in test |
| 472 | // code. |
| 473 | // |
| 474 | // If you would like to read a protocol buffer serialized in the |
| 475 | // (non-human-readable) binary wire format, see |
| 476 | // google::protobuf::MessageLite::ParseFromString(). |
| 477 | static bool Parse(io::ZeroCopyInputStream* input, Message* output); |
| 478 | // Like Parse(), but reads directly from a string. |
| 479 | static bool ParseFromString(ConstStringParam input, Message* output); |
| 480 | |
| 481 | // Like Parse(), but the data is merged into the given message, as if |
| 482 | // using Message::MergeFrom(). |
| 483 | static bool Merge(io::ZeroCopyInputStream* input, Message* output); |
| 484 | // Like Merge(), but reads directly from a string. |
| 485 | static bool MergeFromString(ConstStringParam input, Message* output); |
| 486 | |
| 487 | // Parse the given text as a single field value and store it into the |
| 488 | // given field of the given message. If the field is a repeated field, |
| 489 | // the new value will be added to the end |
| 490 | static bool ParseFieldValueFromString(const std::string& input, |
| 491 | const FieldDescriptor* field, |
| 492 | Message* message); |
| 493 | |
| 494 | // A location in the parsed text. |
| 495 | struct ParseLocation { |
| 496 | int line; |
| 497 | int column; |
| 498 | |
| 499 | ParseLocation() : line(-1), column(-1) {} |
| 500 | ParseLocation(int line_param, int column_param) |
| 501 | : line(line_param), column(column_param) {} |
| 502 | }; |
| 503 | |
| 504 | // A range of locations in the parsed text, including `start` and excluding |
| 505 | // `end`. |
| 506 | struct ParseLocationRange { |
| 507 | ParseLocation start; |
| 508 | ParseLocation end; |
| 509 | ParseLocationRange() : start(), end() {} |
| 510 | ParseLocationRange(ParseLocation start_param, ParseLocation end_param) |
| 511 | : start(start_param), end(end_param) {} |
| 512 | }; |
| 513 | |
| 514 | // Data structure which is populated with the locations of each field |
| 515 | // value parsed from the text. |
| 516 | class PROTOBUF_EXPORT ParseInfoTree { |
| 517 | public: |
| 518 | ParseInfoTree() = default; |
| 519 | ParseInfoTree(const ParseInfoTree&) = delete; |
| 520 | ParseInfoTree& operator=(const ParseInfoTree&) = delete; |
| 521 | |
| 522 | // Returns the parse location range for index-th value of the field in |
| 523 | // the parsed text. If none exists, returns a location with start and end |
| 524 | // line -1. Index should be -1 for not-repeated fields. |
| 525 | ParseLocationRange GetLocationRange(const FieldDescriptor* field, |
| 526 | int index) const; |
| 527 | |
| 528 | // Returns the starting parse location for index-th value of the field in |
| 529 | // the parsed text. If none exists, returns a location with line = -1. Index |
| 530 | // should be -1 for not-repeated fields. |
| 531 | ParseLocation GetLocation(const FieldDescriptor* field, int index) const { |
| 532 | return GetLocationRange(field, index).start; |
| 533 | } |
| 534 | |
| 535 | // Returns the parse info tree for the given field, which must be a message |
| 536 | // type. The nested information tree is owned by the root tree and will be |
| 537 | // deleted when it is deleted. |
| 538 | ParseInfoTree* GetTreeForNested(const FieldDescriptor* field, |
| 539 | int index) const; |
| 540 | |
| 541 | private: |
| 542 | // Allow the text format parser to record information into the tree. |
| 543 | friend class TextFormat; |
| 544 | |
| 545 | // Records the starting and ending locations of a single value for a field. |
| 546 | void RecordLocation(const FieldDescriptor* field, ParseLocationRange range); |
| 547 | |
| 548 | // Create and records a nested tree for a nested message field. |
| 549 | ParseInfoTree* CreateNested(const FieldDescriptor* field); |
| 550 | |
| 551 | // Defines the map from the index-th field descriptor to its parse location. |
| 552 | typedef std::map<const FieldDescriptor*, std::vector<ParseLocationRange>> |
| 553 | LocationMap; |
| 554 | |
| 555 | // Defines the map from the index-th field descriptor to the nested parse |
| 556 | // info tree. |
| 557 | typedef std::map<const FieldDescriptor*, |
| 558 | std::vector<std::unique_ptr<ParseInfoTree>>> |
| 559 | NestedMap; |
| 560 | |
| 561 | LocationMap locations_; |
| 562 | NestedMap nested_; |
| 563 | }; |
| 564 | |
| 565 | // For more control over parsing, use this class. |
| 566 | class PROTOBUF_EXPORT Parser { |
| 567 | public: |
| 568 | Parser(); |
| 569 | ~Parser(); |
| 570 | |
| 571 | // Like TextFormat::Parse(). |
| 572 | bool Parse(io::ZeroCopyInputStream* input, Message* output); |
| 573 | // Like TextFormat::ParseFromString(). |
| 574 | bool ParseFromString(ConstStringParam input, Message* output); |
| 575 | // Like TextFormat::Merge(). |
| 576 | bool Merge(io::ZeroCopyInputStream* input, Message* output); |
| 577 | // Like TextFormat::MergeFromString(). |
| 578 | bool MergeFromString(ConstStringParam input, Message* output); |
| 579 | |
| 580 | // Set where to report parse errors. If nullptr (the default), errors will |
| 581 | // be printed to stderr. |
| 582 | void RecordErrorsTo(io::ErrorCollector* error_collector) { |
| 583 | error_collector_ = error_collector; |
| 584 | } |
| 585 | |
| 586 | // Set how parser finds extensions. If nullptr (the default), the |
| 587 | // parser will use the standard Reflection object associated with |
| 588 | // the message being parsed. |
| 589 | void SetFinder(const Finder* finder) { finder_ = finder; } |
| 590 | |
| 591 | // Sets where location information about the parse will be written. If |
| 592 | // nullptr |
| 593 | // (the default), then no location will be written. |
| 594 | void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; } |
| 595 | |
| 596 | // Normally parsing fails if, after parsing, output->IsInitialized() |
| 597 | // returns false. Call AllowPartialMessage(true) to skip this check. |
| 598 | void AllowPartialMessage(bool allow) { allow_partial_ = allow; } |
| 599 | |
| 600 | // Allow field names to be matched case-insensitively. |
| 601 | // This is not advisable if there are fields that only differ in case, or |
| 602 | // if you want to enforce writing in the canonical form. |
| 603 | // This is 'false' by default. |
| 604 | void AllowCaseInsensitiveField(bool allow) { |
| 605 | allow_case_insensitive_field_ = allow; |
| 606 | } |
| 607 | |
| 608 | // Like TextFormat::ParseFieldValueFromString |
| 609 | bool ParseFieldValueFromString(const std::string& input, |
| 610 | const FieldDescriptor* field, |
| 611 | Message* output); |
| 612 | |
| 613 | // When an unknown extension is met, parsing will fail if this option is |
| 614 | // set to false (the default). If true, unknown extensions will be ignored |
| 615 | // and a warning message will be generated. |
| 616 | // Beware! Setting this option true may hide some errors (e.g. spelling |
| 617 | // error on extension name). This allows data loss; unlike binary format, |
| 618 | // text format cannot preserve unknown extensions. Avoid using this option |
| 619 | // if possible. |
| 620 | void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; } |
| 621 | |
| 622 | // When an unknown field is met, parsing will fail if this option is set |
| 623 | // to false (the default). If true, unknown fields will be ignored and |
| 624 | // a warning message will be generated. |
| 625 | // Beware! Setting this option true may hide some errors (e.g. spelling |
| 626 | // error on field name). This allows data loss; unlike binary format, text |
| 627 | // format cannot preserve unknown fields. Avoid using this option |
| 628 | // if possible. |
| 629 | void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; } |
| 630 | |
| 631 | |
| 632 | void AllowFieldNumber(bool allow) { allow_field_number_ = allow; } |
| 633 | |
| 634 | // Sets maximum recursion depth which parser can use. This is effectively |
| 635 | // the maximum allowed nesting of proto messages. |
| 636 | void SetRecursionLimit(int limit) { recursion_limit_ = limit; } |
| 637 | |
| 638 | private: |
| 639 | // Forward declaration of an internal class used to parse text |
| 640 | // representations (see text_format.cc for implementation). |
| 641 | class ParserImpl; |
| 642 | |
| 643 | // Like TextFormat::Merge(). The provided implementation is used |
| 644 | // to do the parsing. |
| 645 | bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output, |
| 646 | ParserImpl* parser_impl); |
| 647 | |
| 648 | io::ErrorCollector* error_collector_; |
| 649 | const Finder* finder_; |
| 650 | ParseInfoTree* parse_info_tree_; |
| 651 | bool allow_partial_; |
| 652 | bool allow_case_insensitive_field_; |
| 653 | bool allow_unknown_field_; |
| 654 | bool allow_unknown_extension_; |
| 655 | bool allow_unknown_enum_; |
| 656 | bool allow_field_number_; |
| 657 | bool allow_relaxed_whitespace_; |
| 658 | bool allow_singular_overwrites_; |
| 659 | int recursion_limit_; |
| 660 | }; |
| 661 | |
| 662 | |
| 663 | private: |
| 664 | // Hack: ParseInfoTree declares TextFormat as a friend which should extend |
| 665 | // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some |
| 666 | // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide |
| 667 | // helpers for ParserImpl to call methods of ParseInfoTree. |
| 668 | static inline void RecordLocation(ParseInfoTree* info_tree, |
| 669 | const FieldDescriptor* field, |
| 670 | ParseLocationRange location); |
| 671 | static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree, |
| 672 | const FieldDescriptor* field); |
| 673 | |
| 674 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); |
| 675 | }; |
| 676 | |
| 677 | inline void TextFormat::RecordLocation(ParseInfoTree* info_tree, |
| 678 | const FieldDescriptor* field, |
| 679 | ParseLocationRange location) { |
| 680 | info_tree->RecordLocation(field, range: location); |
| 681 | } |
| 682 | |
| 683 | inline TextFormat::ParseInfoTree* TextFormat::CreateNested( |
| 684 | ParseInfoTree* info_tree, const FieldDescriptor* field) { |
| 685 | return info_tree->CreateNested(field); |
| 686 | } |
| 687 | |
| 688 | } // namespace protobuf |
| 689 | } // namespace google |
| 690 | |
| 691 | #include <google/protobuf/port_undef.inc> |
| 692 | |
| 693 | #endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ |
| 694 | |