Armelle Laine | 2f5a707 | 2022-11-06 19:03:46 +0000 | [diff] [blame] | 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 | #include <google/protobuf/text_format.h> |
| 36 | |
| 37 | #include <float.h> |
| 38 | #include <stdio.h> |
| 39 | |
| 40 | #include <algorithm> |
| 41 | #include <atomic> |
| 42 | #include <climits> |
| 43 | #include <cmath> |
| 44 | #include <limits> |
| 45 | #include <utility> |
| 46 | #include <vector> |
| 47 | |
| 48 | #include <google/protobuf/io/coded_stream.h> |
| 49 | #include <google/protobuf/io/tokenizer.h> |
| 50 | #include <google/protobuf/io/zero_copy_stream.h> |
| 51 | #include <google/protobuf/io/zero_copy_stream_impl.h> |
| 52 | #include <google/protobuf/stubs/strutil.h> |
| 53 | #include <google/protobuf/any.h> |
| 54 | #include <google/protobuf/descriptor.h> |
| 55 | #include <google/protobuf/descriptor.pb.h> |
| 56 | #include <google/protobuf/dynamic_message.h> |
| 57 | #include <google/protobuf/io/strtod.h> |
| 58 | #include <google/protobuf/map_field.h> |
| 59 | #include <google/protobuf/message.h> |
| 60 | #include <google/protobuf/repeated_field.h> |
| 61 | #include <google/protobuf/unknown_field_set.h> |
| 62 | #include <google/protobuf/wire_format_lite.h> |
| 63 | #include <google/protobuf/stubs/map_util.h> |
| 64 | #include <google/protobuf/stubs/stl_util.h> |
| 65 | |
| 66 | // Must be included last. |
| 67 | #include <google/protobuf/port_def.inc> |
| 68 | |
| 69 | namespace google { |
| 70 | namespace protobuf { |
| 71 | |
| 72 | namespace { |
| 73 | |
| 74 | inline bool IsHexNumber(const std::string& str) { |
| 75 | return (str.length() >= 2 && str[0] == '0' && |
| 76 | (str[1] == 'x' || str[1] == 'X')); |
| 77 | } |
| 78 | |
| 79 | inline bool IsOctNumber(const std::string& str) { |
| 80 | return (str.length() >= 2 && str[0] == '0' && |
| 81 | (str[1] >= '0' && str[1] < '8')); |
| 82 | } |
| 83 | |
| 84 | } // namespace |
| 85 | |
| 86 | namespace internal { |
| 87 | const char kDebugStringSilentMarker[] = ""; |
| 88 | const char kDebugStringSilentMarkerForDetection[] = "\t "; |
| 89 | |
| 90 | // Controls insertion of kDebugStringSilentMarker. |
| 91 | PROTOBUF_EXPORT std::atomic<bool> enable_debug_text_format_marker; |
| 92 | } // namespace internal |
| 93 | |
| 94 | std::string Message::DebugString() const { |
| 95 | std::string debug_string; |
| 96 | |
| 97 | TextFormat::Printer printer; |
| 98 | printer.SetExpandAny(true); |
| 99 | printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load( |
| 100 | std::memory_order_relaxed)); |
| 101 | |
| 102 | printer.PrintToString(*this, &debug_string); |
| 103 | |
| 104 | return debug_string; |
| 105 | } |
| 106 | |
| 107 | std::string Message::ShortDebugString() const { |
| 108 | std::string debug_string; |
| 109 | |
| 110 | TextFormat::Printer printer; |
| 111 | printer.SetSingleLineMode(true); |
| 112 | printer.SetExpandAny(true); |
| 113 | printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load( |
| 114 | std::memory_order_relaxed)); |
| 115 | |
| 116 | printer.PrintToString(*this, &debug_string); |
| 117 | // Single line mode currently might have an extra space at the end. |
| 118 | if (!debug_string.empty() && debug_string[debug_string.size() - 1] == ' ') { |
| 119 | debug_string.resize(debug_string.size() - 1); |
| 120 | } |
| 121 | |
| 122 | return debug_string; |
| 123 | } |
| 124 | |
| 125 | std::string Message::Utf8DebugString() const { |
| 126 | std::string debug_string; |
| 127 | |
| 128 | TextFormat::Printer printer; |
| 129 | printer.SetUseUtf8StringEscaping(true); |
| 130 | printer.SetExpandAny(true); |
| 131 | printer.SetInsertSilentMarker(internal::enable_debug_text_format_marker.load( |
| 132 | std::memory_order_relaxed)); |
| 133 | |
| 134 | printer.PrintToString(*this, &debug_string); |
| 135 | |
| 136 | return debug_string; |
| 137 | } |
| 138 | |
| 139 | void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); } |
| 140 | |
| 141 | |
| 142 | // =========================================================================== |
| 143 | // Implementation of the parse information tree class. |
| 144 | void TextFormat::ParseInfoTree::RecordLocation( |
| 145 | const FieldDescriptor* field, TextFormat::ParseLocationRange range) { |
| 146 | locations_[field].push_back(range); |
| 147 | } |
| 148 | |
| 149 | TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( |
| 150 | const FieldDescriptor* field) { |
| 151 | // Owned by us in the map. |
| 152 | auto& vec = nested_[field]; |
| 153 | vec.emplace_back(new TextFormat::ParseInfoTree()); |
| 154 | return vec.back().get(); |
| 155 | } |
| 156 | |
| 157 | void CheckFieldIndex(const FieldDescriptor* field, int index) { |
| 158 | if (field == nullptr) { |
| 159 | return; |
| 160 | } |
| 161 | |
| 162 | if (field->is_repeated() && index == -1) { |
| 163 | GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. " |
| 164 | << "Field: " << field->name(); |
| 165 | } else if (!field->is_repeated() && index != -1) { |
| 166 | GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields." |
| 167 | << "Field: " << field->name(); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | TextFormat::ParseLocationRange TextFormat::ParseInfoTree::GetLocationRange( |
| 172 | const FieldDescriptor* field, int index) const { |
| 173 | CheckFieldIndex(field, index); |
| 174 | if (index == -1) { |
| 175 | index = 0; |
| 176 | } |
| 177 | |
| 178 | const std::vector<TextFormat::ParseLocationRange>* locations = |
| 179 | FindOrNull(locations_, field); |
| 180 | if (locations == nullptr || |
| 181 | index >= static_cast<int64_t>(locations->size())) { |
| 182 | return TextFormat::ParseLocationRange(); |
| 183 | } |
| 184 | |
| 185 | return (*locations)[index]; |
| 186 | } |
| 187 | |
| 188 | TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( |
| 189 | const FieldDescriptor* field, int index) const { |
| 190 | CheckFieldIndex(field, index); |
| 191 | if (index == -1) { |
| 192 | index = 0; |
| 193 | } |
| 194 | |
| 195 | auto it = nested_.find(field); |
| 196 | if (it == nested_.end() || index >= static_cast<int64_t>(it->second.size())) { |
| 197 | return nullptr; |
| 198 | } |
| 199 | |
| 200 | return it->second[index].get(); |
| 201 | } |
| 202 | |
| 203 | namespace { |
| 204 | // These functions implement the behavior of the "default" TextFormat::Finder, |
| 205 | // they are defined as standalone to be called when finder_ is nullptr. |
| 206 | const FieldDescriptor* DefaultFinderFindExtension(Message* message, |
| 207 | const std::string& name) { |
| 208 | const Descriptor* descriptor = message->GetDescriptor(); |
| 209 | return descriptor->file()->pool()->FindExtensionByPrintableName(descriptor, |
| 210 | name); |
| 211 | } |
| 212 | |
| 213 | const FieldDescriptor* DefaultFinderFindExtensionByNumber( |
| 214 | const Descriptor* descriptor, int number) { |
| 215 | return descriptor->file()->pool()->FindExtensionByNumber(descriptor, number); |
| 216 | } |
| 217 | |
| 218 | const Descriptor* DefaultFinderFindAnyType(const Message& message, |
| 219 | const std::string& prefix, |
| 220 | const std::string& name) { |
| 221 | if (prefix != internal::kTypeGoogleApisComPrefix && |
| 222 | prefix != internal::kTypeGoogleProdComPrefix) { |
| 223 | return nullptr; |
| 224 | } |
| 225 | return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name); |
| 226 | } |
| 227 | } // namespace |
| 228 | |
| 229 | // =========================================================================== |
| 230 | // Internal class for parsing an ASCII representation of a Protocol Message. |
| 231 | // This class makes use of the Protocol Message compiler's tokenizer found |
| 232 | // in //net/proto2/io/public/tokenizer.h. Note that class's Parse |
| 233 | // method is *not* thread-safe and should only be used in a single thread at |
| 234 | // a time. |
| 235 | |
| 236 | // Makes code slightly more readable. The meaning of "DO(foo)" is |
| 237 | // "Execute foo and fail if it fails.", where failure is indicated by |
| 238 | // returning false. Borrowed from parser.cc (Thanks Kenton!). |
| 239 | #define DO(STATEMENT) \ |
| 240 | if (STATEMENT) { \ |
| 241 | } else { \ |
| 242 | return false; \ |
| 243 | } |
| 244 | |
| 245 | class TextFormat::Parser::ParserImpl { |
| 246 | public: |
| 247 | // Determines if repeated values for non-repeated fields and |
| 248 | // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a |
| 249 | // required/optional field named "foo", or "baz: 1 bar: 2" |
| 250 | // where "baz" and "bar" are members of the same oneof. |
| 251 | enum SingularOverwritePolicy { |
| 252 | ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained |
| 253 | FORBID_SINGULAR_OVERWRITES = 1, // an error is issued |
| 254 | }; |
| 255 | |
| 256 | ParserImpl(const Descriptor* root_message_type, |
| 257 | io::ZeroCopyInputStream* input_stream, |
| 258 | io::ErrorCollector* error_collector, |
| 259 | const TextFormat::Finder* finder, ParseInfoTree* parse_info_tree, |
| 260 | SingularOverwritePolicy singular_overwrite_policy, |
| 261 | bool allow_case_insensitive_field, bool allow_unknown_field, |
| 262 | bool allow_unknown_extension, bool allow_unknown_enum, |
| 263 | bool allow_field_number, bool allow_relaxed_whitespace, |
| 264 | bool allow_partial, int recursion_limit) |
| 265 | : error_collector_(error_collector), |
| 266 | finder_(finder), |
| 267 | parse_info_tree_(parse_info_tree), |
| 268 | tokenizer_error_collector_(this), |
| 269 | tokenizer_(input_stream, &tokenizer_error_collector_), |
| 270 | root_message_type_(root_message_type), |
| 271 | singular_overwrite_policy_(singular_overwrite_policy), |
| 272 | allow_case_insensitive_field_(allow_case_insensitive_field), |
| 273 | allow_unknown_field_(allow_unknown_field), |
| 274 | allow_unknown_extension_(allow_unknown_extension), |
| 275 | allow_unknown_enum_(allow_unknown_enum), |
| 276 | allow_field_number_(allow_field_number), |
| 277 | allow_partial_(allow_partial), |
| 278 | initial_recursion_limit_(recursion_limit), |
| 279 | recursion_limit_(recursion_limit), |
| 280 | had_silent_marker_(false), |
| 281 | had_errors_(false) { |
| 282 | // For backwards-compatibility with proto1, we need to allow the 'f' suffix |
| 283 | // for floats. |
| 284 | tokenizer_.set_allow_f_after_float(true); |
| 285 | |
| 286 | // '#' starts a comment. |
| 287 | tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); |
| 288 | |
| 289 | if (allow_relaxed_whitespace) { |
| 290 | tokenizer_.set_require_space_after_number(false); |
| 291 | tokenizer_.set_allow_multiline_strings(true); |
| 292 | } |
| 293 | |
| 294 | // Consume the starting token. |
| 295 | tokenizer_.Next(); |
| 296 | } |
| 297 | ~ParserImpl() {} |
| 298 | |
| 299 | // Parses the ASCII representation specified in input and saves the |
| 300 | // information into the output pointer (a Message). Returns |
| 301 | // false if an error occurs (an error will also be logged to |
| 302 | // GOOGLE_LOG(ERROR)). |
| 303 | bool Parse(Message* output) { |
| 304 | // Consume fields until we cannot do so anymore. |
| 305 | while (true) { |
| 306 | if (LookingAtType(io::Tokenizer::TYPE_END)) { |
| 307 | // Ensures recursion limit properly unwinded, but only for success |
| 308 | // cases. This implicitly avoids the check when `Parse` returns false |
| 309 | // via `DO(...)`. |
| 310 | GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_) |
| 311 | << "Recursion limit at end of parse should be " |
| 312 | << initial_recursion_limit_ << ", but was " << recursion_limit_ |
| 313 | << ". Difference of " << initial_recursion_limit_ - recursion_limit_ |
| 314 | << " stack frames not accounted for stack unwind."; |
| 315 | |
| 316 | return !had_errors_; |
| 317 | } |
| 318 | |
| 319 | DO(ConsumeField(output)); |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | bool ParseField(const FieldDescriptor* field, Message* output) { |
| 324 | bool suc; |
| 325 | if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 326 | suc = ConsumeFieldMessage(output, output->GetReflection(), field); |
| 327 | } else { |
| 328 | suc = ConsumeFieldValue(output, output->GetReflection(), field); |
| 329 | } |
| 330 | return suc && LookingAtType(io::Tokenizer::TYPE_END); |
| 331 | } |
| 332 | |
| 333 | void ReportError(int line, int col, const std::string& message) { |
| 334 | had_errors_ = true; |
| 335 | if (error_collector_ == nullptr) { |
| 336 | if (line >= 0) { |
| 337 | GOOGLE_LOG(ERROR) << "Error parsing text-format " |
| 338 | << root_message_type_->full_name() << ": " << (line + 1) |
| 339 | << ":" << (col + 1) << ": " << message; |
| 340 | } else { |
| 341 | GOOGLE_LOG(ERROR) << "Error parsing text-format " |
| 342 | << root_message_type_->full_name() << ": " << message; |
| 343 | } |
| 344 | } else { |
| 345 | error_collector_->AddError(line, col, message); |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | void ReportWarning(int line, int col, const std::string& message) { |
| 350 | if (error_collector_ == nullptr) { |
| 351 | if (line >= 0) { |
| 352 | GOOGLE_LOG(WARNING) << "Warning parsing text-format " |
| 353 | << root_message_type_->full_name() << ": " << (line + 1) |
| 354 | << ":" << (col + 1) << ": " << message; |
| 355 | } else { |
| 356 | GOOGLE_LOG(WARNING) << "Warning parsing text-format " |
| 357 | << root_message_type_->full_name() << ": " << message; |
| 358 | } |
| 359 | } else { |
| 360 | error_collector_->AddWarning(line, col, message); |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | private: |
| 365 | static constexpr int32_t kint32max = std::numeric_limits<int32_t>::max(); |
| 366 | static constexpr uint32_t kuint32max = std::numeric_limits<uint32_t>::max(); |
| 367 | static constexpr int64_t kint64min = std::numeric_limits<int64_t>::min(); |
| 368 | static constexpr int64_t kint64max = std::numeric_limits<int64_t>::max(); |
| 369 | static constexpr uint64_t kuint64max = std::numeric_limits<uint64_t>::max(); |
| 370 | |
| 371 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); |
| 372 | |
| 373 | // Reports an error with the given message with information indicating |
| 374 | // the position (as derived from the current token). |
| 375 | void ReportError(const std::string& message) { |
| 376 | ReportError(tokenizer_.current().line, tokenizer_.current().column, |
| 377 | message); |
| 378 | } |
| 379 | |
| 380 | // Reports a warning with the given message with information indicating |
| 381 | // the position (as derived from the current token). |
| 382 | void ReportWarning(const std::string& message) { |
| 383 | ReportWarning(tokenizer_.current().line, tokenizer_.current().column, |
| 384 | message); |
| 385 | } |
| 386 | |
| 387 | // Consumes the specified message with the given starting delimiter. |
| 388 | // This method checks to see that the end delimiter at the conclusion of |
| 389 | // the consumption matches the starting delimiter passed in here. |
| 390 | bool ConsumeMessage(Message* message, const std::string delimiter) { |
| 391 | while (!LookingAt(">") && !LookingAt("}")) { |
| 392 | DO(ConsumeField(message)); |
| 393 | } |
| 394 | |
| 395 | // Confirm that we have a valid ending delimiter. |
| 396 | DO(Consume(delimiter)); |
| 397 | return true; |
| 398 | } |
| 399 | |
| 400 | // Consume either "<" or "{". |
| 401 | bool ConsumeMessageDelimiter(std::string* delimiter) { |
| 402 | if (TryConsume("<")) { |
| 403 | *delimiter = ">"; |
| 404 | } else { |
| 405 | DO(Consume("{")); |
| 406 | *delimiter = "}"; |
| 407 | } |
| 408 | return true; |
| 409 | } |
| 410 | |
| 411 | |
| 412 | // Consumes the current field (as returned by the tokenizer) on the |
| 413 | // passed in message. |
| 414 | bool ConsumeField(Message* message) { |
| 415 | const Reflection* reflection = message->GetReflection(); |
| 416 | const Descriptor* descriptor = message->GetDescriptor(); |
| 417 | |
| 418 | std::string field_name; |
| 419 | bool reserved_field = false; |
| 420 | const FieldDescriptor* field = nullptr; |
| 421 | int start_line = tokenizer_.current().line; |
| 422 | int start_column = tokenizer_.current().column; |
| 423 | |
| 424 | const FieldDescriptor* any_type_url_field; |
| 425 | const FieldDescriptor* any_value_field; |
| 426 | if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field, |
| 427 | &any_value_field) && |
| 428 | TryConsume("[")) { |
| 429 | std::string full_type_name, prefix; |
| 430 | DO(ConsumeAnyTypeUrl(&full_type_name, &prefix)); |
| 431 | std::string prefix_and_full_type_name = |
| 432 | StrCat(prefix, full_type_name); |
| 433 | DO(ConsumeBeforeWhitespace("]")); |
| 434 | TryConsumeWhitespace(); |
| 435 | // ':' is optional between message labels and values. |
| 436 | if (TryConsumeBeforeWhitespace(":")) { |
| 437 | TryConsumeWhitespace(); |
| 438 | } |
| 439 | std::string serialized_value; |
| 440 | const Descriptor* value_descriptor = |
| 441 | finder_ ? finder_->FindAnyType(*message, prefix, full_type_name) |
| 442 | : DefaultFinderFindAnyType(*message, prefix, full_type_name); |
| 443 | if (value_descriptor == nullptr) { |
| 444 | ReportError("Could not find type \"" + prefix_and_full_type_name + |
| 445 | "\" stored in google.protobuf.Any."); |
| 446 | return false; |
| 447 | } |
| 448 | DO(ConsumeAnyValue(value_descriptor, &serialized_value)); |
| 449 | if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { |
| 450 | // Fail if any_type_url_field has already been specified. |
| 451 | if ((!any_type_url_field->is_repeated() && |
| 452 | reflection->HasField(*message, any_type_url_field)) || |
| 453 | (!any_value_field->is_repeated() && |
| 454 | reflection->HasField(*message, any_value_field))) { |
| 455 | ReportError("Non-repeated Any specified multiple times."); |
| 456 | return false; |
| 457 | } |
| 458 | } |
| 459 | reflection->SetString(message, any_type_url_field, |
| 460 | std::move(prefix_and_full_type_name)); |
| 461 | reflection->SetString(message, any_value_field, |
| 462 | std::move(serialized_value)); |
| 463 | return true; |
| 464 | } |
| 465 | if (TryConsume("[")) { |
| 466 | // Extension. |
| 467 | DO(ConsumeFullTypeName(&field_name)); |
| 468 | DO(ConsumeBeforeWhitespace("]")); |
| 469 | TryConsumeWhitespace(); |
| 470 | |
| 471 | field = finder_ ? finder_->FindExtension(message, field_name) |
| 472 | : DefaultFinderFindExtension(message, field_name); |
| 473 | |
| 474 | if (field == nullptr) { |
| 475 | if (!allow_unknown_field_ && !allow_unknown_extension_) { |
| 476 | ReportError("Extension \"" + field_name + |
| 477 | "\" is not defined or " |
| 478 | "is not an extension of \"" + |
| 479 | descriptor->full_name() + "\"."); |
| 480 | return false; |
| 481 | } else { |
| 482 | ReportWarning("Ignoring extension \"" + field_name + |
| 483 | "\" which is not defined or is not an extension of \"" + |
| 484 | descriptor->full_name() + "\"."); |
| 485 | } |
| 486 | } |
| 487 | } else { |
| 488 | DO(ConsumeIdentifierBeforeWhitespace(&field_name)); |
| 489 | TryConsumeWhitespace(); |
| 490 | |
| 491 | int32_t field_number; |
| 492 | if (allow_field_number_ && safe_strto32(field_name, &field_number)) { |
| 493 | if (descriptor->IsExtensionNumber(field_number)) { |
| 494 | field = finder_ |
| 495 | ? finder_->FindExtensionByNumber(descriptor, field_number) |
| 496 | : DefaultFinderFindExtensionByNumber(descriptor, |
| 497 | field_number); |
| 498 | } else if (descriptor->IsReservedNumber(field_number)) { |
| 499 | reserved_field = true; |
| 500 | } else { |
| 501 | field = descriptor->FindFieldByNumber(field_number); |
| 502 | } |
| 503 | } else { |
| 504 | field = descriptor->FindFieldByName(field_name); |
| 505 | // Group names are expected to be capitalized as they appear in the |
| 506 | // .proto file, which actually matches their type names, not their |
| 507 | // field names. |
| 508 | if (field == nullptr) { |
| 509 | std::string lower_field_name = field_name; |
| 510 | LowerString(&lower_field_name); |
| 511 | field = descriptor->FindFieldByName(lower_field_name); |
| 512 | // If the case-insensitive match worked but the field is NOT a group, |
| 513 | if (field != nullptr && |
| 514 | field->type() != FieldDescriptor::TYPE_GROUP) { |
| 515 | field = nullptr; |
| 516 | } |
| 517 | } |
| 518 | // Again, special-case group names as described above. |
| 519 | if (field != nullptr && field->type() == FieldDescriptor::TYPE_GROUP && |
| 520 | field->message_type()->name() != field_name) { |
| 521 | field = nullptr; |
| 522 | } |
| 523 | |
| 524 | if (field == nullptr && allow_case_insensitive_field_) { |
| 525 | std::string lower_field_name = field_name; |
| 526 | LowerString(&lower_field_name); |
| 527 | field = descriptor->FindFieldByLowercaseName(lower_field_name); |
| 528 | } |
| 529 | |
| 530 | if (field == nullptr) { |
| 531 | reserved_field = descriptor->IsReservedName(field_name); |
| 532 | } |
| 533 | } |
| 534 | |
| 535 | if (field == nullptr && !reserved_field) { |
| 536 | if (!allow_unknown_field_) { |
| 537 | ReportError("Message type \"" + descriptor->full_name() + |
| 538 | "\" has no field named \"" + field_name + "\"."); |
| 539 | return false; |
| 540 | } else { |
| 541 | ReportWarning("Message type \"" + descriptor->full_name() + |
| 542 | "\" has no field named \"" + field_name + "\"."); |
| 543 | } |
| 544 | } |
| 545 | } |
| 546 | |
| 547 | // Skips unknown or reserved fields. |
| 548 | if (field == nullptr) { |
| 549 | GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field); |
| 550 | |
| 551 | // Try to guess the type of this field. |
| 552 | // If this field is not a message, there should be a ":" between the |
| 553 | // field name and the field value and also the field value should not |
| 554 | // start with "{" or "<" which indicates the beginning of a message body. |
| 555 | // If there is no ":" or there is a "{" or "<" after ":", this field has |
| 556 | // to be a message or the input is ill-formed. |
| 557 | if (TryConsumeBeforeWhitespace(":")) { |
| 558 | TryConsumeWhitespace(); |
| 559 | if (!LookingAt("{") && !LookingAt("<")) { |
| 560 | return SkipFieldValue(); |
| 561 | } |
| 562 | } |
| 563 | return SkipFieldMessage(); |
| 564 | } |
| 565 | |
| 566 | if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { |
| 567 | // Fail if the field is not repeated and it has already been specified. |
| 568 | if (!field->is_repeated() && reflection->HasField(*message, field)) { |
| 569 | ReportError("Non-repeated field \"" + field_name + |
| 570 | "\" is specified multiple times."); |
| 571 | return false; |
| 572 | } |
| 573 | // Fail if the field is a member of a oneof and another member has already |
| 574 | // been specified. |
| 575 | const OneofDescriptor* oneof = field->containing_oneof(); |
| 576 | if (oneof != nullptr && reflection->HasOneof(*message, oneof)) { |
| 577 | const FieldDescriptor* other_field = |
| 578 | reflection->GetOneofFieldDescriptor(*message, oneof); |
| 579 | ReportError("Field \"" + field_name + |
| 580 | "\" is specified along with " |
| 581 | "field \"" + |
| 582 | other_field->name() + |
| 583 | "\", another member " |
| 584 | "of oneof \"" + |
| 585 | oneof->name() + "\"."); |
| 586 | return false; |
| 587 | } |
| 588 | } |
| 589 | |
| 590 | // Perform special handling for embedded message types. |
| 591 | if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 592 | // ':' is optional here. |
| 593 | bool consumed_semicolon = TryConsumeBeforeWhitespace(":"); |
| 594 | if (consumed_semicolon) { |
| 595 | TryConsumeWhitespace(); |
| 596 | } |
| 597 | if (consumed_semicolon && field->options().weak() && |
| 598 | LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 599 | // we are getting a bytes string for a weak field. |
| 600 | std::string tmp; |
| 601 | DO(ConsumeString(&tmp)); |
| 602 | MessageFactory* factory = |
| 603 | finder_ ? finder_->FindExtensionFactory(field) : nullptr; |
| 604 | reflection->MutableMessage(message, field, factory) |
| 605 | ->ParseFromString(tmp); |
| 606 | goto label_skip_parsing; |
| 607 | } |
| 608 | } else { |
| 609 | // ':' is required here. |
| 610 | DO(ConsumeBeforeWhitespace(":")); |
| 611 | TryConsumeWhitespace(); |
| 612 | } |
| 613 | |
| 614 | if (field->is_repeated() && TryConsume("[")) { |
| 615 | // Short repeated format, e.g. "foo: [1, 2, 3]". |
| 616 | if (!TryConsume("]")) { |
| 617 | // "foo: []" is treated as empty. |
| 618 | while (true) { |
| 619 | if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 620 | // Perform special handling for embedded message types. |
| 621 | DO(ConsumeFieldMessage(message, reflection, field)); |
| 622 | } else { |
| 623 | DO(ConsumeFieldValue(message, reflection, field)); |
| 624 | } |
| 625 | if (TryConsume("]")) { |
| 626 | break; |
| 627 | } |
| 628 | DO(Consume(",")); |
| 629 | } |
| 630 | } |
| 631 | } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 632 | DO(ConsumeFieldMessage(message, reflection, field)); |
| 633 | } else { |
| 634 | DO(ConsumeFieldValue(message, reflection, field)); |
| 635 | } |
| 636 | label_skip_parsing: |
| 637 | // For historical reasons, fields may optionally be separated by commas or |
| 638 | // semicolons. |
| 639 | TryConsume(";") || TryConsume(","); |
| 640 | |
| 641 | if (field->options().deprecated()) { |
| 642 | ReportWarning("text format contains deprecated field \"" + field_name + |
| 643 | "\""); |
| 644 | } |
| 645 | |
| 646 | // If a parse info tree exists, add the location for the parsed |
| 647 | // field. |
| 648 | if (parse_info_tree_ != nullptr) { |
| 649 | int end_line = tokenizer_.previous().line; |
| 650 | int end_column = tokenizer_.previous().end_column; |
| 651 | |
| 652 | RecordLocation(parse_info_tree_, field, |
| 653 | ParseLocationRange(ParseLocation(start_line, start_column), |
| 654 | ParseLocation(end_line, end_column))); |
| 655 | } |
| 656 | |
| 657 | return true; |
| 658 | } |
| 659 | |
| 660 | // Skips the next field including the field's name and value. |
| 661 | bool SkipField() { |
| 662 | std::string field_name; |
| 663 | if (TryConsume("[")) { |
| 664 | // Extension name or type URL. |
| 665 | DO(ConsumeTypeUrlOrFullTypeName(&field_name)); |
| 666 | DO(ConsumeBeforeWhitespace("]")); |
| 667 | } else { |
| 668 | DO(ConsumeIdentifierBeforeWhitespace(&field_name)); |
| 669 | } |
| 670 | TryConsumeWhitespace(); |
| 671 | |
| 672 | // Try to guess the type of this field. |
| 673 | // If this field is not a message, there should be a ":" between the |
| 674 | // field name and the field value and also the field value should not |
| 675 | // start with "{" or "<" which indicates the beginning of a message body. |
| 676 | // If there is no ":" or there is a "{" or "<" after ":", this field has |
| 677 | // to be a message or the input is ill-formed. |
| 678 | if (TryConsumeBeforeWhitespace(":")) { |
| 679 | TryConsumeWhitespace(); |
| 680 | if (!LookingAt("{") && !LookingAt("<")) { |
| 681 | DO(SkipFieldValue()); |
| 682 | } else { |
| 683 | DO(SkipFieldMessage()); |
| 684 | } |
| 685 | } else { |
| 686 | DO(SkipFieldMessage()); |
| 687 | } |
| 688 | // For historical reasons, fields may optionally be separated by commas or |
| 689 | // semicolons. |
| 690 | TryConsume(";") || TryConsume(","); |
| 691 | return true; |
| 692 | } |
| 693 | |
| 694 | bool ConsumeFieldMessage(Message* message, const Reflection* reflection, |
| 695 | const FieldDescriptor* field) { |
| 696 | if (--recursion_limit_ < 0) { |
| 697 | ReportError( |
| 698 | StrCat("Message is too deep, the parser exceeded the " |
| 699 | "configured recursion limit of ", |
| 700 | initial_recursion_limit_, ".")); |
| 701 | return false; |
| 702 | } |
| 703 | // If the parse information tree is not nullptr, create a nested one |
| 704 | // for the nested message. |
| 705 | ParseInfoTree* parent = parse_info_tree_; |
| 706 | if (parent != nullptr) { |
| 707 | parse_info_tree_ = CreateNested(parent, field); |
| 708 | } |
| 709 | |
| 710 | std::string delimiter; |
| 711 | DO(ConsumeMessageDelimiter(&delimiter)); |
| 712 | MessageFactory* factory = |
| 713 | finder_ ? finder_->FindExtensionFactory(field) : nullptr; |
| 714 | if (field->is_repeated()) { |
| 715 | DO(ConsumeMessage(reflection->AddMessage(message, field, factory), |
| 716 | delimiter)); |
| 717 | } else { |
| 718 | DO(ConsumeMessage(reflection->MutableMessage(message, field, factory), |
| 719 | delimiter)); |
| 720 | } |
| 721 | |
| 722 | ++recursion_limit_; |
| 723 | |
| 724 | // Reset the parse information tree. |
| 725 | parse_info_tree_ = parent; |
| 726 | return true; |
| 727 | } |
| 728 | |
| 729 | // Skips the whole body of a message including the beginning delimiter and |
| 730 | // the ending delimiter. |
| 731 | bool SkipFieldMessage() { |
| 732 | if (--recursion_limit_ < 0) { |
| 733 | ReportError( |
| 734 | StrCat("Message is too deep, the parser exceeded the " |
| 735 | "configured recursion limit of ", |
| 736 | initial_recursion_limit_, ".")); |
| 737 | return false; |
| 738 | } |
| 739 | |
| 740 | std::string delimiter; |
| 741 | DO(ConsumeMessageDelimiter(&delimiter)); |
| 742 | while (!LookingAt(">") && !LookingAt("}")) { |
| 743 | DO(SkipField()); |
| 744 | } |
| 745 | DO(Consume(delimiter)); |
| 746 | |
| 747 | ++recursion_limit_; |
| 748 | return true; |
| 749 | } |
| 750 | |
| 751 | bool ConsumeFieldValue(Message* message, const Reflection* reflection, |
| 752 | const FieldDescriptor* field) { |
| 753 | // Define an easy to use macro for setting fields. This macro checks |
| 754 | // to see if the field is repeated (in which case we need to use the Add |
| 755 | // methods or not (in which case we need to use the Set methods). |
| 756 | #define SET_FIELD(CPPTYPE, VALUE) \ |
| 757 | if (field->is_repeated()) { \ |
| 758 | reflection->Add##CPPTYPE(message, field, VALUE); \ |
| 759 | } else { \ |
| 760 | reflection->Set##CPPTYPE(message, field, VALUE); \ |
| 761 | } |
| 762 | |
| 763 | switch (field->cpp_type()) { |
| 764 | case FieldDescriptor::CPPTYPE_INT32: { |
| 765 | int64_t value; |
| 766 | DO(ConsumeSignedInteger(&value, kint32max)); |
| 767 | SET_FIELD(Int32, static_cast<int32_t>(value)); |
| 768 | break; |
| 769 | } |
| 770 | |
| 771 | case FieldDescriptor::CPPTYPE_UINT32: { |
| 772 | uint64_t value; |
| 773 | DO(ConsumeUnsignedInteger(&value, kuint32max)); |
| 774 | SET_FIELD(UInt32, static_cast<uint32_t>(value)); |
| 775 | break; |
| 776 | } |
| 777 | |
| 778 | case FieldDescriptor::CPPTYPE_INT64: { |
| 779 | int64_t value; |
| 780 | DO(ConsumeSignedInteger(&value, kint64max)); |
| 781 | SET_FIELD(Int64, value); |
| 782 | break; |
| 783 | } |
| 784 | |
| 785 | case FieldDescriptor::CPPTYPE_UINT64: { |
| 786 | uint64_t value; |
| 787 | DO(ConsumeUnsignedInteger(&value, kuint64max)); |
| 788 | SET_FIELD(UInt64, value); |
| 789 | break; |
| 790 | } |
| 791 | |
| 792 | case FieldDescriptor::CPPTYPE_FLOAT: { |
| 793 | double value; |
| 794 | DO(ConsumeDouble(&value)); |
| 795 | SET_FIELD(Float, io::SafeDoubleToFloat(value)); |
| 796 | break; |
| 797 | } |
| 798 | |
| 799 | case FieldDescriptor::CPPTYPE_DOUBLE: { |
| 800 | double value; |
| 801 | DO(ConsumeDouble(&value)); |
| 802 | SET_FIELD(Double, value); |
| 803 | break; |
| 804 | } |
| 805 | |
| 806 | case FieldDescriptor::CPPTYPE_STRING: { |
| 807 | std::string value; |
| 808 | DO(ConsumeString(&value)); |
| 809 | SET_FIELD(String, std::move(value)); |
| 810 | break; |
| 811 | } |
| 812 | |
| 813 | case FieldDescriptor::CPPTYPE_BOOL: { |
| 814 | if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 815 | uint64_t value; |
| 816 | DO(ConsumeUnsignedInteger(&value, 1)); |
| 817 | SET_FIELD(Bool, value); |
| 818 | } else { |
| 819 | std::string value; |
| 820 | DO(ConsumeIdentifier(&value)); |
| 821 | if (value == "true" || value == "True" || value == "t") { |
| 822 | SET_FIELD(Bool, true); |
| 823 | } else if (value == "false" || value == "False" || value == "f") { |
| 824 | SET_FIELD(Bool, false); |
| 825 | } else { |
| 826 | ReportError("Invalid value for boolean field \"" + field->name() + |
| 827 | "\". Value: \"" + value + "\"."); |
| 828 | return false; |
| 829 | } |
| 830 | } |
| 831 | break; |
| 832 | } |
| 833 | |
| 834 | case FieldDescriptor::CPPTYPE_ENUM: { |
| 835 | std::string value; |
| 836 | int64_t int_value = kint64max; |
| 837 | const EnumDescriptor* enum_type = field->enum_type(); |
| 838 | const EnumValueDescriptor* enum_value = nullptr; |
| 839 | |
| 840 | if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
| 841 | DO(ConsumeIdentifier(&value)); |
| 842 | // Find the enumeration value. |
| 843 | enum_value = enum_type->FindValueByName(value); |
| 844 | |
| 845 | } else if (LookingAt("-") || |
| 846 | LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 847 | DO(ConsumeSignedInteger(&int_value, kint32max)); |
| 848 | value = StrCat(int_value); // for error reporting |
| 849 | enum_value = enum_type->FindValueByNumber(int_value); |
| 850 | } else { |
| 851 | ReportError("Expected integer or identifier, got: " + |
| 852 | tokenizer_.current().text); |
| 853 | return false; |
| 854 | } |
| 855 | |
| 856 | if (enum_value == nullptr) { |
| 857 | if (int_value != kint64max && |
| 858 | reflection->SupportsUnknownEnumValues()) { |
| 859 | SET_FIELD(EnumValue, int_value); |
| 860 | return true; |
| 861 | } else if (!allow_unknown_enum_) { |
| 862 | ReportError("Unknown enumeration value of \"" + value + |
| 863 | "\" for " |
| 864 | "field \"" + |
| 865 | field->name() + "\"."); |
| 866 | return false; |
| 867 | } else { |
| 868 | ReportWarning("Unknown enumeration value of \"" + value + |
| 869 | "\" for " |
| 870 | "field \"" + |
| 871 | field->name() + "\"."); |
| 872 | return true; |
| 873 | } |
| 874 | } |
| 875 | |
| 876 | SET_FIELD(Enum, enum_value); |
| 877 | break; |
| 878 | } |
| 879 | |
| 880 | case FieldDescriptor::CPPTYPE_MESSAGE: { |
| 881 | // We should never get here. Put here instead of a default |
| 882 | // so that if new types are added, we get a nice compiler warning. |
| 883 | GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; |
| 884 | break; |
| 885 | } |
| 886 | } |
| 887 | #undef SET_FIELD |
| 888 | return true; |
| 889 | } |
| 890 | |
| 891 | bool SkipFieldValue() { |
| 892 | if (--recursion_limit_ < 0) { |
| 893 | ReportError( |
| 894 | StrCat("Message is too deep, the parser exceeded the " |
| 895 | "configured recursion limit of ", |
| 896 | initial_recursion_limit_, ".")); |
| 897 | return false; |
| 898 | } |
| 899 | |
| 900 | if (LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 901 | while (LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 902 | tokenizer_.Next(); |
| 903 | } |
| 904 | ++recursion_limit_; |
| 905 | return true; |
| 906 | } |
| 907 | if (TryConsume("[")) { |
| 908 | while (true) { |
| 909 | if (!LookingAt("{") && !LookingAt("<")) { |
| 910 | DO(SkipFieldValue()); |
| 911 | } else { |
| 912 | DO(SkipFieldMessage()); |
| 913 | } |
| 914 | if (TryConsume("]")) { |
| 915 | break; |
| 916 | } |
| 917 | DO(Consume(",")); |
| 918 | } |
| 919 | ++recursion_limit_; |
| 920 | return true; |
| 921 | } |
| 922 | // Possible field values other than string: |
| 923 | // 12345 => TYPE_INTEGER |
| 924 | // -12345 => TYPE_SYMBOL + TYPE_INTEGER |
| 925 | // 1.2345 => TYPE_FLOAT |
| 926 | // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT |
| 927 | // inf => TYPE_IDENTIFIER |
| 928 | // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER |
| 929 | // TYPE_INTEGER => TYPE_IDENTIFIER |
| 930 | // Divides them into two group, one with TYPE_SYMBOL |
| 931 | // and the other without: |
| 932 | // Group one: |
| 933 | // 12345 => TYPE_INTEGER |
| 934 | // 1.2345 => TYPE_FLOAT |
| 935 | // inf => TYPE_IDENTIFIER |
| 936 | // TYPE_INTEGER => TYPE_IDENTIFIER |
| 937 | // Group two: |
| 938 | // -12345 => TYPE_SYMBOL + TYPE_INTEGER |
| 939 | // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT |
| 940 | // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER |
| 941 | // As we can see, the field value consists of an optional '-' and one of |
| 942 | // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER. |
| 943 | bool has_minus = TryConsume("-"); |
| 944 | if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) && |
| 945 | !LookingAtType(io::Tokenizer::TYPE_FLOAT) && |
| 946 | !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
| 947 | std::string text = tokenizer_.current().text; |
| 948 | ReportError("Cannot skip field value, unexpected token: " + text); |
| 949 | ++recursion_limit_; |
| 950 | return false; |
| 951 | } |
| 952 | // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field |
| 953 | // value while other combinations all generate valid values. |
| 954 | // We check if the value of this combination is valid here. |
| 955 | // TYPE_IDENTIFIER after a '-' should be one of the float values listed |
| 956 | // below: |
| 957 | // inf, inff, infinity, nan |
| 958 | if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
| 959 | std::string text = tokenizer_.current().text; |
| 960 | LowerString(&text); |
| 961 | if (text != "inf" && |
| 962 | text != "infinity" && text != "nan") { |
| 963 | ReportError("Invalid float number: " + text); |
| 964 | ++recursion_limit_; |
| 965 | return false; |
| 966 | } |
| 967 | } |
| 968 | tokenizer_.Next(); |
| 969 | ++recursion_limit_; |
| 970 | return true; |
| 971 | } |
| 972 | |
| 973 | // Returns true if the current token's text is equal to that specified. |
| 974 | bool LookingAt(const std::string& text) { |
| 975 | return tokenizer_.current().text == text; |
| 976 | } |
| 977 | |
| 978 | // Returns true if the current token's type is equal to that specified. |
| 979 | bool LookingAtType(io::Tokenizer::TokenType token_type) { |
| 980 | return tokenizer_.current().type == token_type; |
| 981 | } |
| 982 | |
| 983 | // Consumes an identifier and saves its value in the identifier parameter. |
| 984 | // Returns false if the token is not of type IDENTIFIER. |
| 985 | bool ConsumeIdentifier(std::string* identifier) { |
| 986 | if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
| 987 | *identifier = tokenizer_.current().text; |
| 988 | tokenizer_.Next(); |
| 989 | return true; |
| 990 | } |
| 991 | |
| 992 | // If allow_field_numer_ or allow_unknown_field_ is true, we should able |
| 993 | // to parse integer identifiers. |
| 994 | if ((allow_field_number_ || allow_unknown_field_ || |
| 995 | allow_unknown_extension_) && |
| 996 | LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 997 | *identifier = tokenizer_.current().text; |
| 998 | tokenizer_.Next(); |
| 999 | return true; |
| 1000 | } |
| 1001 | |
| 1002 | ReportError("Expected identifier, got: " + tokenizer_.current().text); |
| 1003 | return false; |
| 1004 | } |
| 1005 | |
| 1006 | // Similar to `ConsumeIdentifier`, but any following whitespace token may |
| 1007 | // be reported. |
| 1008 | bool ConsumeIdentifierBeforeWhitespace(std::string* identifier) { |
| 1009 | tokenizer_.set_report_whitespace(true); |
| 1010 | bool result = ConsumeIdentifier(identifier); |
| 1011 | tokenizer_.set_report_whitespace(false); |
| 1012 | return result; |
| 1013 | } |
| 1014 | |
| 1015 | // Consume a string of form "<id1>.<id2>....<idN>". |
| 1016 | bool ConsumeFullTypeName(std::string* name) { |
| 1017 | DO(ConsumeIdentifier(name)); |
| 1018 | while (TryConsume(".")) { |
| 1019 | std::string part; |
| 1020 | DO(ConsumeIdentifier(&part)); |
| 1021 | *name += "."; |
| 1022 | *name += part; |
| 1023 | } |
| 1024 | return true; |
| 1025 | } |
| 1026 | |
| 1027 | bool ConsumeTypeUrlOrFullTypeName(std::string* name) { |
| 1028 | DO(ConsumeIdentifier(name)); |
| 1029 | while (true) { |
| 1030 | std::string connector; |
| 1031 | if (TryConsume(".")) { |
| 1032 | connector = "."; |
| 1033 | } else if (TryConsume("/")) { |
| 1034 | connector = "/"; |
| 1035 | } else { |
| 1036 | break; |
| 1037 | } |
| 1038 | std::string part; |
| 1039 | DO(ConsumeIdentifier(&part)); |
| 1040 | *name += connector; |
| 1041 | *name += part; |
| 1042 | } |
| 1043 | return true; |
| 1044 | } |
| 1045 | |
| 1046 | // Consumes a string and saves its value in the text parameter. |
| 1047 | // Returns false if the token is not of type STRING. |
| 1048 | bool ConsumeString(std::string* text) { |
| 1049 | if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 1050 | ReportError("Expected string, got: " + tokenizer_.current().text); |
| 1051 | return false; |
| 1052 | } |
| 1053 | |
| 1054 | text->clear(); |
| 1055 | while (LookingAtType(io::Tokenizer::TYPE_STRING)) { |
| 1056 | io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); |
| 1057 | |
| 1058 | tokenizer_.Next(); |
| 1059 | } |
| 1060 | |
| 1061 | return true; |
| 1062 | } |
| 1063 | |
| 1064 | // Consumes a uint64_t and saves its value in the value parameter. |
| 1065 | // Returns false if the token is not of type INTEGER. |
| 1066 | bool ConsumeUnsignedInteger(uint64_t* value, uint64_t max_value) { |
| 1067 | if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 1068 | ReportError("Expected integer, got: " + tokenizer_.current().text); |
| 1069 | return false; |
| 1070 | } |
| 1071 | |
| 1072 | if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value, |
| 1073 | value)) { |
| 1074 | ReportError("Integer out of range (" + tokenizer_.current().text + ")"); |
| 1075 | return false; |
| 1076 | } |
| 1077 | |
| 1078 | tokenizer_.Next(); |
| 1079 | return true; |
| 1080 | } |
| 1081 | |
| 1082 | // Consumes an int64_t and saves its value in the value parameter. |
| 1083 | // Note that since the tokenizer does not support negative numbers, |
| 1084 | // we actually may consume an additional token (for the minus sign) in this |
| 1085 | // method. Returns false if the token is not an integer |
| 1086 | // (signed or otherwise). |
| 1087 | bool ConsumeSignedInteger(int64_t* value, uint64_t max_value) { |
| 1088 | bool negative = false; |
| 1089 | |
| 1090 | if (TryConsume("-")) { |
| 1091 | negative = true; |
| 1092 | // Two's complement always allows one more negative integer than |
| 1093 | // positive. |
| 1094 | ++max_value; |
| 1095 | } |
| 1096 | |
| 1097 | uint64_t unsigned_value; |
| 1098 | |
| 1099 | DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); |
| 1100 | |
| 1101 | if (negative) { |
| 1102 | if ((static_cast<uint64_t>(kint64max) + 1) == unsigned_value) { |
| 1103 | *value = kint64min; |
| 1104 | } else { |
| 1105 | *value = -static_cast<int64_t>(unsigned_value); |
| 1106 | } |
| 1107 | } else { |
| 1108 | *value = static_cast<int64_t>(unsigned_value); |
| 1109 | } |
| 1110 | |
| 1111 | return true; |
| 1112 | } |
| 1113 | |
| 1114 | // Consumes a double and saves its value in the value parameter. |
| 1115 | // Accepts decimal numbers only, rejects hex or oct numbers. |
| 1116 | bool ConsumeUnsignedDecimalAsDouble(double* value, uint64_t max_value) { |
| 1117 | if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 1118 | ReportError("Expected integer, got: " + tokenizer_.current().text); |
| 1119 | return false; |
| 1120 | } |
| 1121 | |
| 1122 | const std::string& text = tokenizer_.current().text; |
| 1123 | if (IsHexNumber(text) || IsOctNumber(text)) { |
| 1124 | ReportError("Expect a decimal number, got: " + text); |
| 1125 | return false; |
| 1126 | } |
| 1127 | |
| 1128 | uint64_t uint64_value; |
| 1129 | if (io::Tokenizer::ParseInteger(text, max_value, &uint64_value)) { |
| 1130 | *value = static_cast<double>(uint64_value); |
| 1131 | } else { |
| 1132 | // Uint64 overflow, attempt to parse as a double instead. |
| 1133 | *value = io::Tokenizer::ParseFloat(text); |
| 1134 | } |
| 1135 | |
| 1136 | tokenizer_.Next(); |
| 1137 | return true; |
| 1138 | } |
| 1139 | |
| 1140 | // Consumes a double and saves its value in the value parameter. |
| 1141 | // Note that since the tokenizer does not support negative numbers, |
| 1142 | // we actually may consume an additional token (for the minus sign) in this |
| 1143 | // method. Returns false if the token is not a double |
| 1144 | // (signed or otherwise). |
| 1145 | bool ConsumeDouble(double* value) { |
| 1146 | bool negative = false; |
| 1147 | |
| 1148 | if (TryConsume("-")) { |
| 1149 | negative = true; |
| 1150 | } |
| 1151 | |
| 1152 | // A double can actually be an integer, according to the tokenizer. |
| 1153 | // Therefore, we must check both cases here. |
| 1154 | if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 1155 | // We have found an integer value for the double. |
| 1156 | DO(ConsumeUnsignedDecimalAsDouble(value, kuint64max)); |
| 1157 | } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { |
| 1158 | // We have found a float value for the double. |
| 1159 | *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); |
| 1160 | |
| 1161 | // Mark the current token as consumed. |
| 1162 | tokenizer_.Next(); |
| 1163 | } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
| 1164 | std::string text = tokenizer_.current().text; |
| 1165 | LowerString(&text); |
| 1166 | if (text == "inf" || |
| 1167 | text == "infinity") { |
| 1168 | *value = std::numeric_limits<double>::infinity(); |
| 1169 | tokenizer_.Next(); |
| 1170 | } else if (text == "nan") { |
| 1171 | *value = std::numeric_limits<double>::quiet_NaN(); |
| 1172 | tokenizer_.Next(); |
| 1173 | } else { |
| 1174 | ReportError("Expected double, got: " + text); |
| 1175 | return false; |
| 1176 | } |
| 1177 | } else { |
| 1178 | ReportError("Expected double, got: " + tokenizer_.current().text); |
| 1179 | return false; |
| 1180 | } |
| 1181 | |
| 1182 | if (negative) { |
| 1183 | *value = -*value; |
| 1184 | } |
| 1185 | |
| 1186 | return true; |
| 1187 | } |
| 1188 | |
| 1189 | // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name" |
| 1190 | // or "type.googleprod.com/full.type.Name" |
| 1191 | bool ConsumeAnyTypeUrl(std::string* full_type_name, std::string* prefix) { |
| 1192 | // TODO(saito) Extend Consume() to consume multiple tokens at once, so that |
| 1193 | // this code can be written as just DO(Consume(kGoogleApisTypePrefix)). |
| 1194 | DO(ConsumeIdentifier(prefix)); |
| 1195 | while (TryConsume(".")) { |
| 1196 | std::string url; |
| 1197 | DO(ConsumeIdentifier(&url)); |
| 1198 | *prefix += "." + url; |
| 1199 | } |
| 1200 | DO(Consume("/")); |
| 1201 | *prefix += "/"; |
| 1202 | DO(ConsumeFullTypeName(full_type_name)); |
| 1203 | |
| 1204 | return true; |
| 1205 | } |
| 1206 | |
| 1207 | // A helper function for reconstructing Any::value. Consumes a text of |
| 1208 | // full_type_name, then serializes it into serialized_value. |
| 1209 | bool ConsumeAnyValue(const Descriptor* value_descriptor, |
| 1210 | std::string* serialized_value) { |
| 1211 | DynamicMessageFactory factory; |
| 1212 | const Message* value_prototype = factory.GetPrototype(value_descriptor); |
| 1213 | if (value_prototype == nullptr) { |
| 1214 | return false; |
| 1215 | } |
| 1216 | std::unique_ptr<Message> value(value_prototype->New()); |
| 1217 | std::string sub_delimiter; |
| 1218 | DO(ConsumeMessageDelimiter(&sub_delimiter)); |
| 1219 | DO(ConsumeMessage(value.get(), sub_delimiter)); |
| 1220 | |
| 1221 | if (allow_partial_) { |
| 1222 | value->AppendPartialToString(serialized_value); |
| 1223 | } else { |
| 1224 | if (!value->IsInitialized()) { |
| 1225 | ReportError( |
| 1226 | "Value of type \"" + value_descriptor->full_name() + |
| 1227 | "\" stored in google.protobuf.Any has missing required fields"); |
| 1228 | return false; |
| 1229 | } |
| 1230 | value->AppendToString(serialized_value); |
| 1231 | } |
| 1232 | return true; |
| 1233 | } |
| 1234 | |
| 1235 | // Consumes a token and confirms that it matches that specified in the |
| 1236 | // value parameter. Returns false if the token found does not match that |
| 1237 | // which was specified. |
| 1238 | bool Consume(const std::string& value) { |
| 1239 | const std::string& current_value = tokenizer_.current().text; |
| 1240 | |
| 1241 | if (current_value != value) { |
| 1242 | ReportError("Expected \"" + value + "\", found \"" + current_value + |
| 1243 | "\"."); |
| 1244 | return false; |
| 1245 | } |
| 1246 | |
| 1247 | tokenizer_.Next(); |
| 1248 | |
| 1249 | return true; |
| 1250 | } |
| 1251 | |
| 1252 | // Similar to `Consume`, but the following token may be tokenized as |
| 1253 | // TYPE_WHITESPACE. |
| 1254 | bool ConsumeBeforeWhitespace(const std::string& value) { |
| 1255 | // Report whitespace after this token, but only once. |
| 1256 | tokenizer_.set_report_whitespace(true); |
| 1257 | bool result = Consume(value); |
| 1258 | tokenizer_.set_report_whitespace(false); |
| 1259 | return result; |
| 1260 | } |
| 1261 | |
| 1262 | // Attempts to consume the supplied value. Returns false if a the |
| 1263 | // token found does not match the value specified. |
| 1264 | bool TryConsume(const std::string& value) { |
| 1265 | if (tokenizer_.current().text == value) { |
| 1266 | tokenizer_.Next(); |
| 1267 | return true; |
| 1268 | } else { |
| 1269 | return false; |
| 1270 | } |
| 1271 | } |
| 1272 | |
| 1273 | // Similar to `TryConsume`, but the following token may be tokenized as |
| 1274 | // TYPE_WHITESPACE. |
| 1275 | bool TryConsumeBeforeWhitespace(const std::string& value) { |
| 1276 | // Report whitespace after this token, but only once. |
| 1277 | tokenizer_.set_report_whitespace(true); |
| 1278 | bool result = TryConsume(value); |
| 1279 | tokenizer_.set_report_whitespace(false); |
| 1280 | return result; |
| 1281 | } |
| 1282 | |
| 1283 | bool TryConsumeWhitespace() { |
| 1284 | had_silent_marker_ = false; |
| 1285 | if (LookingAtType(io::Tokenizer::TYPE_WHITESPACE)) { |
| 1286 | if (tokenizer_.current().text == |
| 1287 | StrCat(" ", internal::kDebugStringSilentMarkerForDetection)) { |
| 1288 | had_silent_marker_ = true; |
| 1289 | } |
| 1290 | tokenizer_.Next(); |
| 1291 | return true; |
| 1292 | } |
| 1293 | return false; |
| 1294 | } |
| 1295 | |
| 1296 | // An internal instance of the Tokenizer's error collector, used to |
| 1297 | // collect any base-level parse errors and feed them to the ParserImpl. |
| 1298 | class ParserErrorCollector : public io::ErrorCollector { |
| 1299 | public: |
| 1300 | explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) |
| 1301 | : parser_(parser) {} |
| 1302 | |
| 1303 | ~ParserErrorCollector() override {} |
| 1304 | |
| 1305 | void AddError(int line, int column, const std::string& message) override { |
| 1306 | parser_->ReportError(line, column, message); |
| 1307 | } |
| 1308 | |
| 1309 | void AddWarning(int line, int column, const std::string& message) override { |
| 1310 | parser_->ReportWarning(line, column, message); |
| 1311 | } |
| 1312 | |
| 1313 | private: |
| 1314 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); |
| 1315 | TextFormat::Parser::ParserImpl* parser_; |
| 1316 | }; |
| 1317 | |
| 1318 | io::ErrorCollector* error_collector_; |
| 1319 | const TextFormat::Finder* finder_; |
| 1320 | ParseInfoTree* parse_info_tree_; |
| 1321 | ParserErrorCollector tokenizer_error_collector_; |
| 1322 | io::Tokenizer tokenizer_; |
| 1323 | const Descriptor* root_message_type_; |
| 1324 | SingularOverwritePolicy singular_overwrite_policy_; |
| 1325 | const bool allow_case_insensitive_field_; |
| 1326 | const bool allow_unknown_field_; |
| 1327 | const bool allow_unknown_extension_; |
| 1328 | const bool allow_unknown_enum_; |
| 1329 | const bool allow_field_number_; |
| 1330 | const bool allow_partial_; |
| 1331 | const int initial_recursion_limit_; |
| 1332 | int recursion_limit_; |
| 1333 | bool had_silent_marker_; |
| 1334 | bool had_errors_; |
| 1335 | }; |
| 1336 | |
| 1337 | // =========================================================================== |
| 1338 | // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted |
| 1339 | // from the Printer found in //net/proto2/io/public/printer.h |
| 1340 | class TextFormat::Printer::TextGenerator |
| 1341 | : public TextFormat::BaseTextGenerator { |
| 1342 | public: |
| 1343 | explicit TextGenerator(io::ZeroCopyOutputStream* output, |
| 1344 | int initial_indent_level) |
| 1345 | : output_(output), |
| 1346 | buffer_(nullptr), |
| 1347 | buffer_size_(0), |
| 1348 | at_start_of_line_(true), |
| 1349 | failed_(false), |
| 1350 | insert_silent_marker_(false), |
| 1351 | indent_level_(initial_indent_level), |
| 1352 | initial_indent_level_(initial_indent_level) {} |
| 1353 | |
| 1354 | explicit TextGenerator(io::ZeroCopyOutputStream* output, |
| 1355 | bool insert_silent_marker, int initial_indent_level) |
| 1356 | : output_(output), |
| 1357 | buffer_(nullptr), |
| 1358 | buffer_size_(0), |
| 1359 | at_start_of_line_(true), |
| 1360 | failed_(false), |
| 1361 | insert_silent_marker_(insert_silent_marker), |
| 1362 | indent_level_(initial_indent_level), |
| 1363 | initial_indent_level_(initial_indent_level) {} |
| 1364 | |
| 1365 | ~TextGenerator() override { |
| 1366 | // Only BackUp() if we're sure we've successfully called Next() at least |
| 1367 | // once. |
| 1368 | if (!failed_) { |
| 1369 | output_->BackUp(buffer_size_); |
| 1370 | } |
| 1371 | } |
| 1372 | |
| 1373 | // Indent text by two spaces. After calling Indent(), two spaces will be |
| 1374 | // inserted at the beginning of each line of text. Indent() may be called |
| 1375 | // multiple times to produce deeper indents. |
| 1376 | void Indent() override { ++indent_level_; } |
| 1377 | |
| 1378 | // Reduces the current indent level by two spaces, or crashes if the indent |
| 1379 | // level is zero. |
| 1380 | void Outdent() override { |
| 1381 | if (indent_level_ == 0 || indent_level_ < initial_indent_level_) { |
| 1382 | GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; |
| 1383 | return; |
| 1384 | } |
| 1385 | |
| 1386 | --indent_level_; |
| 1387 | } |
| 1388 | |
| 1389 | size_t GetCurrentIndentationSize() const override { |
| 1390 | return 2 * indent_level_; |
| 1391 | } |
| 1392 | |
| 1393 | // Print text to the output stream. |
| 1394 | void Print(const char* text, size_t size) override { |
| 1395 | if (indent_level_ > 0) { |
| 1396 | size_t pos = 0; // The number of bytes we've written so far. |
| 1397 | for (size_t i = 0; i < size; i++) { |
| 1398 | if (text[i] == '\n') { |
| 1399 | // Saw newline. If there is more text, we may need to insert an |
| 1400 | // indent here. So, write what we have so far, including the '\n'. |
| 1401 | Write(text + pos, i - pos + 1); |
| 1402 | pos = i + 1; |
| 1403 | |
| 1404 | // Setting this true will cause the next Write() to insert an indent |
| 1405 | // first. |
| 1406 | at_start_of_line_ = true; |
| 1407 | } |
| 1408 | } |
| 1409 | // Write the rest. |
| 1410 | Write(text + pos, size - pos); |
| 1411 | } else { |
| 1412 | Write(text, size); |
| 1413 | if (size > 0 && text[size - 1] == '\n') { |
| 1414 | at_start_of_line_ = true; |
| 1415 | } |
| 1416 | } |
| 1417 | } |
| 1418 | |
| 1419 | // True if any write to the underlying stream failed. (We don't just |
| 1420 | // crash in this case because this is an I/O failure, not a programming |
| 1421 | // error.) |
| 1422 | bool failed() const { return failed_; } |
| 1423 | |
| 1424 | void PrintMaybeWithMarker(StringPiece text) { |
| 1425 | Print(text.data(), text.size()); |
| 1426 | if (ConsumeInsertSilentMarker()) { |
| 1427 | PrintLiteral(internal::kDebugStringSilentMarker); |
| 1428 | } |
| 1429 | } |
| 1430 | |
| 1431 | void PrintMaybeWithMarker(StringPiece text_head, |
| 1432 | StringPiece text_tail) { |
| 1433 | Print(text_head.data(), text_head.size()); |
| 1434 | if (ConsumeInsertSilentMarker()) { |
| 1435 | PrintLiteral(internal::kDebugStringSilentMarker); |
| 1436 | } |
| 1437 | Print(text_tail.data(), text_tail.size()); |
| 1438 | } |
| 1439 | |
| 1440 | private: |
| 1441 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); |
| 1442 | |
| 1443 | void Write(const char* data, size_t size) { |
| 1444 | if (failed_) return; |
| 1445 | if (size == 0) return; |
| 1446 | |
| 1447 | if (at_start_of_line_) { |
| 1448 | // Insert an indent. |
| 1449 | at_start_of_line_ = false; |
| 1450 | WriteIndent(); |
| 1451 | if (failed_) return; |
| 1452 | } |
| 1453 | |
| 1454 | while (static_cast<int64_t>(size) > buffer_size_) { |
| 1455 | // Data exceeds space in the buffer. Copy what we can and request a |
| 1456 | // new buffer. |
| 1457 | if (buffer_size_ > 0) { |
| 1458 | memcpy(buffer_, data, buffer_size_); |
| 1459 | data += buffer_size_; |
| 1460 | size -= buffer_size_; |
| 1461 | } |
| 1462 | void* void_buffer = nullptr; |
| 1463 | failed_ = !output_->Next(&void_buffer, &buffer_size_); |
| 1464 | if (failed_) return; |
| 1465 | buffer_ = reinterpret_cast<char*>(void_buffer); |
| 1466 | } |
| 1467 | |
| 1468 | // Buffer is big enough to receive the data; copy it. |
| 1469 | memcpy(buffer_, data, size); |
| 1470 | buffer_ += size; |
| 1471 | buffer_size_ -= size; |
| 1472 | } |
| 1473 | |
| 1474 | void WriteIndent() { |
| 1475 | if (indent_level_ == 0) { |
| 1476 | return; |
| 1477 | } |
| 1478 | GOOGLE_DCHECK(!failed_); |
| 1479 | int size = GetCurrentIndentationSize(); |
| 1480 | |
| 1481 | while (size > buffer_size_) { |
| 1482 | // Data exceeds space in the buffer. Write what we can and request a new |
| 1483 | // buffer. |
| 1484 | if (buffer_size_ > 0) { |
| 1485 | memset(buffer_, ' ', buffer_size_); |
| 1486 | } |
| 1487 | size -= buffer_size_; |
| 1488 | void* void_buffer; |
| 1489 | failed_ = !output_->Next(&void_buffer, &buffer_size_); |
| 1490 | if (failed_) return; |
| 1491 | buffer_ = reinterpret_cast<char*>(void_buffer); |
| 1492 | } |
| 1493 | |
| 1494 | // Buffer is big enough to receive the data; copy it. |
| 1495 | memset(buffer_, ' ', size); |
| 1496 | buffer_ += size; |
| 1497 | buffer_size_ -= size; |
| 1498 | } |
| 1499 | |
| 1500 | // Return the current value of insert_silent_marker_. If it is true, set it |
| 1501 | // to false as we assume that a silent marker is inserted after a call to this |
| 1502 | // function. |
| 1503 | bool ConsumeInsertSilentMarker() { |
| 1504 | if (insert_silent_marker_) { |
| 1505 | insert_silent_marker_ = false; |
| 1506 | return true; |
| 1507 | } |
| 1508 | return false; |
| 1509 | } |
| 1510 | |
| 1511 | io::ZeroCopyOutputStream* const output_; |
| 1512 | char* buffer_; |
| 1513 | int buffer_size_; |
| 1514 | bool at_start_of_line_; |
| 1515 | bool failed_; |
| 1516 | // This flag is false when inserting silent marker is disabled or a silent |
| 1517 | // marker has been inserted. |
| 1518 | bool insert_silent_marker_; |
| 1519 | |
| 1520 | int indent_level_; |
| 1521 | int initial_indent_level_; |
| 1522 | }; |
| 1523 | |
| 1524 | // =========================================================================== |
| 1525 | // An internal field value printer that may insert a silent marker in |
| 1526 | // DebugStrings. |
| 1527 | class TextFormat::Printer::DebugStringFieldValuePrinter |
| 1528 | : public TextFormat::FastFieldValuePrinter { |
| 1529 | public: |
| 1530 | void PrintMessageStart(const Message& /*message*/, int /*field_index*/, |
| 1531 | int /*field_count*/, bool single_line_mode, |
| 1532 | BaseTextGenerator* generator) const override { |
| 1533 | // This is safe as only TextGenerator is used with |
| 1534 | // DebugStringFieldValuePrinter. |
| 1535 | TextGenerator* text_generator = static_cast<TextGenerator*>(generator); |
| 1536 | if (single_line_mode) { |
| 1537 | text_generator->PrintMaybeWithMarker(" ", "{ "); |
| 1538 | } else { |
| 1539 | text_generator->PrintMaybeWithMarker(" ", "{\n"); |
| 1540 | } |
| 1541 | } |
| 1542 | }; |
| 1543 | |
| 1544 | // =========================================================================== |
| 1545 | // An internal field value printer that escape UTF8 strings. |
| 1546 | class TextFormat::Printer::FastFieldValuePrinterUtf8Escaping |
| 1547 | : public TextFormat::Printer::DebugStringFieldValuePrinter { |
| 1548 | public: |
| 1549 | void PrintString(const std::string& val, |
| 1550 | TextFormat::BaseTextGenerator* generator) const override { |
| 1551 | generator->PrintLiteral("\""); |
| 1552 | generator->PrintString(strings::Utf8SafeCEscape(val)); |
| 1553 | generator->PrintLiteral("\""); |
| 1554 | } |
| 1555 | void PrintBytes(const std::string& val, |
| 1556 | TextFormat::BaseTextGenerator* generator) const override { |
| 1557 | return FastFieldValuePrinter::PrintString(val, generator); |
| 1558 | } |
| 1559 | }; |
| 1560 | |
| 1561 | // =========================================================================== |
| 1562 | // Implementation of the default Finder for extensions. |
| 1563 | TextFormat::Finder::~Finder() {} |
| 1564 | |
| 1565 | const FieldDescriptor* TextFormat::Finder::FindExtension( |
| 1566 | Message* message, const std::string& name) const { |
| 1567 | return DefaultFinderFindExtension(message, name); |
| 1568 | } |
| 1569 | |
| 1570 | const FieldDescriptor* TextFormat::Finder::FindExtensionByNumber( |
| 1571 | const Descriptor* descriptor, int number) const { |
| 1572 | return DefaultFinderFindExtensionByNumber(descriptor, number); |
| 1573 | } |
| 1574 | |
| 1575 | const Descriptor* TextFormat::Finder::FindAnyType( |
| 1576 | const Message& message, const std::string& prefix, |
| 1577 | const std::string& name) const { |
| 1578 | return DefaultFinderFindAnyType(message, prefix, name); |
| 1579 | } |
| 1580 | |
| 1581 | MessageFactory* TextFormat::Finder::FindExtensionFactory( |
| 1582 | const FieldDescriptor* /*field*/) const { |
| 1583 | return nullptr; |
| 1584 | } |
| 1585 | |
| 1586 | // =========================================================================== |
| 1587 | |
| 1588 | TextFormat::Parser::Parser() |
| 1589 | : error_collector_(nullptr), |
| 1590 | finder_(nullptr), |
| 1591 | parse_info_tree_(nullptr), |
| 1592 | allow_partial_(false), |
| 1593 | allow_case_insensitive_field_(false), |
| 1594 | allow_unknown_field_(false), |
| 1595 | allow_unknown_extension_(false), |
| 1596 | allow_unknown_enum_(false), |
| 1597 | allow_field_number_(false), |
| 1598 | allow_relaxed_whitespace_(false), |
| 1599 | allow_singular_overwrites_(false), |
| 1600 | recursion_limit_(std::numeric_limits<int>::max()) {} |
| 1601 | |
| 1602 | TextFormat::Parser::~Parser() {} |
| 1603 | |
| 1604 | namespace { |
| 1605 | |
| 1606 | bool CheckParseInputSize(StringPiece input, |
| 1607 | io::ErrorCollector* error_collector) { |
| 1608 | if (input.size() > INT_MAX) { |
| 1609 | error_collector->AddError( |
| 1610 | -1, 0, |
| 1611 | StrCat( |
| 1612 | "Input size too large: ", static_cast<int64_t>(input.size()), |
| 1613 | " bytes", " > ", INT_MAX, " bytes.")); |
| 1614 | return false; |
| 1615 | } |
| 1616 | return true; |
| 1617 | } |
| 1618 | |
| 1619 | } // namespace |
| 1620 | |
| 1621 | bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, |
| 1622 | Message* output) { |
| 1623 | output->Clear(); |
| 1624 | |
| 1625 | ParserImpl::SingularOverwritePolicy overwrites_policy = |
| 1626 | allow_singular_overwrites_ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES |
| 1627 | : ParserImpl::FORBID_SINGULAR_OVERWRITES; |
| 1628 | |
| 1629 | ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_, |
| 1630 | parse_info_tree_, overwrites_policy, |
| 1631 | allow_case_insensitive_field_, allow_unknown_field_, |
| 1632 | allow_unknown_extension_, allow_unknown_enum_, |
| 1633 | allow_field_number_, allow_relaxed_whitespace_, |
| 1634 | allow_partial_, recursion_limit_); |
| 1635 | return MergeUsingImpl(input, output, &parser); |
| 1636 | } |
| 1637 | |
| 1638 | bool TextFormat::Parser::ParseFromString(ConstStringParam input, |
| 1639 | Message* output) { |
| 1640 | DO(CheckParseInputSize(input, error_collector_)); |
| 1641 | io::ArrayInputStream input_stream(input.data(), input.size()); |
| 1642 | return Parse(&input_stream, output); |
| 1643 | } |
| 1644 | |
| 1645 | bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, |
| 1646 | Message* output) { |
| 1647 | ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_, |
| 1648 | parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES, |
| 1649 | allow_case_insensitive_field_, allow_unknown_field_, |
| 1650 | allow_unknown_extension_, allow_unknown_enum_, |
| 1651 | allow_field_number_, allow_relaxed_whitespace_, |
| 1652 | allow_partial_, recursion_limit_); |
| 1653 | return MergeUsingImpl(input, output, &parser); |
| 1654 | } |
| 1655 | |
| 1656 | bool TextFormat::Parser::MergeFromString(ConstStringParam input, |
| 1657 | Message* output) { |
| 1658 | DO(CheckParseInputSize(input, error_collector_)); |
| 1659 | io::ArrayInputStream input_stream(input.data(), input.size()); |
| 1660 | return Merge(&input_stream, output); |
| 1661 | } |
| 1662 | |
| 1663 | bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */, |
| 1664 | Message* output, |
| 1665 | ParserImpl* parser_impl) { |
| 1666 | if (!parser_impl->Parse(output)) return false; |
| 1667 | if (!allow_partial_ && !output->IsInitialized()) { |
| 1668 | std::vector<std::string> missing_fields; |
| 1669 | output->FindInitializationErrors(&missing_fields); |
| 1670 | parser_impl->ReportError(-1, 0, |
| 1671 | "Message missing required fields: " + |
| 1672 | Join(missing_fields, ", ")); |
| 1673 | return false; |
| 1674 | } |
| 1675 | return true; |
| 1676 | } |
| 1677 | |
| 1678 | bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input, |
| 1679 | const FieldDescriptor* field, |
| 1680 | Message* output) { |
| 1681 | io::ArrayInputStream input_stream(input.data(), input.size()); |
| 1682 | ParserImpl parser( |
| 1683 | output->GetDescriptor(), &input_stream, error_collector_, finder_, |
| 1684 | parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES, |
| 1685 | allow_case_insensitive_field_, allow_unknown_field_, |
| 1686 | allow_unknown_extension_, allow_unknown_enum_, allow_field_number_, |
| 1687 | allow_relaxed_whitespace_, allow_partial_, recursion_limit_); |
| 1688 | return parser.ParseField(field, output); |
| 1689 | } |
| 1690 | |
| 1691 | /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, |
| 1692 | Message* output) { |
| 1693 | return Parser().Parse(input, output); |
| 1694 | } |
| 1695 | |
| 1696 | /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, |
| 1697 | Message* output) { |
| 1698 | return Parser().Merge(input, output); |
| 1699 | } |
| 1700 | |
| 1701 | /* static */ bool TextFormat::ParseFromString(ConstStringParam input, |
| 1702 | Message* output) { |
| 1703 | return Parser().ParseFromString(input, output); |
| 1704 | } |
| 1705 | |
| 1706 | /* static */ bool TextFormat::MergeFromString(ConstStringParam input, |
| 1707 | Message* output) { |
| 1708 | return Parser().MergeFromString(input, output); |
| 1709 | } |
| 1710 | |
| 1711 | #undef DO |
| 1712 | |
| 1713 | // =========================================================================== |
| 1714 | |
| 1715 | TextFormat::BaseTextGenerator::~BaseTextGenerator() {} |
| 1716 | |
| 1717 | namespace { |
| 1718 | |
| 1719 | // A BaseTextGenerator that writes to a string. |
| 1720 | class StringBaseTextGenerator : public TextFormat::BaseTextGenerator { |
| 1721 | public: |
| 1722 | void Print(const char* text, size_t size) override { |
| 1723 | output_.append(text, size); |
| 1724 | } |
| 1725 | |
| 1726 | // Some compilers do not support ref-qualifiers even in C++11 mode. |
| 1727 | // Disable the optimization for now and revisit it later. |
| 1728 | #if 0 // LANG_CXX11 |
| 1729 | std::string Consume() && { return std::move(output_); } |
| 1730 | #else // !LANG_CXX11 |
| 1731 | const std::string& Get() { return output_; } |
| 1732 | #endif // LANG_CXX11 |
| 1733 | |
| 1734 | private: |
| 1735 | std::string output_; |
| 1736 | }; |
| 1737 | |
| 1738 | } // namespace |
| 1739 | |
| 1740 | // The default implementation for FieldValuePrinter. We just delegate the |
| 1741 | // implementation to the default FastFieldValuePrinter to avoid duplicating the |
| 1742 | // logic. |
| 1743 | TextFormat::FieldValuePrinter::FieldValuePrinter() {} |
| 1744 | TextFormat::FieldValuePrinter::~FieldValuePrinter() {} |
| 1745 | |
| 1746 | #if 0 // LANG_CXX11 |
| 1747 | #define FORWARD_IMPL(fn, ...) \ |
| 1748 | StringBaseTextGenerator generator; \ |
| 1749 | delegate_.fn(__VA_ARGS__, &generator); \ |
| 1750 | return std::move(generator).Consume() |
| 1751 | #else // !LANG_CXX11 |
| 1752 | #define FORWARD_IMPL(fn, ...) \ |
| 1753 | StringBaseTextGenerator generator; \ |
| 1754 | delegate_.fn(__VA_ARGS__, &generator); \ |
| 1755 | return generator.Get() |
| 1756 | #endif // LANG_CXX11 |
| 1757 | |
| 1758 | std::string TextFormat::FieldValuePrinter::PrintBool(bool val) const { |
| 1759 | FORWARD_IMPL(PrintBool, val); |
| 1760 | } |
| 1761 | std::string TextFormat::FieldValuePrinter::PrintInt32(int32_t val) const { |
| 1762 | FORWARD_IMPL(PrintInt32, val); |
| 1763 | } |
| 1764 | std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32_t val) const { |
| 1765 | FORWARD_IMPL(PrintUInt32, val); |
| 1766 | } |
| 1767 | std::string TextFormat::FieldValuePrinter::PrintInt64(int64_t val) const { |
| 1768 | FORWARD_IMPL(PrintInt64, val); |
| 1769 | } |
| 1770 | std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64_t val) const { |
| 1771 | FORWARD_IMPL(PrintUInt64, val); |
| 1772 | } |
| 1773 | std::string TextFormat::FieldValuePrinter::PrintFloat(float val) const { |
| 1774 | FORWARD_IMPL(PrintFloat, val); |
| 1775 | } |
| 1776 | std::string TextFormat::FieldValuePrinter::PrintDouble(double val) const { |
| 1777 | FORWARD_IMPL(PrintDouble, val); |
| 1778 | } |
| 1779 | std::string TextFormat::FieldValuePrinter::PrintString( |
| 1780 | const std::string& val) const { |
| 1781 | FORWARD_IMPL(PrintString, val); |
| 1782 | } |
| 1783 | std::string TextFormat::FieldValuePrinter::PrintBytes( |
| 1784 | const std::string& val) const { |
| 1785 | return PrintString(val); |
| 1786 | } |
| 1787 | std::string TextFormat::FieldValuePrinter::PrintEnum( |
| 1788 | int32_t val, const std::string& name) const { |
| 1789 | FORWARD_IMPL(PrintEnum, val, name); |
| 1790 | } |
| 1791 | std::string TextFormat::FieldValuePrinter::PrintFieldName( |
| 1792 | const Message& message, const Reflection* reflection, |
| 1793 | const FieldDescriptor* field) const { |
| 1794 | FORWARD_IMPL(PrintFieldName, message, reflection, field); |
| 1795 | } |
| 1796 | std::string TextFormat::FieldValuePrinter::PrintMessageStart( |
| 1797 | const Message& message, int field_index, int field_count, |
| 1798 | bool single_line_mode) const { |
| 1799 | FORWARD_IMPL(PrintMessageStart, message, field_index, field_count, |
| 1800 | single_line_mode); |
| 1801 | } |
| 1802 | std::string TextFormat::FieldValuePrinter::PrintMessageEnd( |
| 1803 | const Message& message, int field_index, int field_count, |
| 1804 | bool single_line_mode) const { |
| 1805 | FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count, |
| 1806 | single_line_mode); |
| 1807 | } |
| 1808 | #undef FORWARD_IMPL |
| 1809 | |
| 1810 | TextFormat::FastFieldValuePrinter::FastFieldValuePrinter() {} |
| 1811 | TextFormat::FastFieldValuePrinter::~FastFieldValuePrinter() {} |
| 1812 | void TextFormat::FastFieldValuePrinter::PrintBool( |
| 1813 | bool val, BaseTextGenerator* generator) const { |
| 1814 | if (val) { |
| 1815 | generator->PrintLiteral("true"); |
| 1816 | } else { |
| 1817 | generator->PrintLiteral("false"); |
| 1818 | } |
| 1819 | } |
| 1820 | void TextFormat::FastFieldValuePrinter::PrintInt32( |
| 1821 | int32_t val, BaseTextGenerator* generator) const { |
| 1822 | generator->PrintString(StrCat(val)); |
| 1823 | } |
| 1824 | void TextFormat::FastFieldValuePrinter::PrintUInt32( |
| 1825 | uint32_t val, BaseTextGenerator* generator) const { |
| 1826 | generator->PrintString(StrCat(val)); |
| 1827 | } |
| 1828 | void TextFormat::FastFieldValuePrinter::PrintInt64( |
| 1829 | int64_t val, BaseTextGenerator* generator) const { |
| 1830 | generator->PrintString(StrCat(val)); |
| 1831 | } |
| 1832 | void TextFormat::FastFieldValuePrinter::PrintUInt64( |
| 1833 | uint64_t val, BaseTextGenerator* generator) const { |
| 1834 | generator->PrintString(StrCat(val)); |
| 1835 | } |
| 1836 | void TextFormat::FastFieldValuePrinter::PrintFloat( |
| 1837 | float val, BaseTextGenerator* generator) const { |
| 1838 | generator->PrintString(!std::isnan(val) ? SimpleFtoa(val) : "nan"); |
| 1839 | } |
| 1840 | void TextFormat::FastFieldValuePrinter::PrintDouble( |
| 1841 | double val, BaseTextGenerator* generator) const { |
| 1842 | generator->PrintString(!std::isnan(val) ? SimpleDtoa(val) : "nan"); |
| 1843 | } |
| 1844 | void TextFormat::FastFieldValuePrinter::PrintEnum( |
| 1845 | int32_t /*val*/, const std::string& name, |
| 1846 | BaseTextGenerator* generator) const { |
| 1847 | generator->PrintString(name); |
| 1848 | } |
| 1849 | |
| 1850 | void TextFormat::FastFieldValuePrinter::PrintString( |
| 1851 | const std::string& val, BaseTextGenerator* generator) const { |
| 1852 | generator->PrintLiteral("\""); |
| 1853 | generator->PrintString(CEscape(val)); |
| 1854 | generator->PrintLiteral("\""); |
| 1855 | } |
| 1856 | void TextFormat::FastFieldValuePrinter::PrintBytes( |
| 1857 | const std::string& val, BaseTextGenerator* generator) const { |
| 1858 | PrintString(val, generator); |
| 1859 | } |
| 1860 | void TextFormat::FastFieldValuePrinter::PrintFieldName( |
| 1861 | const Message& message, int /*field_index*/, int /*field_count*/, |
| 1862 | const Reflection* reflection, const FieldDescriptor* field, |
| 1863 | BaseTextGenerator* generator) const { |
| 1864 | PrintFieldName(message, reflection, field, generator); |
| 1865 | } |
| 1866 | void TextFormat::FastFieldValuePrinter::PrintFieldName( |
| 1867 | const Message& /*message*/, const Reflection* /*reflection*/, |
| 1868 | const FieldDescriptor* field, BaseTextGenerator* generator) const { |
| 1869 | if (field->is_extension()) { |
| 1870 | generator->PrintLiteral("["); |
| 1871 | generator->PrintString(field->PrintableNameForExtension()); |
| 1872 | generator->PrintLiteral("]"); |
| 1873 | } else if (field->type() == FieldDescriptor::TYPE_GROUP) { |
| 1874 | // Groups must be serialized with their original capitalization. |
| 1875 | generator->PrintString(field->message_type()->name()); |
| 1876 | } else { |
| 1877 | generator->PrintString(field->name()); |
| 1878 | } |
| 1879 | } |
| 1880 | void TextFormat::FastFieldValuePrinter::PrintMessageStart( |
| 1881 | const Message& /*message*/, int /*field_index*/, int /*field_count*/, |
| 1882 | bool single_line_mode, BaseTextGenerator* generator) const { |
| 1883 | if (single_line_mode) { |
| 1884 | generator->PrintLiteral(" { "); |
| 1885 | } else { |
| 1886 | generator->PrintLiteral(" {\n"); |
| 1887 | } |
| 1888 | } |
| 1889 | bool TextFormat::FastFieldValuePrinter::PrintMessageContent( |
| 1890 | const Message& /*message*/, int /*field_index*/, int /*field_count*/, |
| 1891 | bool /*single_line_mode*/, BaseTextGenerator* /*generator*/) const { |
| 1892 | return false; // Use the default printing function. |
| 1893 | } |
| 1894 | void TextFormat::FastFieldValuePrinter::PrintMessageEnd( |
| 1895 | const Message& /*message*/, int /*field_index*/, int /*field_count*/, |
| 1896 | bool single_line_mode, BaseTextGenerator* generator) const { |
| 1897 | if (single_line_mode) { |
| 1898 | generator->PrintLiteral("} "); |
| 1899 | } else { |
| 1900 | generator->PrintLiteral("}\n"); |
| 1901 | } |
| 1902 | } |
| 1903 | |
| 1904 | namespace { |
| 1905 | |
| 1906 | // A legacy compatibility wrapper. Takes ownership of the delegate. |
| 1907 | class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter { |
| 1908 | public: |
| 1909 | explicit FieldValuePrinterWrapper( |
| 1910 | const TextFormat::FieldValuePrinter* delegate) |
| 1911 | : delegate_(delegate) {} |
| 1912 | |
| 1913 | void SetDelegate(const TextFormat::FieldValuePrinter* delegate) { |
| 1914 | delegate_.reset(delegate); |
| 1915 | } |
| 1916 | |
| 1917 | void PrintBool(bool val, |
| 1918 | TextFormat::BaseTextGenerator* generator) const override { |
| 1919 | generator->PrintString(delegate_->PrintBool(val)); |
| 1920 | } |
| 1921 | void PrintInt32(int32_t val, |
| 1922 | TextFormat::BaseTextGenerator* generator) const override { |
| 1923 | generator->PrintString(delegate_->PrintInt32(val)); |
| 1924 | } |
| 1925 | void PrintUInt32(uint32_t val, |
| 1926 | TextFormat::BaseTextGenerator* generator) const override { |
| 1927 | generator->PrintString(delegate_->PrintUInt32(val)); |
| 1928 | } |
| 1929 | void PrintInt64(int64_t val, |
| 1930 | TextFormat::BaseTextGenerator* generator) const override { |
| 1931 | generator->PrintString(delegate_->PrintInt64(val)); |
| 1932 | } |
| 1933 | void PrintUInt64(uint64_t val, |
| 1934 | TextFormat::BaseTextGenerator* generator) const override { |
| 1935 | generator->PrintString(delegate_->PrintUInt64(val)); |
| 1936 | } |
| 1937 | void PrintFloat(float val, |
| 1938 | TextFormat::BaseTextGenerator* generator) const override { |
| 1939 | generator->PrintString(delegate_->PrintFloat(val)); |
| 1940 | } |
| 1941 | void PrintDouble(double val, |
| 1942 | TextFormat::BaseTextGenerator* generator) const override { |
| 1943 | generator->PrintString(delegate_->PrintDouble(val)); |
| 1944 | } |
| 1945 | void PrintString(const std::string& val, |
| 1946 | TextFormat::BaseTextGenerator* generator) const override { |
| 1947 | generator->PrintString(delegate_->PrintString(val)); |
| 1948 | } |
| 1949 | void PrintBytes(const std::string& val, |
| 1950 | TextFormat::BaseTextGenerator* generator) const override { |
| 1951 | generator->PrintString(delegate_->PrintBytes(val)); |
| 1952 | } |
| 1953 | void PrintEnum(int32_t val, const std::string& name, |
| 1954 | TextFormat::BaseTextGenerator* generator) const override { |
| 1955 | generator->PrintString(delegate_->PrintEnum(val, name)); |
| 1956 | } |
| 1957 | void PrintFieldName(const Message& message, int /*field_index*/, |
| 1958 | int /*field_count*/, const Reflection* reflection, |
| 1959 | const FieldDescriptor* field, |
| 1960 | TextFormat::BaseTextGenerator* generator) const override { |
| 1961 | generator->PrintString( |
| 1962 | delegate_->PrintFieldName(message, reflection, field)); |
| 1963 | } |
| 1964 | void PrintFieldName(const Message& message, const Reflection* reflection, |
| 1965 | const FieldDescriptor* field, |
| 1966 | TextFormat::BaseTextGenerator* generator) const override { |
| 1967 | generator->PrintString( |
| 1968 | delegate_->PrintFieldName(message, reflection, field)); |
| 1969 | } |
| 1970 | void PrintMessageStart( |
| 1971 | const Message& message, int field_index, int field_count, |
| 1972 | bool single_line_mode, |
| 1973 | TextFormat::BaseTextGenerator* generator) const override { |
| 1974 | generator->PrintString(delegate_->PrintMessageStart( |
| 1975 | message, field_index, field_count, single_line_mode)); |
| 1976 | } |
| 1977 | void PrintMessageEnd( |
| 1978 | const Message& message, int field_index, int field_count, |
| 1979 | bool single_line_mode, |
| 1980 | TextFormat::BaseTextGenerator* generator) const override { |
| 1981 | generator->PrintString(delegate_->PrintMessageEnd( |
| 1982 | message, field_index, field_count, single_line_mode)); |
| 1983 | } |
| 1984 | |
| 1985 | private: |
| 1986 | std::unique_ptr<const TextFormat::FieldValuePrinter> delegate_; |
| 1987 | }; |
| 1988 | |
| 1989 | } // namespace |
| 1990 | |
| 1991 | const char* const TextFormat::Printer::kDoNotParse = |
| 1992 | "DO NOT PARSE: fields may be stripped and missing.\n"; |
| 1993 | |
| 1994 | TextFormat::Printer::Printer() |
| 1995 | : initial_indent_level_(0), |
| 1996 | single_line_mode_(false), |
| 1997 | use_field_number_(false), |
| 1998 | use_short_repeated_primitives_(false), |
| 1999 | insert_silent_marker_(false), |
| 2000 | hide_unknown_fields_(false), |
| 2001 | print_message_fields_in_index_order_(false), |
| 2002 | expand_any_(false), |
| 2003 | truncate_string_field_longer_than_(0LL), |
| 2004 | finder_(nullptr) { |
| 2005 | SetUseUtf8StringEscaping(false); |
| 2006 | } |
| 2007 | |
| 2008 | void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) { |
| 2009 | SetDefaultFieldValuePrinter(as_utf8 ? new FastFieldValuePrinterUtf8Escaping() |
| 2010 | : new DebugStringFieldValuePrinter()); |
| 2011 | } |
| 2012 | |
| 2013 | void TextFormat::Printer::SetDefaultFieldValuePrinter( |
| 2014 | const FieldValuePrinter* printer) { |
| 2015 | default_field_value_printer_.reset(new FieldValuePrinterWrapper(printer)); |
| 2016 | } |
| 2017 | |
| 2018 | void TextFormat::Printer::SetDefaultFieldValuePrinter( |
| 2019 | const FastFieldValuePrinter* printer) { |
| 2020 | default_field_value_printer_.reset(printer); |
| 2021 | } |
| 2022 | |
| 2023 | bool TextFormat::Printer::RegisterFieldValuePrinter( |
| 2024 | const FieldDescriptor* field, const FieldValuePrinter* printer) { |
| 2025 | if (field == nullptr || printer == nullptr) { |
| 2026 | return false; |
| 2027 | } |
| 2028 | std::unique_ptr<FieldValuePrinterWrapper> wrapper( |
| 2029 | new FieldValuePrinterWrapper(nullptr)); |
| 2030 | auto pair = custom_printers_.insert(std::make_pair(field, nullptr)); |
| 2031 | if (pair.second) { |
| 2032 | wrapper->SetDelegate(printer); |
| 2033 | pair.first->second = std::move(wrapper); |
| 2034 | return true; |
| 2035 | } else { |
| 2036 | return false; |
| 2037 | } |
| 2038 | } |
| 2039 | |
| 2040 | bool TextFormat::Printer::RegisterFieldValuePrinter( |
| 2041 | const FieldDescriptor* field, const FastFieldValuePrinter* printer) { |
| 2042 | if (field == nullptr || printer == nullptr) { |
| 2043 | return false; |
| 2044 | } |
| 2045 | auto pair = custom_printers_.insert(std::make_pair(field, nullptr)); |
| 2046 | if (pair.second) { |
| 2047 | pair.first->second.reset(printer); |
| 2048 | return true; |
| 2049 | } else { |
| 2050 | return false; |
| 2051 | } |
| 2052 | } |
| 2053 | |
| 2054 | bool TextFormat::Printer::RegisterMessagePrinter( |
| 2055 | const Descriptor* descriptor, const MessagePrinter* printer) { |
| 2056 | if (descriptor == nullptr || printer == nullptr) { |
| 2057 | return false; |
| 2058 | } |
| 2059 | auto pair = |
| 2060 | custom_message_printers_.insert(std::make_pair(descriptor, nullptr)); |
| 2061 | if (pair.second) { |
| 2062 | pair.first->second.reset(printer); |
| 2063 | return true; |
| 2064 | } else { |
| 2065 | return false; |
| 2066 | } |
| 2067 | } |
| 2068 | |
| 2069 | bool TextFormat::Printer::PrintToString(const Message& message, |
| 2070 | std::string* output) const { |
| 2071 | GOOGLE_DCHECK(output) << "output specified is nullptr"; |
| 2072 | |
| 2073 | output->clear(); |
| 2074 | io::StringOutputStream output_stream(output); |
| 2075 | |
| 2076 | return Print(message, &output_stream); |
| 2077 | } |
| 2078 | |
| 2079 | bool TextFormat::Printer::PrintUnknownFieldsToString( |
| 2080 | const UnknownFieldSet& unknown_fields, std::string* output) const { |
| 2081 | GOOGLE_DCHECK(output) << "output specified is nullptr"; |
| 2082 | |
| 2083 | output->clear(); |
| 2084 | io::StringOutputStream output_stream(output); |
| 2085 | return PrintUnknownFields(unknown_fields, &output_stream); |
| 2086 | } |
| 2087 | |
| 2088 | bool TextFormat::Printer::Print(const Message& message, |
| 2089 | io::ZeroCopyOutputStream* output) const { |
| 2090 | TextGenerator generator(output, insert_silent_marker_, initial_indent_level_); |
| 2091 | |
| 2092 | Print(message, &generator); |
| 2093 | |
| 2094 | // Output false if the generator failed internally. |
| 2095 | return !generator.failed(); |
| 2096 | } |
| 2097 | |
| 2098 | // Maximum recursion depth for heuristically printing out length-delimited |
| 2099 | // unknown fields as messages. |
| 2100 | static constexpr int kUnknownFieldRecursionLimit = 10; |
| 2101 | |
| 2102 | bool TextFormat::Printer::PrintUnknownFields( |
| 2103 | const UnknownFieldSet& unknown_fields, |
| 2104 | io::ZeroCopyOutputStream* output) const { |
| 2105 | TextGenerator generator(output, initial_indent_level_); |
| 2106 | |
| 2107 | PrintUnknownFields(unknown_fields, &generator, kUnknownFieldRecursionLimit); |
| 2108 | |
| 2109 | // Output false if the generator failed internally. |
| 2110 | return !generator.failed(); |
| 2111 | } |
| 2112 | |
| 2113 | namespace { |
| 2114 | // Comparison functor for sorting FieldDescriptors by field index. |
| 2115 | // Normal fields have higher precedence than extensions. |
| 2116 | struct FieldIndexSorter { |
| 2117 | bool operator()(const FieldDescriptor* left, |
| 2118 | const FieldDescriptor* right) const { |
| 2119 | if (left->is_extension() && right->is_extension()) { |
| 2120 | return left->number() < right->number(); |
| 2121 | } else if (left->is_extension()) { |
| 2122 | return false; |
| 2123 | } else if (right->is_extension()) { |
| 2124 | return true; |
| 2125 | } else { |
| 2126 | return left->index() < right->index(); |
| 2127 | } |
| 2128 | } |
| 2129 | }; |
| 2130 | |
| 2131 | } // namespace |
| 2132 | |
| 2133 | bool TextFormat::Printer::PrintAny(const Message& message, |
| 2134 | TextGenerator* generator) const { |
| 2135 | const FieldDescriptor* type_url_field; |
| 2136 | const FieldDescriptor* value_field; |
| 2137 | if (!internal::GetAnyFieldDescriptors(message, &type_url_field, |
| 2138 | &value_field)) { |
| 2139 | return false; |
| 2140 | } |
| 2141 | |
| 2142 | const Reflection* reflection = message.GetReflection(); |
| 2143 | |
| 2144 | // Extract the full type name from the type_url field. |
| 2145 | const std::string& type_url = reflection->GetString(message, type_url_field); |
| 2146 | std::string url_prefix; |
| 2147 | std::string full_type_name; |
| 2148 | if (!internal::ParseAnyTypeUrl(type_url, &url_prefix, &full_type_name)) { |
| 2149 | return false; |
| 2150 | } |
| 2151 | |
| 2152 | // Print the "value" in text. |
| 2153 | const Descriptor* value_descriptor = |
| 2154 | finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name) |
| 2155 | : DefaultFinderFindAnyType(message, url_prefix, full_type_name); |
| 2156 | if (value_descriptor == nullptr) { |
| 2157 | GOOGLE_LOG(WARNING) << "Can't print proto content: proto type " << type_url |
| 2158 | << " not found"; |
| 2159 | return false; |
| 2160 | } |
| 2161 | DynamicMessageFactory factory; |
| 2162 | std::unique_ptr<Message> value_message( |
| 2163 | factory.GetPrototype(value_descriptor)->New()); |
| 2164 | std::string serialized_value = reflection->GetString(message, value_field); |
| 2165 | if (!value_message->ParseFromString(serialized_value)) { |
| 2166 | GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents"; |
| 2167 | return false; |
| 2168 | } |
| 2169 | generator->PrintLiteral("["); |
| 2170 | generator->PrintString(type_url); |
| 2171 | generator->PrintLiteral("]"); |
| 2172 | const FastFieldValuePrinter* printer = GetFieldPrinter(value_field); |
| 2173 | printer->PrintMessageStart(message, -1, 0, single_line_mode_, generator); |
| 2174 | generator->Indent(); |
| 2175 | Print(*value_message, generator); |
| 2176 | generator->Outdent(); |
| 2177 | printer->PrintMessageEnd(message, -1, 0, single_line_mode_, generator); |
| 2178 | return true; |
| 2179 | } |
| 2180 | |
| 2181 | void TextFormat::Printer::Print(const Message& message, |
| 2182 | TextGenerator* generator) const { |
| 2183 | const Reflection* reflection = message.GetReflection(); |
| 2184 | if (!reflection) { |
| 2185 | // This message does not provide any way to describe its structure. |
| 2186 | // Parse it again in an UnknownFieldSet, and display this instead. |
| 2187 | UnknownFieldSet unknown_fields; |
| 2188 | { |
| 2189 | std::string serialized = message.SerializeAsString(); |
| 2190 | io::ArrayInputStream input(serialized.data(), serialized.size()); |
| 2191 | unknown_fields.ParseFromZeroCopyStream(&input); |
| 2192 | } |
| 2193 | PrintUnknownFields(unknown_fields, generator, kUnknownFieldRecursionLimit); |
| 2194 | return; |
| 2195 | } |
| 2196 | const Descriptor* descriptor = message.GetDescriptor(); |
| 2197 | auto itr = custom_message_printers_.find(descriptor); |
| 2198 | if (itr != custom_message_printers_.end()) { |
| 2199 | itr->second->Print(message, single_line_mode_, generator); |
| 2200 | return; |
| 2201 | } |
| 2202 | if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && |
| 2203 | PrintAny(message, generator)) { |
| 2204 | return; |
| 2205 | } |
| 2206 | std::vector<const FieldDescriptor*> fields; |
| 2207 | if (descriptor->options().map_entry()) { |
| 2208 | fields.push_back(descriptor->field(0)); |
| 2209 | fields.push_back(descriptor->field(1)); |
| 2210 | } else { |
| 2211 | reflection->ListFieldsOmitStripped(message, &fields); |
| 2212 | if (reflection->IsMessageStripped(message.GetDescriptor())) { |
| 2213 | generator->Print(kDoNotParse, std::strlen(kDoNotParse)); |
| 2214 | } |
| 2215 | } |
| 2216 | |
| 2217 | if (print_message_fields_in_index_order_) { |
| 2218 | std::sort(fields.begin(), fields.end(), FieldIndexSorter()); |
| 2219 | } |
| 2220 | for (const FieldDescriptor* field : fields) { |
| 2221 | PrintField(message, reflection, field, generator); |
| 2222 | } |
| 2223 | if (!hide_unknown_fields_) { |
| 2224 | PrintUnknownFields(reflection->GetUnknownFields(message), generator, |
| 2225 | kUnknownFieldRecursionLimit); |
| 2226 | } |
| 2227 | } |
| 2228 | |
| 2229 | void TextFormat::Printer::PrintFieldValueToString(const Message& message, |
| 2230 | const FieldDescriptor* field, |
| 2231 | int index, |
| 2232 | std::string* output) const { |
| 2233 | GOOGLE_DCHECK(output) << "output specified is nullptr"; |
| 2234 | |
| 2235 | output->clear(); |
| 2236 | io::StringOutputStream output_stream(output); |
| 2237 | TextGenerator generator(&output_stream, initial_indent_level_); |
| 2238 | |
| 2239 | PrintFieldValue(message, message.GetReflection(), field, index, &generator); |
| 2240 | } |
| 2241 | |
| 2242 | class MapEntryMessageComparator { |
| 2243 | public: |
| 2244 | explicit MapEntryMessageComparator(const Descriptor* descriptor) |
| 2245 | : field_(descriptor->field(0)) {} |
| 2246 | |
| 2247 | bool operator()(const Message* a, const Message* b) { |
| 2248 | const Reflection* reflection = a->GetReflection(); |
| 2249 | switch (field_->cpp_type()) { |
| 2250 | case FieldDescriptor::CPPTYPE_BOOL: { |
| 2251 | bool first = reflection->GetBool(*a, field_); |
| 2252 | bool second = reflection->GetBool(*b, field_); |
| 2253 | return first < second; |
| 2254 | } |
| 2255 | case FieldDescriptor::CPPTYPE_INT32: { |
| 2256 | int32_t first = reflection->GetInt32(*a, field_); |
| 2257 | int32_t second = reflection->GetInt32(*b, field_); |
| 2258 | return first < second; |
| 2259 | } |
| 2260 | case FieldDescriptor::CPPTYPE_INT64: { |
| 2261 | int64_t first = reflection->GetInt64(*a, field_); |
| 2262 | int64_t second = reflection->GetInt64(*b, field_); |
| 2263 | return first < second; |
| 2264 | } |
| 2265 | case FieldDescriptor::CPPTYPE_UINT32: { |
| 2266 | uint32_t first = reflection->GetUInt32(*a, field_); |
| 2267 | uint32_t second = reflection->GetUInt32(*b, field_); |
| 2268 | return first < second; |
| 2269 | } |
| 2270 | case FieldDescriptor::CPPTYPE_UINT64: { |
| 2271 | uint64_t first = reflection->GetUInt64(*a, field_); |
| 2272 | uint64_t second = reflection->GetUInt64(*b, field_); |
| 2273 | return first < second; |
| 2274 | } |
| 2275 | case FieldDescriptor::CPPTYPE_STRING: { |
| 2276 | std::string first = reflection->GetString(*a, field_); |
| 2277 | std::string second = reflection->GetString(*b, field_); |
| 2278 | return first < second; |
| 2279 | } |
| 2280 | default: |
| 2281 | GOOGLE_LOG(DFATAL) << "Invalid key for map field."; |
| 2282 | return true; |
| 2283 | } |
| 2284 | } |
| 2285 | |
| 2286 | private: |
| 2287 | const FieldDescriptor* field_; |
| 2288 | }; |
| 2289 | |
| 2290 | namespace internal { |
| 2291 | class MapFieldPrinterHelper { |
| 2292 | public: |
| 2293 | // DynamicMapSorter::Sort cannot be used because it enforces syncing with |
| 2294 | // repeated field. |
| 2295 | static bool SortMap(const Message& message, const Reflection* reflection, |
| 2296 | const FieldDescriptor* field, |
| 2297 | std::vector<const Message*>* sorted_map_field); |
| 2298 | static void CopyKey(const MapKey& key, Message* message, |
| 2299 | const FieldDescriptor* field_desc); |
| 2300 | static void CopyValue(const MapValueRef& value, Message* message, |
| 2301 | const FieldDescriptor* field_desc); |
| 2302 | }; |
| 2303 | |
| 2304 | // Returns true if elements contained in sorted_map_field need to be released. |
| 2305 | bool MapFieldPrinterHelper::SortMap( |
| 2306 | const Message& message, const Reflection* reflection, |
| 2307 | const FieldDescriptor* field, |
| 2308 | std::vector<const Message*>* sorted_map_field) { |
| 2309 | bool need_release = false; |
| 2310 | const MapFieldBase& base = *reflection->GetMapData(message, field); |
| 2311 | |
| 2312 | if (base.IsRepeatedFieldValid()) { |
| 2313 | const RepeatedPtrField<Message>& map_field = |
| 2314 | reflection->GetRepeatedPtrFieldInternal<Message>(message, field); |
| 2315 | for (int i = 0; i < map_field.size(); ++i) { |
| 2316 | sorted_map_field->push_back( |
| 2317 | const_cast<RepeatedPtrField<Message>*>(&map_field)->Mutable(i)); |
| 2318 | } |
| 2319 | } else { |
| 2320 | // TODO(teboring): For performance, instead of creating map entry message |
| 2321 | // for each element, just store map keys and sort them. |
| 2322 | const Descriptor* map_entry_desc = field->message_type(); |
| 2323 | const Message* prototype = |
| 2324 | reflection->GetMessageFactory()->GetPrototype(map_entry_desc); |
| 2325 | for (MapIterator iter = |
| 2326 | reflection->MapBegin(const_cast<Message*>(&message), field); |
| 2327 | iter != reflection->MapEnd(const_cast<Message*>(&message), field); |
| 2328 | ++iter) { |
| 2329 | Message* map_entry_message = prototype->New(); |
| 2330 | CopyKey(iter.GetKey(), map_entry_message, map_entry_desc->field(0)); |
| 2331 | CopyValue(iter.GetValueRef(), map_entry_message, |
| 2332 | map_entry_desc->field(1)); |
| 2333 | sorted_map_field->push_back(map_entry_message); |
| 2334 | } |
| 2335 | need_release = true; |
| 2336 | } |
| 2337 | |
| 2338 | MapEntryMessageComparator comparator(field->message_type()); |
| 2339 | std::stable_sort(sorted_map_field->begin(), sorted_map_field->end(), |
| 2340 | comparator); |
| 2341 | return need_release; |
| 2342 | } |
| 2343 | |
| 2344 | void MapFieldPrinterHelper::CopyKey(const MapKey& key, Message* message, |
| 2345 | const FieldDescriptor* field_desc) { |
| 2346 | const Reflection* reflection = message->GetReflection(); |
| 2347 | switch (field_desc->cpp_type()) { |
| 2348 | case FieldDescriptor::CPPTYPE_DOUBLE: |
| 2349 | case FieldDescriptor::CPPTYPE_FLOAT: |
| 2350 | case FieldDescriptor::CPPTYPE_ENUM: |
| 2351 | case FieldDescriptor::CPPTYPE_MESSAGE: |
| 2352 | GOOGLE_LOG(ERROR) << "Not supported."; |
| 2353 | break; |
| 2354 | case FieldDescriptor::CPPTYPE_STRING: |
| 2355 | reflection->SetString(message, field_desc, key.GetStringValue()); |
| 2356 | return; |
| 2357 | case FieldDescriptor::CPPTYPE_INT64: |
| 2358 | reflection->SetInt64(message, field_desc, key.GetInt64Value()); |
| 2359 | return; |
| 2360 | case FieldDescriptor::CPPTYPE_INT32: |
| 2361 | reflection->SetInt32(message, field_desc, key.GetInt32Value()); |
| 2362 | return; |
| 2363 | case FieldDescriptor::CPPTYPE_UINT64: |
| 2364 | reflection->SetUInt64(message, field_desc, key.GetUInt64Value()); |
| 2365 | return; |
| 2366 | case FieldDescriptor::CPPTYPE_UINT32: |
| 2367 | reflection->SetUInt32(message, field_desc, key.GetUInt32Value()); |
| 2368 | return; |
| 2369 | case FieldDescriptor::CPPTYPE_BOOL: |
| 2370 | reflection->SetBool(message, field_desc, key.GetBoolValue()); |
| 2371 | return; |
| 2372 | } |
| 2373 | } |
| 2374 | |
| 2375 | void MapFieldPrinterHelper::CopyValue(const MapValueRef& value, |
| 2376 | Message* message, |
| 2377 | const FieldDescriptor* field_desc) { |
| 2378 | const Reflection* reflection = message->GetReflection(); |
| 2379 | switch (field_desc->cpp_type()) { |
| 2380 | case FieldDescriptor::CPPTYPE_DOUBLE: |
| 2381 | reflection->SetDouble(message, field_desc, value.GetDoubleValue()); |
| 2382 | return; |
| 2383 | case FieldDescriptor::CPPTYPE_FLOAT: |
| 2384 | reflection->SetFloat(message, field_desc, value.GetFloatValue()); |
| 2385 | return; |
| 2386 | case FieldDescriptor::CPPTYPE_ENUM: |
| 2387 | reflection->SetEnumValue(message, field_desc, value.GetEnumValue()); |
| 2388 | return; |
| 2389 | case FieldDescriptor::CPPTYPE_MESSAGE: { |
| 2390 | Message* sub_message = value.GetMessageValue().New(); |
| 2391 | sub_message->CopyFrom(value.GetMessageValue()); |
| 2392 | reflection->SetAllocatedMessage(message, sub_message, field_desc); |
| 2393 | return; |
| 2394 | } |
| 2395 | case FieldDescriptor::CPPTYPE_STRING: |
| 2396 | reflection->SetString(message, field_desc, value.GetStringValue()); |
| 2397 | return; |
| 2398 | case FieldDescriptor::CPPTYPE_INT64: |
| 2399 | reflection->SetInt64(message, field_desc, value.GetInt64Value()); |
| 2400 | return; |
| 2401 | case FieldDescriptor::CPPTYPE_INT32: |
| 2402 | reflection->SetInt32(message, field_desc, value.GetInt32Value()); |
| 2403 | return; |
| 2404 | case FieldDescriptor::CPPTYPE_UINT64: |
| 2405 | reflection->SetUInt64(message, field_desc, value.GetUInt64Value()); |
| 2406 | return; |
| 2407 | case FieldDescriptor::CPPTYPE_UINT32: |
| 2408 | reflection->SetUInt32(message, field_desc, value.GetUInt32Value()); |
| 2409 | return; |
| 2410 | case FieldDescriptor::CPPTYPE_BOOL: |
| 2411 | reflection->SetBool(message, field_desc, value.GetBoolValue()); |
| 2412 | return; |
| 2413 | } |
| 2414 | } |
| 2415 | } // namespace internal |
| 2416 | |
| 2417 | void TextFormat::Printer::PrintField(const Message& message, |
| 2418 | const Reflection* reflection, |
| 2419 | const FieldDescriptor* field, |
| 2420 | TextGenerator* generator) const { |
| 2421 | if (use_short_repeated_primitives_ && field->is_repeated() && |
| 2422 | field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && |
| 2423 | field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { |
| 2424 | PrintShortRepeatedField(message, reflection, field, generator); |
| 2425 | return; |
| 2426 | } |
| 2427 | |
| 2428 | int count = 0; |
| 2429 | |
| 2430 | if (field->is_repeated()) { |
| 2431 | count = reflection->FieldSize(message, field); |
| 2432 | } else if (reflection->HasField(message, field) || |
| 2433 | field->containing_type()->options().map_entry()) { |
| 2434 | count = 1; |
| 2435 | } |
| 2436 | |
| 2437 | std::vector<const Message*> sorted_map_field; |
| 2438 | bool need_release = false; |
| 2439 | bool is_map = field->is_map(); |
| 2440 | if (is_map) { |
| 2441 | need_release = internal::MapFieldPrinterHelper::SortMap( |
| 2442 | message, reflection, field, &sorted_map_field); |
| 2443 | } |
| 2444 | |
| 2445 | for (int j = 0; j < count; ++j) { |
| 2446 | const int field_index = field->is_repeated() ? j : -1; |
| 2447 | |
| 2448 | PrintFieldName(message, field_index, count, reflection, field, generator); |
| 2449 | |
| 2450 | if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 2451 | const FastFieldValuePrinter* printer = GetFieldPrinter(field); |
| 2452 | const Message& sub_message = |
| 2453 | field->is_repeated() |
| 2454 | ? (is_map ? *sorted_map_field[j] |
| 2455 | : reflection->GetRepeatedMessage(message, field, j)) |
| 2456 | : reflection->GetMessage(message, field); |
| 2457 | printer->PrintMessageStart(sub_message, field_index, count, |
| 2458 | single_line_mode_, generator); |
| 2459 | generator->Indent(); |
| 2460 | if (!printer->PrintMessageContent(sub_message, field_index, count, |
| 2461 | single_line_mode_, generator)) { |
| 2462 | Print(sub_message, generator); |
| 2463 | } |
| 2464 | generator->Outdent(); |
| 2465 | printer->PrintMessageEnd(sub_message, field_index, count, |
| 2466 | single_line_mode_, generator); |
| 2467 | } else { |
| 2468 | generator->PrintMaybeWithMarker(": "); |
| 2469 | // Write the field value. |
| 2470 | PrintFieldValue(message, reflection, field, field_index, generator); |
| 2471 | if (single_line_mode_) { |
| 2472 | generator->PrintLiteral(" "); |
| 2473 | } else { |
| 2474 | generator->PrintLiteral("\n"); |
| 2475 | } |
| 2476 | } |
| 2477 | } |
| 2478 | |
| 2479 | if (need_release) { |
| 2480 | for (const Message* message_to_delete : sorted_map_field) { |
| 2481 | delete message_to_delete; |
| 2482 | } |
| 2483 | } |
| 2484 | } |
| 2485 | |
| 2486 | void TextFormat::Printer::PrintShortRepeatedField( |
| 2487 | const Message& message, const Reflection* reflection, |
| 2488 | const FieldDescriptor* field, TextGenerator* generator) const { |
| 2489 | // Print primitive repeated field in short form. |
| 2490 | int size = reflection->FieldSize(message, field); |
| 2491 | PrintFieldName(message, /*field_index=*/-1, /*field_count=*/size, reflection, |
| 2492 | field, generator); |
| 2493 | generator->PrintMaybeWithMarker(": ", "["); |
| 2494 | for (int i = 0; i < size; i++) { |
| 2495 | if (i > 0) generator->PrintLiteral(", "); |
| 2496 | PrintFieldValue(message, reflection, field, i, generator); |
| 2497 | } |
| 2498 | if (single_line_mode_) { |
| 2499 | generator->PrintLiteral("] "); |
| 2500 | } else { |
| 2501 | generator->PrintLiteral("]\n"); |
| 2502 | } |
| 2503 | } |
| 2504 | |
| 2505 | void TextFormat::Printer::PrintFieldName(const Message& message, |
| 2506 | int field_index, int field_count, |
| 2507 | const Reflection* reflection, |
| 2508 | const FieldDescriptor* field, |
| 2509 | TextGenerator* generator) const { |
| 2510 | // if use_field_number_ is true, prints field number instead |
| 2511 | // of field name. |
| 2512 | if (use_field_number_) { |
| 2513 | generator->PrintString(StrCat(field->number())); |
| 2514 | return; |
| 2515 | } |
| 2516 | |
| 2517 | const FastFieldValuePrinter* printer = GetFieldPrinter(field); |
| 2518 | printer->PrintFieldName(message, field_index, field_count, reflection, field, |
| 2519 | generator); |
| 2520 | } |
| 2521 | |
| 2522 | void TextFormat::Printer::PrintFieldValue(const Message& message, |
| 2523 | const Reflection* reflection, |
| 2524 | const FieldDescriptor* field, |
| 2525 | int index, |
| 2526 | TextGenerator* generator) const { |
| 2527 | GOOGLE_DCHECK(field->is_repeated() || (index == -1)) |
| 2528 | << "Index must be -1 for non-repeated fields"; |
| 2529 | |
| 2530 | const FastFieldValuePrinter* printer = GetFieldPrinter(field); |
| 2531 | |
| 2532 | switch (field->cpp_type()) { |
| 2533 | #define OUTPUT_FIELD(CPPTYPE, METHOD) \ |
| 2534 | case FieldDescriptor::CPPTYPE_##CPPTYPE: \ |
| 2535 | printer->Print##METHOD( \ |
| 2536 | field->is_repeated() \ |
| 2537 | ? reflection->GetRepeated##METHOD(message, field, index) \ |
| 2538 | : reflection->Get##METHOD(message, field), \ |
| 2539 | generator); \ |
| 2540 | break |
| 2541 | |
| 2542 | OUTPUT_FIELD(INT32, Int32); |
| 2543 | OUTPUT_FIELD(INT64, Int64); |
| 2544 | OUTPUT_FIELD(UINT32, UInt32); |
| 2545 | OUTPUT_FIELD(UINT64, UInt64); |
| 2546 | OUTPUT_FIELD(FLOAT, Float); |
| 2547 | OUTPUT_FIELD(DOUBLE, Double); |
| 2548 | OUTPUT_FIELD(BOOL, Bool); |
| 2549 | #undef OUTPUT_FIELD |
| 2550 | |
| 2551 | case FieldDescriptor::CPPTYPE_STRING: { |
| 2552 | std::string scratch; |
| 2553 | const std::string& value = |
| 2554 | field->is_repeated() |
| 2555 | ? reflection->GetRepeatedStringReference(message, field, index, |
| 2556 | &scratch) |
| 2557 | : reflection->GetStringReference(message, field, &scratch); |
| 2558 | const std::string* value_to_print = &value; |
| 2559 | std::string truncated_value; |
| 2560 | if (truncate_string_field_longer_than_ > 0 && |
| 2561 | static_cast<size_t>(truncate_string_field_longer_than_) < |
| 2562 | value.size()) { |
| 2563 | truncated_value = value.substr(0, truncate_string_field_longer_than_) + |
| 2564 | "...<truncated>..."; |
| 2565 | value_to_print = &truncated_value; |
| 2566 | } |
| 2567 | if (field->type() == FieldDescriptor::TYPE_STRING) { |
| 2568 | printer->PrintString(*value_to_print, generator); |
| 2569 | } else { |
| 2570 | GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES); |
| 2571 | printer->PrintBytes(*value_to_print, generator); |
| 2572 | } |
| 2573 | break; |
| 2574 | } |
| 2575 | |
| 2576 | case FieldDescriptor::CPPTYPE_ENUM: { |
| 2577 | int enum_value = |
| 2578 | field->is_repeated() |
| 2579 | ? reflection->GetRepeatedEnumValue(message, field, index) |
| 2580 | : reflection->GetEnumValue(message, field); |
| 2581 | const EnumValueDescriptor* enum_desc = |
| 2582 | field->enum_type()->FindValueByNumber(enum_value); |
| 2583 | if (enum_desc != nullptr) { |
| 2584 | printer->PrintEnum(enum_value, enum_desc->name(), generator); |
| 2585 | } else { |
| 2586 | // Ordinarily, enum_desc should not be null, because proto2 has the |
| 2587 | // invariant that set enum field values must be in-range, but with the |
| 2588 | // new integer-based API for enums (or the RepeatedField<int> loophole), |
| 2589 | // it is possible for the user to force an unknown integer value. So we |
| 2590 | // simply use the integer value itself as the enum value name in this |
| 2591 | // case. |
| 2592 | printer->PrintEnum(enum_value, StrCat(enum_value), generator); |
| 2593 | } |
| 2594 | break; |
| 2595 | } |
| 2596 | |
| 2597 | case FieldDescriptor::CPPTYPE_MESSAGE: |
| 2598 | Print(field->is_repeated() |
| 2599 | ? reflection->GetRepeatedMessage(message, field, index) |
| 2600 | : reflection->GetMessage(message, field), |
| 2601 | generator); |
| 2602 | break; |
| 2603 | } |
| 2604 | } |
| 2605 | |
| 2606 | /* static */ bool TextFormat::Print(const Message& message, |
| 2607 | io::ZeroCopyOutputStream* output) { |
| 2608 | return Printer().Print(message, output); |
| 2609 | } |
| 2610 | |
| 2611 | /* static */ bool TextFormat::PrintUnknownFields( |
| 2612 | const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) { |
| 2613 | return Printer().PrintUnknownFields(unknown_fields, output); |
| 2614 | } |
| 2615 | |
| 2616 | /* static */ bool TextFormat::PrintToString(const Message& message, |
| 2617 | std::string* output) { |
| 2618 | return Printer().PrintToString(message, output); |
| 2619 | } |
| 2620 | |
| 2621 | /* static */ bool TextFormat::PrintUnknownFieldsToString( |
| 2622 | const UnknownFieldSet& unknown_fields, std::string* output) { |
| 2623 | return Printer().PrintUnknownFieldsToString(unknown_fields, output); |
| 2624 | } |
| 2625 | |
| 2626 | /* static */ void TextFormat::PrintFieldValueToString( |
| 2627 | const Message& message, const FieldDescriptor* field, int index, |
| 2628 | std::string* output) { |
| 2629 | return Printer().PrintFieldValueToString(message, field, index, output); |
| 2630 | } |
| 2631 | |
| 2632 | /* static */ bool TextFormat::ParseFieldValueFromString( |
| 2633 | const std::string& input, const FieldDescriptor* field, Message* message) { |
| 2634 | return Parser().ParseFieldValueFromString(input, field, message); |
| 2635 | } |
| 2636 | |
| 2637 | void TextFormat::Printer::PrintUnknownFields( |
| 2638 | const UnknownFieldSet& unknown_fields, TextGenerator* generator, |
| 2639 | int recursion_budget) const { |
| 2640 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
| 2641 | const UnknownField& field = unknown_fields.field(i); |
| 2642 | std::string field_number = StrCat(field.number()); |
| 2643 | |
| 2644 | switch (field.type()) { |
| 2645 | case UnknownField::TYPE_VARINT: |
| 2646 | generator->PrintString(field_number); |
| 2647 | generator->PrintMaybeWithMarker(": "); |
| 2648 | generator->PrintString(StrCat(field.varint())); |
| 2649 | if (single_line_mode_) { |
| 2650 | generator->PrintLiteral(" "); |
| 2651 | } else { |
| 2652 | generator->PrintLiteral("\n"); |
| 2653 | } |
| 2654 | break; |
| 2655 | case UnknownField::TYPE_FIXED32: { |
| 2656 | generator->PrintString(field_number); |
| 2657 | generator->PrintMaybeWithMarker(": ", "0x"); |
| 2658 | generator->PrintString( |
| 2659 | StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8))); |
| 2660 | if (single_line_mode_) { |
| 2661 | generator->PrintLiteral(" "); |
| 2662 | } else { |
| 2663 | generator->PrintLiteral("\n"); |
| 2664 | } |
| 2665 | break; |
| 2666 | } |
| 2667 | case UnknownField::TYPE_FIXED64: { |
| 2668 | generator->PrintString(field_number); |
| 2669 | generator->PrintMaybeWithMarker(": ", "0x"); |
| 2670 | generator->PrintString( |
| 2671 | StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16))); |
| 2672 | if (single_line_mode_) { |
| 2673 | generator->PrintLiteral(" "); |
| 2674 | } else { |
| 2675 | generator->PrintLiteral("\n"); |
| 2676 | } |
| 2677 | break; |
| 2678 | } |
| 2679 | case UnknownField::TYPE_LENGTH_DELIMITED: { |
| 2680 | generator->PrintString(field_number); |
| 2681 | const std::string& value = field.length_delimited(); |
| 2682 | // We create a CodedInputStream so that we can adhere to our recursion |
| 2683 | // budget when we attempt to parse the data. UnknownFieldSet parsing is |
| 2684 | // recursive because of groups. |
| 2685 | io::CodedInputStream input_stream( |
| 2686 | reinterpret_cast<const uint8_t*>(value.data()), value.size()); |
| 2687 | input_stream.SetRecursionLimit(recursion_budget); |
| 2688 | UnknownFieldSet embedded_unknown_fields; |
| 2689 | if (!value.empty() && recursion_budget > 0 && |
| 2690 | embedded_unknown_fields.ParseFromCodedStream(&input_stream)) { |
| 2691 | // This field is parseable as a Message. |
| 2692 | // So it is probably an embedded message. |
| 2693 | if (single_line_mode_) { |
| 2694 | generator->PrintMaybeWithMarker(" ", "{ "); |
| 2695 | } else { |
| 2696 | generator->PrintMaybeWithMarker(" ", "{\n"); |
| 2697 | generator->Indent(); |
| 2698 | } |
| 2699 | PrintUnknownFields(embedded_unknown_fields, generator, |
| 2700 | recursion_budget - 1); |
| 2701 | if (single_line_mode_) { |
| 2702 | generator->PrintLiteral("} "); |
| 2703 | } else { |
| 2704 | generator->Outdent(); |
| 2705 | generator->PrintLiteral("}\n"); |
| 2706 | } |
| 2707 | } else { |
| 2708 | // This field is not parseable as a Message (or we ran out of |
| 2709 | // recursion budget). So it is probably just a plain string. |
| 2710 | generator->PrintMaybeWithMarker(": ", "\""); |
| 2711 | generator->PrintString(CEscape(value)); |
| 2712 | if (single_line_mode_) { |
| 2713 | generator->PrintLiteral("\" "); |
| 2714 | } else { |
| 2715 | generator->PrintLiteral("\"\n"); |
| 2716 | } |
| 2717 | } |
| 2718 | break; |
| 2719 | } |
| 2720 | case UnknownField::TYPE_GROUP: |
| 2721 | generator->PrintString(field_number); |
| 2722 | if (single_line_mode_) { |
| 2723 | generator->PrintMaybeWithMarker(" ", "{ "); |
| 2724 | } else { |
| 2725 | generator->PrintMaybeWithMarker(" ", "{\n"); |
| 2726 | generator->Indent(); |
| 2727 | } |
| 2728 | // For groups, we recurse without checking the budget. This is OK, |
| 2729 | // because if the groups were too deeply nested then we would have |
| 2730 | // already rejected the message when we originally parsed it. |
| 2731 | PrintUnknownFields(field.group(), generator, recursion_budget - 1); |
| 2732 | if (single_line_mode_) { |
| 2733 | generator->PrintLiteral("} "); |
| 2734 | } else { |
| 2735 | generator->Outdent(); |
| 2736 | generator->PrintLiteral("}\n"); |
| 2737 | } |
| 2738 | break; |
| 2739 | } |
| 2740 | } |
| 2741 | } |
| 2742 | |
| 2743 | } // namespace protobuf |
| 2744 | } // namespace google |
| 2745 | |
| 2746 | #include <google/protobuf/port_undef.inc> |