OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // http://code.google.com/p/protobuf/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
(...skipping 11 matching lines...) Expand all Loading... |
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | 30 |
31 // Author: jschorr@google.com (Joseph Schorr) | 31 // Author: jschorr@google.com (Joseph Schorr) |
32 // Based on original Protocol Buffers design by | 32 // Based on original Protocol Buffers design by |
33 // Sanjay Ghemawat, Jeff Dean, and others. | 33 // Sanjay Ghemawat, Jeff Dean, and others. |
34 | 34 |
| 35 #include <algorithm> |
35 #include <float.h> | 36 #include <float.h> |
36 #include <math.h> | 37 #include <math.h> |
37 #include <stdio.h> | 38 #include <stdio.h> |
38 #include <stack> | 39 #include <stack> |
39 #include <limits> | 40 #include <limits> |
40 #include <vector> | 41 #include <vector> |
41 | 42 |
42 #include <google/protobuf/text_format.h> | 43 #include <google/protobuf/text_format.h> |
43 | 44 |
44 #include <google/protobuf/descriptor.h> | 45 #include <google/protobuf/descriptor.h> |
| 46 #include <google/protobuf/dynamic_message.h> |
| 47 #include <google/protobuf/repeated_field.h> |
| 48 #include <google/protobuf/wire_format_lite.h> |
| 49 #include <google/protobuf/io/strtod.h> |
45 #include <google/protobuf/io/coded_stream.h> | 50 #include <google/protobuf/io/coded_stream.h> |
46 #include <google/protobuf/io/zero_copy_stream.h> | 51 #include <google/protobuf/io/zero_copy_stream.h> |
47 #include <google/protobuf/io/zero_copy_stream_impl.h> | 52 #include <google/protobuf/io/zero_copy_stream_impl.h> |
48 #include <google/protobuf/unknown_field_set.h> | 53 #include <google/protobuf/unknown_field_set.h> |
49 #include <google/protobuf/descriptor.pb.h> | 54 #include <google/protobuf/descriptor.pb.h> |
50 #include <google/protobuf/io/tokenizer.h> | 55 #include <google/protobuf/io/tokenizer.h> |
| 56 #include <google/protobuf/any.h> |
| 57 #include <google/protobuf/stubs/stringprintf.h> |
51 #include <google/protobuf/stubs/strutil.h> | 58 #include <google/protobuf/stubs/strutil.h> |
52 #include <google/protobuf/stubs/map-util.h> | 59 #include <google/protobuf/stubs/map_util.h> |
53 #include <google/protobuf/stubs/stl_util.h> | 60 #include <google/protobuf/stubs/stl_util.h> |
54 | 61 |
55 namespace google { | 62 namespace google { |
56 namespace protobuf { | 63 namespace protobuf { |
57 | 64 |
| 65 namespace { |
| 66 |
| 67 inline bool IsHexNumber(const string& str) { |
| 68 return (str.length() >= 2 && str[0] == '0' && |
| 69 (str[1] == 'x' || str[1] == 'X')); |
| 70 } |
| 71 |
| 72 inline bool IsOctNumber(const string& str) { |
| 73 return (str.length() >= 2 && str[0] == '0' && |
| 74 (str[1] >= '0' && str[1] < '8')); |
| 75 } |
| 76 |
| 77 inline bool GetAnyFieldDescriptors(const Message& message, |
| 78 const FieldDescriptor** type_url_field, |
| 79 const FieldDescriptor** value_field) { |
| 80 const Descriptor* descriptor = message.GetDescriptor(); |
| 81 *type_url_field = descriptor->FindFieldByNumber(1); |
| 82 *value_field = descriptor->FindFieldByNumber(2); |
| 83 return (*type_url_field != NULL && |
| 84 (*type_url_field)->type() == FieldDescriptor::TYPE_STRING && |
| 85 *value_field != NULL && |
| 86 (*value_field)->type() == FieldDescriptor::TYPE_BYTES); |
| 87 } |
| 88 |
| 89 } // namespace |
| 90 |
58 string Message::DebugString() const { | 91 string Message::DebugString() const { |
59 string debug_string; | 92 string debug_string; |
60 | 93 |
61 TextFormat::PrintToString(*this, &debug_string); | 94 TextFormat::PrintToString(*this, &debug_string); |
62 | 95 |
63 return debug_string; | 96 return debug_string; |
64 } | 97 } |
65 | 98 |
66 string Message::ShortDebugString() const { | 99 string Message::ShortDebugString() const { |
67 string debug_string; | 100 string debug_string; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 // a time. | 203 // a time. |
171 | 204 |
172 // Makes code slightly more readable. The meaning of "DO(foo)" is | 205 // Makes code slightly more readable. The meaning of "DO(foo)" is |
173 // "Execute foo and fail if it fails.", where failure is indicated by | 206 // "Execute foo and fail if it fails.", where failure is indicated by |
174 // returning false. Borrowed from parser.cc (Thanks Kenton!). | 207 // returning false. Borrowed from parser.cc (Thanks Kenton!). |
175 #define DO(STATEMENT) if (STATEMENT) {} else return false | 208 #define DO(STATEMENT) if (STATEMENT) {} else return false |
176 | 209 |
177 class TextFormat::Parser::ParserImpl { | 210 class TextFormat::Parser::ParserImpl { |
178 public: | 211 public: |
179 | 212 |
180 // Determines if repeated values for a non-repeated field are | 213 // Determines if repeated values for non-repeated fields and |
181 // permitted, e.g., the string "foo: 1 foo: 2" for a | 214 // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a |
182 // required/optional field named "foo". | 215 // required/optional field named "foo", or "baz: 1 qux: 2" |
| 216 // where "baz" and "qux" are members of the same oneof. |
183 enum SingularOverwritePolicy { | 217 enum SingularOverwritePolicy { |
184 ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained | 218 ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained |
185 FORBID_SINGULAR_OVERWRITES = 1, // an error is issued | 219 FORBID_SINGULAR_OVERWRITES = 1, // an error is issued |
186 }; | 220 }; |
187 | 221 |
188 ParserImpl(const Descriptor* root_message_type, | 222 ParserImpl(const Descriptor* root_message_type, |
189 io::ZeroCopyInputStream* input_stream, | 223 io::ZeroCopyInputStream* input_stream, |
190 io::ErrorCollector* error_collector, | 224 io::ErrorCollector* error_collector, |
191 TextFormat::Finder* finder, | 225 TextFormat::Finder* finder, |
192 ParseInfoTree* parse_info_tree, | 226 ParseInfoTree* parse_info_tree, |
193 SingularOverwritePolicy singular_overwrite_policy, | 227 SingularOverwritePolicy singular_overwrite_policy, |
194 bool allow_unknown_field) | 228 bool allow_case_insensitive_field, |
| 229 bool allow_unknown_field, |
| 230 bool allow_unknown_enum, |
| 231 bool allow_field_number, |
| 232 bool allow_relaxed_whitespace) |
195 : error_collector_(error_collector), | 233 : error_collector_(error_collector), |
196 finder_(finder), | 234 finder_(finder), |
197 parse_info_tree_(parse_info_tree), | 235 parse_info_tree_(parse_info_tree), |
198 tokenizer_error_collector_(this), | 236 tokenizer_error_collector_(this), |
199 tokenizer_(input_stream, &tokenizer_error_collector_), | 237 tokenizer_(input_stream, &tokenizer_error_collector_), |
200 root_message_type_(root_message_type), | 238 root_message_type_(root_message_type), |
201 singular_overwrite_policy_(singular_overwrite_policy), | 239 singular_overwrite_policy_(singular_overwrite_policy), |
| 240 allow_case_insensitive_field_(allow_case_insensitive_field), |
202 allow_unknown_field_(allow_unknown_field), | 241 allow_unknown_field_(allow_unknown_field), |
| 242 allow_unknown_enum_(allow_unknown_enum), |
| 243 allow_field_number_(allow_field_number), |
203 had_errors_(false) { | 244 had_errors_(false) { |
204 // For backwards-compatibility with proto1, we need to allow the 'f' suffix | 245 // For backwards-compatibility with proto1, we need to allow the 'f' suffix |
205 // for floats. | 246 // for floats. |
206 tokenizer_.set_allow_f_after_float(true); | 247 tokenizer_.set_allow_f_after_float(true); |
207 | 248 |
208 // '#' starts a comment. | 249 // '#' starts a comment. |
209 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); | 250 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); |
210 | 251 |
| 252 if (allow_relaxed_whitespace) { |
| 253 tokenizer_.set_require_space_after_number(false); |
| 254 tokenizer_.set_allow_multiline_strings(true); |
| 255 } |
| 256 |
211 // Consume the starting token. | 257 // Consume the starting token. |
212 tokenizer_.Next(); | 258 tokenizer_.Next(); |
213 } | 259 } |
214 ~ParserImpl() { } | 260 ~ParserImpl() { } |
215 | 261 |
216 // Parses the ASCII representation specified in input and saves the | 262 // Parses the ASCII representation specified in input and saves the |
217 // information into the output pointer (a Message). Returns | 263 // information into the output pointer (a Message). Returns |
218 // false if an error occurs (an error will also be logged to | 264 // false if an error occurs (an error will also be logged to |
219 // GOOGLE_LOG(ERROR)). | 265 // GOOGLE_LOG(ERROR)). |
220 bool Parse(Message* output) { | 266 bool Parse(Message* output) { |
221 // Consume fields until we cannot do so anymore. | 267 // Consume fields until we cannot do so anymore. |
222 while(true) { | 268 while (true) { |
223 if (LookingAtType(io::Tokenizer::TYPE_END)) { | 269 if (LookingAtType(io::Tokenizer::TYPE_END)) { |
224 return !had_errors_; | 270 return !had_errors_; |
225 } | 271 } |
226 | 272 |
227 DO(ConsumeField(output)); | 273 DO(ConsumeField(output)); |
228 } | 274 } |
229 } | 275 } |
230 | 276 |
231 bool ParseField(const FieldDescriptor* field, Message* output) { | 277 bool ParseField(const FieldDescriptor* field, Message* output) { |
232 bool suc; | 278 bool suc; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 message); | 329 message); |
284 } | 330 } |
285 | 331 |
286 // Reports a warning with the given message with information indicating | 332 // Reports a warning with the given message with information indicating |
287 // the position (as derived from the current token). | 333 // the position (as derived from the current token). |
288 void ReportWarning(const string& message) { | 334 void ReportWarning(const string& message) { |
289 ReportWarning(tokenizer_.current().line, tokenizer_.current().column, | 335 ReportWarning(tokenizer_.current().line, tokenizer_.current().column, |
290 message); | 336 message); |
291 } | 337 } |
292 | 338 |
293 // Consumes the specified message with the given starting delimeter. | 339 // Consumes the specified message with the given starting delimiter. |
294 // This method checks to see that the end delimeter at the conclusion of | 340 // This method checks to see that the end delimiter at the conclusion of |
295 // the consumption matches the starting delimeter passed in here. | 341 // the consumption matches the starting delimiter passed in here. |
296 bool ConsumeMessage(Message* message, const string delimeter) { | 342 bool ConsumeMessage(Message* message, const string delimiter) { |
297 while (!LookingAt(">") && !LookingAt("}")) { | 343 while (!LookingAt(">") && !LookingAt("}")) { |
298 DO(ConsumeField(message)); | 344 DO(ConsumeField(message)); |
299 } | 345 } |
300 | 346 |
301 // Confirm that we have a valid ending delimeter. | 347 // Confirm that we have a valid ending delimiter. |
302 DO(Consume(delimeter)); | 348 DO(Consume(delimiter)); |
303 | |
304 return true; | 349 return true; |
305 } | 350 } |
306 | 351 |
| 352 // Consume either "<" or "{". |
| 353 bool ConsumeMessageDelimiter(string* delimiter) { |
| 354 if (TryConsume("<")) { |
| 355 *delimiter = ">"; |
| 356 } else { |
| 357 DO(Consume("{")); |
| 358 *delimiter = "}"; |
| 359 } |
| 360 return true; |
| 361 } |
| 362 |
| 363 |
307 // Consumes the current field (as returned by the tokenizer) on the | 364 // Consumes the current field (as returned by the tokenizer) on the |
308 // passed in message. | 365 // passed in message. |
309 bool ConsumeField(Message* message) { | 366 bool ConsumeField(Message* message) { |
310 const Reflection* reflection = message->GetReflection(); | 367 const Reflection* reflection = message->GetReflection(); |
311 const Descriptor* descriptor = message->GetDescriptor(); | 368 const Descriptor* descriptor = message->GetDescriptor(); |
312 | 369 |
313 string field_name; | 370 string field_name; |
314 | 371 |
315 const FieldDescriptor* field = NULL; | 372 const FieldDescriptor* field = NULL; |
316 int start_line = tokenizer_.current().line; | 373 int start_line = tokenizer_.current().line; |
317 int start_column = tokenizer_.current().column; | 374 int start_column = tokenizer_.current().column; |
318 | 375 |
| 376 const FieldDescriptor* any_type_url_field; |
| 377 const FieldDescriptor* any_value_field; |
| 378 if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field, |
| 379 &any_value_field) && |
| 380 TryConsume("[")) { |
| 381 string full_type_name, prefix; |
| 382 DO(ConsumeAnyTypeUrl(&full_type_name, &prefix)); |
| 383 DO(Consume("]")); |
| 384 TryConsume(":"); // ':' is optional between message labels and values. |
| 385 string serialized_value; |
| 386 DO(ConsumeAnyValue(full_type_name, |
| 387 message->GetDescriptor()->file()->pool(), |
| 388 &serialized_value)); |
| 389 reflection->SetString( |
| 390 message, any_type_url_field, |
| 391 string(prefix + full_type_name)); |
| 392 reflection->SetString(message, any_value_field, serialized_value); |
| 393 return true; |
| 394 } |
319 if (TryConsume("[")) { | 395 if (TryConsume("[")) { |
320 // Extension. | 396 // Extension. |
321 DO(ConsumeIdentifier(&field_name)); | 397 DO(ConsumeFullTypeName(&field_name)); |
322 while (TryConsume(".")) { | |
323 string part; | |
324 DO(ConsumeIdentifier(&part)); | |
325 field_name += "."; | |
326 field_name += part; | |
327 } | |
328 DO(Consume("]")); | 398 DO(Consume("]")); |
329 | 399 |
330 field = (finder_ != NULL | 400 field = (finder_ != NULL |
331 ? finder_->FindExtension(message, field_name) | 401 ? finder_->FindExtension(message, field_name) |
332 : reflection->FindKnownExtensionByName(field_name)); | 402 : reflection->FindKnownExtensionByName(field_name)); |
333 | 403 |
334 if (field == NULL) { | 404 if (field == NULL) { |
335 if (!allow_unknown_field_) { | 405 if (!allow_unknown_field_) { |
336 ReportError("Extension \"" + field_name + "\" is not defined or " | 406 ReportError("Extension \"" + field_name + "\" is not defined or " |
337 "is not an extension of \"" + | 407 "is not an extension of \"" + |
338 descriptor->full_name() + "\"."); | 408 descriptor->full_name() + "\"."); |
339 return false; | 409 return false; |
340 } else { | 410 } else { |
341 ReportWarning("Extension \"" + field_name + "\" is not defined or " | 411 ReportWarning("Extension \"" + field_name + "\" is not defined or " |
342 "is not an extension of \"" + | 412 "is not an extension of \"" + |
343 descriptor->full_name() + "\"."); | 413 descriptor->full_name() + "\"."); |
344 } | 414 } |
345 } | 415 } |
346 } else { | 416 } else { |
347 DO(ConsumeIdentifier(&field_name)); | 417 DO(ConsumeIdentifier(&field_name)); |
348 | 418 |
349 field = descriptor->FindFieldByName(field_name); | 419 int32 field_number; |
350 // Group names are expected to be capitalized as they appear in the | 420 if (allow_field_number_ && safe_strto32(field_name, &field_number)) { |
351 // .proto file, which actually matches their type names, not their field | 421 if (descriptor->IsExtensionNumber(field_number)) { |
352 // names. | 422 field = reflection->FindKnownExtensionByNumber(field_number); |
353 if (field == NULL) { | 423 } else { |
354 string lower_field_name = field_name; | 424 field = descriptor->FindFieldByNumber(field_number); |
355 LowerString(&lower_field_name); | 425 } |
356 field = descriptor->FindFieldByName(lower_field_name); | 426 } else { |
357 // If the case-insensitive match worked but the field is NOT a group, | 427 field = descriptor->FindFieldByName(field_name); |
358 if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { | 428 // Group names are expected to be capitalized as they appear in the |
| 429 // .proto file, which actually matches their type names, not their |
| 430 // field names. |
| 431 if (field == NULL) { |
| 432 string lower_field_name = field_name; |
| 433 LowerString(&lower_field_name); |
| 434 field = descriptor->FindFieldByName(lower_field_name); |
| 435 // If the case-insensitive match worked but the field is NOT a group, |
| 436 if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { |
| 437 field = NULL; |
| 438 } |
| 439 } |
| 440 // Again, special-case group names as described above. |
| 441 if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP |
| 442 && field->message_type()->name() != field_name) { |
359 field = NULL; | 443 field = NULL; |
360 } | 444 } |
361 } | 445 |
362 // Again, special-case group names as described above. | 446 if (field == NULL && allow_case_insensitive_field_) { |
363 if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP | 447 string lower_field_name = field_name; |
364 && field->message_type()->name() != field_name) { | 448 LowerString(&lower_field_name); |
365 field = NULL; | 449 field = descriptor->FindFieldByLowercaseName(lower_field_name); |
| 450 } |
366 } | 451 } |
367 | 452 |
368 if (field == NULL) { | 453 if (field == NULL) { |
369 if (!allow_unknown_field_) { | 454 if (!allow_unknown_field_) { |
370 ReportError("Message type \"" + descriptor->full_name() + | 455 ReportError("Message type \"" + descriptor->full_name() + |
371 "\" has no field named \"" + field_name + "\"."); | 456 "\" has no field named \"" + field_name + "\"."); |
372 return false; | 457 return false; |
373 } else { | 458 } else { |
374 ReportWarning("Message type \"" + descriptor->full_name() + | 459 ReportWarning("Message type \"" + descriptor->full_name() + |
375 "\" has no field named \"" + field_name + "\"."); | 460 "\" has no field named \"" + field_name + "\"."); |
376 } | 461 } |
377 } | 462 } |
378 } | 463 } |
379 | 464 |
380 // Skips unknown field. | 465 // Skips unknown field. |
381 if (field == NULL) { | 466 if (field == NULL) { |
382 GOOGLE_CHECK(allow_unknown_field_); | 467 GOOGLE_CHECK(allow_unknown_field_); |
383 // Try to guess the type of this field. | 468 // Try to guess the type of this field. |
384 // If this field is not a message, there should be a ":" between the | 469 // If this field is not a message, there should be a ":" between the |
385 // field name and the field value and also the field value should not | 470 // field name and the field value and also the field value should not |
386 // start with "{" or "<" which indicates the begining of a message body. | 471 // start with "{" or "<" which indicates the beginning of a message body. |
387 // If there is no ":" or there is a "{" or "<" after ":", this field has | 472 // If there is no ":" or there is a "{" or "<" after ":", this field has |
388 // to be a message or the input is ill-formed. | 473 // to be a message or the input is ill-formed. |
389 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { | 474 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { |
390 return SkipFieldValue(); | 475 return SkipFieldValue(); |
391 } else { | 476 } else { |
392 return SkipFieldMessage(); | 477 return SkipFieldMessage(); |
393 } | 478 } |
394 } | 479 } |
395 | 480 |
396 // Fail if the field is not repeated and it has already been specified. | 481 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { |
397 if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) && | 482 // Fail if the field is not repeated and it has already been specified. |
398 !field->is_repeated() && reflection->HasField(*message, field)) { | 483 if (!field->is_repeated() && reflection->HasField(*message, field)) { |
399 ReportError("Non-repeated field \"" + field_name + | 484 ReportError("Non-repeated field \"" + field_name + |
400 "\" is specified multiple times."); | 485 "\" is specified multiple times."); |
401 return false; | 486 return false; |
| 487 } |
| 488 // Fail if the field is a member of a oneof and another member has already |
| 489 // been specified. |
| 490 const OneofDescriptor* oneof = field->containing_oneof(); |
| 491 if (oneof != NULL && reflection->HasOneof(*message, oneof)) { |
| 492 const FieldDescriptor* other_field = |
| 493 reflection->GetOneofFieldDescriptor(*message, oneof); |
| 494 ReportError("Field \"" + field_name + "\" is specified along with " |
| 495 "field \"" + other_field->name() + "\", another member " |
| 496 "of oneof \"" + oneof->name() + "\"."); |
| 497 return false; |
| 498 } |
402 } | 499 } |
403 | 500 |
404 // Perform special handling for embedded message types. | 501 // Perform special handling for embedded message types. |
405 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 502 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
406 // ':' is optional here. | 503 // ':' is optional here. |
407 TryConsume(":"); | 504 TryConsume(":"); |
| 505 } else { |
| 506 // ':' is required here. |
| 507 DO(Consume(":")); |
| 508 } |
| 509 |
| 510 if (field->is_repeated() && TryConsume("[")) { |
| 511 // Short repeated format, e.g. "foo: [1, 2, 3]" |
| 512 while (true) { |
| 513 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 514 // Perform special handling for embedded message types. |
| 515 DO(ConsumeFieldMessage(message, reflection, field)); |
| 516 } else { |
| 517 DO(ConsumeFieldValue(message, reflection, field)); |
| 518 } |
| 519 if (TryConsume("]")) { |
| 520 break; |
| 521 } |
| 522 DO(Consume(",")); |
| 523 } |
| 524 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
408 DO(ConsumeFieldMessage(message, reflection, field)); | 525 DO(ConsumeFieldMessage(message, reflection, field)); |
409 } else { | 526 } else { |
410 DO(Consume(":")); | 527 DO(ConsumeFieldValue(message, reflection, field)); |
411 if (field->is_repeated() && TryConsume("[")) { | |
412 // Short repeated format, e.g. "foo: [1, 2, 3]" | |
413 while (true) { | |
414 DO(ConsumeFieldValue(message, reflection, field)); | |
415 if (TryConsume("]")) { | |
416 break; | |
417 } | |
418 DO(Consume(",")); | |
419 } | |
420 } else { | |
421 DO(ConsumeFieldValue(message, reflection, field)); | |
422 } | |
423 } | 528 } |
424 | 529 |
425 // For historical reasons, fields may optionally be separated by commas or | 530 // For historical reasons, fields may optionally be separated by commas or |
426 // semicolons. | 531 // semicolons. |
427 TryConsume(";") || TryConsume(","); | 532 TryConsume(";") || TryConsume(","); |
428 | 533 |
429 if (field->options().deprecated()) { | 534 if (field->options().deprecated()) { |
430 ReportWarning("text format contains deprecated field \"" | 535 ReportWarning("text format contains deprecated field \"" |
431 + field_name + "\""); | 536 + field_name + "\""); |
432 } | 537 } |
433 | 538 |
434 // If a parse info tree exists, add the location for the parsed | 539 // If a parse info tree exists, add the location for the parsed |
435 // field. | 540 // field. |
436 if (parse_info_tree_ != NULL) { | 541 if (parse_info_tree_ != NULL) { |
437 RecordLocation(parse_info_tree_, field, | 542 RecordLocation(parse_info_tree_, field, |
438 ParseLocation(start_line, start_column)); | 543 ParseLocation(start_line, start_column)); |
439 } | 544 } |
440 | 545 |
441 return true; | 546 return true; |
442 } | 547 } |
443 | 548 |
444 // Skips the next field including the field's name and value. | 549 // Skips the next field including the field's name and value. |
445 bool SkipField() { | 550 bool SkipField() { |
446 string field_name; | 551 string field_name; |
447 if (TryConsume("[")) { | 552 if (TryConsume("[")) { |
448 // Extension name. | 553 // Extension name. |
449 DO(ConsumeIdentifier(&field_name)); | 554 DO(ConsumeFullTypeName(&field_name)); |
450 while (TryConsume(".")) { | |
451 string part; | |
452 DO(ConsumeIdentifier(&part)); | |
453 field_name += "."; | |
454 field_name += part; | |
455 } | |
456 DO(Consume("]")); | 555 DO(Consume("]")); |
457 } else { | 556 } else { |
458 DO(ConsumeIdentifier(&field_name)); | 557 DO(ConsumeIdentifier(&field_name)); |
459 } | 558 } |
460 | 559 |
461 // Try to guess the type of this field. | 560 // Try to guess the type of this field. |
462 // If this field is not a message, there should be a ":" between the | 561 // If this field is not a message, there should be a ":" between the |
463 // field name and the field value and also the field value should not | 562 // field name and the field value and also the field value should not |
464 // start with "{" or "<" which indicates the begining of a message body. | 563 // start with "{" or "<" which indicates the beginning of a message body. |
465 // If there is no ":" or there is a "{" or "<" after ":", this field has | 564 // If there is no ":" or there is a "{" or "<" after ":", this field has |
466 // to be a message or the input is ill-formed. | 565 // to be a message or the input is ill-formed. |
467 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { | 566 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { |
468 DO(SkipFieldValue()); | 567 DO(SkipFieldValue()); |
469 } else { | 568 } else { |
470 DO(SkipFieldMessage()); | 569 DO(SkipFieldMessage()); |
471 } | 570 } |
472 // For historical reasons, fields may optionally be separated by commas or | 571 // For historical reasons, fields may optionally be separated by commas or |
473 // semicolons. | 572 // semicolons. |
474 TryConsume(";") || TryConsume(","); | 573 TryConsume(";") || TryConsume(","); |
475 return true; | 574 return true; |
476 } | 575 } |
477 | 576 |
478 bool ConsumeFieldMessage(Message* message, | 577 bool ConsumeFieldMessage(Message* message, |
479 const Reflection* reflection, | 578 const Reflection* reflection, |
480 const FieldDescriptor* field) { | 579 const FieldDescriptor* field) { |
481 | 580 |
482 // If the parse information tree is not NULL, create a nested one | 581 // If the parse information tree is not NULL, create a nested one |
483 // for the nested message. | 582 // for the nested message. |
484 ParseInfoTree* parent = parse_info_tree_; | 583 ParseInfoTree* parent = parse_info_tree_; |
485 if (parent != NULL) { | 584 if (parent != NULL) { |
486 parse_info_tree_ = CreateNested(parent, field); | 585 parse_info_tree_ = CreateNested(parent, field); |
487 } | 586 } |
488 | 587 |
489 string delimeter; | 588 string delimiter; |
490 if (TryConsume("<")) { | 589 DO(ConsumeMessageDelimiter(&delimiter)); |
491 delimeter = ">"; | |
492 } else { | |
493 DO(Consume("{")); | |
494 delimeter = "}"; | |
495 } | |
496 | |
497 if (field->is_repeated()) { | 590 if (field->is_repeated()) { |
498 DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); | 591 DO(ConsumeMessage(reflection->AddMessage(message, field), delimiter)); |
499 } else { | 592 } else { |
500 DO(ConsumeMessage(reflection->MutableMessage(message, field), | 593 DO(ConsumeMessage(reflection->MutableMessage(message, field), |
501 delimeter)); | 594 delimiter)); |
502 } | 595 } |
503 | 596 |
504 // Reset the parse information tree. | 597 // Reset the parse information tree. |
505 parse_info_tree_ = parent; | 598 parse_info_tree_ = parent; |
506 return true; | 599 return true; |
507 } | 600 } |
508 | 601 |
509 // Skips the whole body of a message including the begining delimeter and | 602 // Skips the whole body of a message including the beginning delimiter and |
510 // the ending delimeter. | 603 // the ending delimiter. |
511 bool SkipFieldMessage() { | 604 bool SkipFieldMessage() { |
512 string delimeter; | 605 string delimiter; |
513 if (TryConsume("<")) { | 606 DO(ConsumeMessageDelimiter(&delimiter)); |
514 delimeter = ">"; | |
515 } else { | |
516 DO(Consume("{")); | |
517 delimeter = "}"; | |
518 } | |
519 while (!LookingAt(">") && !LookingAt("}")) { | 607 while (!LookingAt(">") && !LookingAt("}")) { |
520 DO(SkipField()); | 608 DO(SkipField()); |
521 } | 609 } |
522 DO(Consume(delimeter)); | 610 DO(Consume(delimiter)); |
523 return true; | 611 return true; |
524 } | 612 } |
525 | 613 |
526 bool ConsumeFieldValue(Message* message, | 614 bool ConsumeFieldValue(Message* message, |
527 const Reflection* reflection, | 615 const Reflection* reflection, |
528 const FieldDescriptor* field) { | 616 const FieldDescriptor* field) { |
529 | 617 |
530 // Define an easy to use macro for setting fields. This macro checks | 618 // Define an easy to use macro for setting fields. This macro checks |
531 // to see if the field is repeated (in which case we need to use the Add | 619 // to see if the field is repeated (in which case we need to use the Add |
532 // methods or not (in which case we need to use the Set methods). | 620 // methods or not (in which case we need to use the Set methods). |
(...skipping 29 matching lines...) Expand all Loading... |
562 case FieldDescriptor::CPPTYPE_UINT64: { | 650 case FieldDescriptor::CPPTYPE_UINT64: { |
563 uint64 value; | 651 uint64 value; |
564 DO(ConsumeUnsignedInteger(&value, kuint64max)); | 652 DO(ConsumeUnsignedInteger(&value, kuint64max)); |
565 SET_FIELD(UInt64, value); | 653 SET_FIELD(UInt64, value); |
566 break; | 654 break; |
567 } | 655 } |
568 | 656 |
569 case FieldDescriptor::CPPTYPE_FLOAT: { | 657 case FieldDescriptor::CPPTYPE_FLOAT: { |
570 double value; | 658 double value; |
571 DO(ConsumeDouble(&value)); | 659 DO(ConsumeDouble(&value)); |
572 SET_FIELD(Float, static_cast<float>(value)); | 660 SET_FIELD(Float, io::SafeDoubleToFloat(value)); |
573 break; | 661 break; |
574 } | 662 } |
575 | 663 |
576 case FieldDescriptor::CPPTYPE_DOUBLE: { | 664 case FieldDescriptor::CPPTYPE_DOUBLE: { |
577 double value; | 665 double value; |
578 DO(ConsumeDouble(&value)); | 666 DO(ConsumeDouble(&value)); |
579 SET_FIELD(Double, value); | 667 SET_FIELD(Double, value); |
580 break; | 668 break; |
581 } | 669 } |
582 | 670 |
583 case FieldDescriptor::CPPTYPE_STRING: { | 671 case FieldDescriptor::CPPTYPE_STRING: { |
584 string value; | 672 string value; |
585 DO(ConsumeString(&value)); | 673 DO(ConsumeString(&value)); |
586 SET_FIELD(String, value); | 674 SET_FIELD(String, value); |
587 break; | 675 break; |
588 } | 676 } |
589 | 677 |
590 case FieldDescriptor::CPPTYPE_BOOL: { | 678 case FieldDescriptor::CPPTYPE_BOOL: { |
591 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { | 679 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
592 uint64 value; | 680 uint64 value; |
593 DO(ConsumeUnsignedInteger(&value, 1)); | 681 DO(ConsumeUnsignedInteger(&value, 1)); |
594 SET_FIELD(Bool, value); | 682 SET_FIELD(Bool, value); |
595 } else { | 683 } else { |
596 string value; | 684 string value; |
597 DO(ConsumeIdentifier(&value)); | 685 DO(ConsumeIdentifier(&value)); |
598 if (value == "true" || value == "t") { | 686 if (value == "true" || value == "True" || value == "t") { |
599 SET_FIELD(Bool, true); | 687 SET_FIELD(Bool, true); |
600 } else if (value == "false" || value == "f") { | 688 } else if (value == "false" || value == "False" || value == "f") { |
601 SET_FIELD(Bool, false); | 689 SET_FIELD(Bool, false); |
602 } else { | 690 } else { |
603 ReportError("Invalid value for boolean field \"" + field->name() | 691 ReportError("Invalid value for boolean field \"" + field->name() |
604 + "\". Value: \"" + value + "\"."); | 692 + "\". Value: \"" + value + "\"."); |
605 return false; | 693 return false; |
606 } | 694 } |
607 } | 695 } |
608 break; | 696 break; |
609 } | 697 } |
610 | 698 |
(...skipping 12 matching lines...) Expand all Loading... |
623 int64 int_value; | 711 int64 int_value; |
624 DO(ConsumeSignedInteger(&int_value, kint32max)); | 712 DO(ConsumeSignedInteger(&int_value, kint32max)); |
625 value = SimpleItoa(int_value); // for error reporting | 713 value = SimpleItoa(int_value); // for error reporting |
626 enum_value = enum_type->FindValueByNumber(int_value); | 714 enum_value = enum_type->FindValueByNumber(int_value); |
627 } else { | 715 } else { |
628 ReportError("Expected integer or identifier."); | 716 ReportError("Expected integer or identifier."); |
629 return false; | 717 return false; |
630 } | 718 } |
631 | 719 |
632 if (enum_value == NULL) { | 720 if (enum_value == NULL) { |
633 ReportError("Unknown enumeration value of \"" + value + "\" for " | 721 if (!allow_unknown_enum_) { |
634 "field \"" + field->name() + "\"."); | 722 ReportError("Unknown enumeration value of \"" + value + "\" for " |
635 return false; | 723 "field \"" + field->name() + "\"."); |
| 724 return false; |
| 725 } else { |
| 726 ReportWarning("Unknown enumeration value of \"" + value + "\" for " |
| 727 "field \"" + field->name() + "\"."); |
| 728 return true; |
| 729 } |
636 } | 730 } |
637 | 731 |
638 SET_FIELD(Enum, enum_value); | 732 SET_FIELD(Enum, enum_value); |
639 break; | 733 break; |
640 } | 734 } |
641 | 735 |
642 case FieldDescriptor::CPPTYPE_MESSAGE: { | 736 case FieldDescriptor::CPPTYPE_MESSAGE: { |
643 // We should never get here. Put here instead of a default | 737 // We should never get here. Put here instead of a default |
644 // so that if new types are added, we get a nice compiler warning. | 738 // so that if new types are added, we get a nice compiler warning. |
645 GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; | 739 GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 } | 804 } |
711 | 805 |
712 // Returns true if the current token's type is equal to that specified. | 806 // Returns true if the current token's type is equal to that specified. |
713 bool LookingAtType(io::Tokenizer::TokenType token_type) { | 807 bool LookingAtType(io::Tokenizer::TokenType token_type) { |
714 return tokenizer_.current().type == token_type; | 808 return tokenizer_.current().type == token_type; |
715 } | 809 } |
716 | 810 |
717 // Consumes an identifier and saves its value in the identifier parameter. | 811 // Consumes an identifier and saves its value in the identifier parameter. |
718 // Returns false if the token is not of type IDENTFIER. | 812 // Returns false if the token is not of type IDENTFIER. |
719 bool ConsumeIdentifier(string* identifier) { | 813 bool ConsumeIdentifier(string* identifier) { |
720 if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { | 814 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
721 ReportError("Expected identifier."); | 815 *identifier = tokenizer_.current().text; |
722 return false; | 816 tokenizer_.Next(); |
| 817 return true; |
723 } | 818 } |
724 | 819 |
725 *identifier = tokenizer_.current().text; | 820 // If allow_field_numer_ or allow_unknown_field_ is true, we should able |
| 821 // to parse integer identifiers. |
| 822 if ((allow_field_number_ || allow_unknown_field_) |
| 823 && LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 824 *identifier = tokenizer_.current().text; |
| 825 tokenizer_.Next(); |
| 826 return true; |
| 827 } |
726 | 828 |
727 tokenizer_.Next(); | 829 ReportError("Expected identifier."); |
| 830 return false; |
| 831 } |
| 832 |
| 833 // Consume a string of form "<id1>.<id2>....<idN>". |
| 834 bool ConsumeFullTypeName(string* name) { |
| 835 DO(ConsumeIdentifier(name)); |
| 836 while (TryConsume(".")) { |
| 837 string part; |
| 838 DO(ConsumeIdentifier(&part)); |
| 839 *name += "."; |
| 840 *name += part; |
| 841 } |
728 return true; | 842 return true; |
729 } | 843 } |
730 | 844 |
731 // Consumes a string and saves its value in the text parameter. | 845 // Consumes a string and saves its value in the text parameter. |
732 // Returns false if the token is not of type STRING. | 846 // Returns false if the token is not of type STRING. |
733 bool ConsumeString(string* text) { | 847 bool ConsumeString(string* text) { |
734 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { | 848 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { |
735 ReportError("Expected string."); | 849 ReportError("Expected string."); |
736 return false; | 850 return false; |
737 } | 851 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 | 899 |
786 *value = static_cast<int64>(unsigned_value); | 900 *value = static_cast<int64>(unsigned_value); |
787 | 901 |
788 if (negative) { | 902 if (negative) { |
789 *value = -*value; | 903 *value = -*value; |
790 } | 904 } |
791 | 905 |
792 return true; | 906 return true; |
793 } | 907 } |
794 | 908 |
| 909 // Consumes a uint64 and saves its value in the value parameter. |
| 910 // Accepts decimal numbers only, rejects hex or oct numbers. |
| 911 bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) { |
| 912 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
| 913 ReportError("Expected integer."); |
| 914 return false; |
| 915 } |
| 916 |
| 917 const string& text = tokenizer_.current().text; |
| 918 if (IsHexNumber(text) || IsOctNumber(text)) { |
| 919 ReportError("Expect a decimal number."); |
| 920 return false; |
| 921 } |
| 922 |
| 923 if (!io::Tokenizer::ParseInteger(text, max_value, value)) { |
| 924 ReportError("Integer out of range."); |
| 925 return false; |
| 926 } |
| 927 |
| 928 tokenizer_.Next(); |
| 929 return true; |
| 930 } |
| 931 |
795 // Consumes a double and saves its value in the value parameter. | 932 // Consumes a double and saves its value in the value parameter. |
796 // Note that since the tokenizer does not support negative numbers, | 933 // Note that since the tokenizer does not support negative numbers, |
797 // we actually may consume an additional token (for the minus sign) in this | 934 // we actually may consume an additional token (for the minus sign) in this |
798 // method. Returns false if the token is not a double | 935 // method. Returns false if the token is not a double |
799 // (signed or otherwise). | 936 // (signed or otherwise). |
800 bool ConsumeDouble(double* value) { | 937 bool ConsumeDouble(double* value) { |
801 bool negative = false; | 938 bool negative = false; |
802 | 939 |
803 if (TryConsume("-")) { | 940 if (TryConsume("-")) { |
804 negative = true; | 941 negative = true; |
805 } | 942 } |
806 | 943 |
807 // A double can actually be an integer, according to the tokenizer. | 944 // A double can actually be an integer, according to the tokenizer. |
808 // Therefore, we must check both cases here. | 945 // Therefore, we must check both cases here. |
809 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { | 946 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { |
810 // We have found an integer value for the double. | 947 // We have found an integer value for the double. |
811 uint64 integer_value; | 948 uint64 integer_value; |
812 DO(ConsumeUnsignedInteger(&integer_value, kuint64max)); | 949 DO(ConsumeUnsignedDecimalInteger(&integer_value, kuint64max)); |
813 | 950 |
814 *value = static_cast<double>(integer_value); | 951 *value = static_cast<double>(integer_value); |
815 } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { | 952 } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { |
816 // We have found a float value for the double. | 953 // We have found a float value for the double. |
817 *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); | 954 *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); |
818 | 955 |
819 // Mark the current token as consumed. | 956 // Mark the current token as consumed. |
820 tokenizer_.Next(); | 957 tokenizer_.Next(); |
821 } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { | 958 } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { |
822 string text = tokenizer_.current().text; | 959 string text = tokenizer_.current().text; |
(...skipping 14 matching lines...) Expand all Loading... |
837 return false; | 974 return false; |
838 } | 975 } |
839 | 976 |
840 if (negative) { | 977 if (negative) { |
841 *value = -*value; | 978 *value = -*value; |
842 } | 979 } |
843 | 980 |
844 return true; | 981 return true; |
845 } | 982 } |
846 | 983 |
| 984 // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name" |
| 985 // or "type.googleprod.com/full.type.Name" |
| 986 bool ConsumeAnyTypeUrl(string* full_type_name, string* prefix) { |
| 987 // TODO(saito) Extend Consume() to consume multiple tokens at once, so that |
| 988 // this code can be written as just DO(Consume(kGoogleApisTypePrefix)). |
| 989 string url1, url2, url3; |
| 990 DO(ConsumeIdentifier(&url1)); // type |
| 991 DO(Consume(".")); |
| 992 DO(ConsumeIdentifier(&url2)); // googleapis |
| 993 DO(Consume(".")); |
| 994 DO(ConsumeIdentifier(&url3)); // com |
| 995 DO(Consume("/")); |
| 996 DO(ConsumeFullTypeName(full_type_name)); |
| 997 |
| 998 *prefix = url1 + "." + url2 + "." + url3 + "/"; |
| 999 if (*prefix != internal::kTypeGoogleApisComPrefix && |
| 1000 *prefix != internal::kTypeGoogleProdComPrefix) { |
| 1001 ReportError("TextFormat::Parser for Any supports only " |
| 1002 "type.googleapis.com and type.googleprod.com, " |
| 1003 "but found \"" + *prefix + "\""); |
| 1004 return false; |
| 1005 } |
| 1006 return true; |
| 1007 } |
| 1008 |
| 1009 // A helper function for reconstructing Any::value. Consumes a text of |
| 1010 // full_type_name, then serializes it into serialized_value. "pool" is used to |
| 1011 // look up and create a temporary object with full_type_name. |
| 1012 bool ConsumeAnyValue(const string& full_type_name, const DescriptorPool* pool, |
| 1013 string* serialized_value) { |
| 1014 const Descriptor* value_descriptor = |
| 1015 pool->FindMessageTypeByName(full_type_name); |
| 1016 if (value_descriptor == NULL) { |
| 1017 ReportError("Could not find type \"" + full_type_name + |
| 1018 "\" stored in google.protobuf.Any."); |
| 1019 return false; |
| 1020 } |
| 1021 DynamicMessageFactory factory; |
| 1022 const Message* value_prototype = factory.GetPrototype(value_descriptor); |
| 1023 if (value_prototype == NULL) { |
| 1024 return false; |
| 1025 } |
| 1026 google::protobuf::scoped_ptr<Message> value(value_prototype->New()); |
| 1027 string sub_delimiter; |
| 1028 DO(ConsumeMessageDelimiter(&sub_delimiter)); |
| 1029 DO(ConsumeMessage(value.get(), sub_delimiter)); |
| 1030 |
| 1031 value->AppendToString(serialized_value); |
| 1032 return true; |
| 1033 } |
| 1034 |
847 // Consumes a token and confirms that it matches that specified in the | 1035 // Consumes a token and confirms that it matches that specified in the |
848 // value parameter. Returns false if the token found does not match that | 1036 // value parameter. Returns false if the token found does not match that |
849 // which was specified. | 1037 // which was specified. |
850 bool Consume(const string& value) { | 1038 bool Consume(const string& value) { |
851 const string& current_value = tokenizer_.current().text; | 1039 const string& current_value = tokenizer_.current().text; |
852 | 1040 |
853 if (current_value != value) { | 1041 if (current_value != value) { |
854 ReportError("Expected \"" + value + "\", found \"" + current_value | 1042 ReportError("Expected \"" + value + "\", found \"" + current_value |
855 + "\"."); | 1043 + "\"."); |
856 return false; | 1044 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
872 } | 1060 } |
873 } | 1061 } |
874 | 1062 |
875 // An internal instance of the Tokenizer's error collector, used to | 1063 // An internal instance of the Tokenizer's error collector, used to |
876 // collect any base-level parse errors and feed them to the ParserImpl. | 1064 // collect any base-level parse errors and feed them to the ParserImpl. |
877 class ParserErrorCollector : public io::ErrorCollector { | 1065 class ParserErrorCollector : public io::ErrorCollector { |
878 public: | 1066 public: |
879 explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : | 1067 explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : |
880 parser_(parser) { } | 1068 parser_(parser) { } |
881 | 1069 |
882 virtual ~ParserErrorCollector() { }; | 1070 virtual ~ParserErrorCollector() { } |
883 | 1071 |
884 virtual void AddError(int line, int column, const string& message) { | 1072 virtual void AddError(int line, int column, const string& message) { |
885 parser_->ReportError(line, column, message); | 1073 parser_->ReportError(line, column, message); |
886 } | 1074 } |
887 | 1075 |
888 virtual void AddWarning(int line, int column, const string& message) { | 1076 virtual void AddWarning(int line, int column, const string& message) { |
889 parser_->ReportWarning(line, column, message); | 1077 parser_->ReportWarning(line, column, message); |
890 } | 1078 } |
891 | 1079 |
892 private: | 1080 private: |
893 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); | 1081 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); |
894 TextFormat::Parser::ParserImpl* parser_; | 1082 TextFormat::Parser::ParserImpl* parser_; |
895 }; | 1083 }; |
896 | 1084 |
897 io::ErrorCollector* error_collector_; | 1085 io::ErrorCollector* error_collector_; |
898 TextFormat::Finder* finder_; | 1086 TextFormat::Finder* finder_; |
899 ParseInfoTree* parse_info_tree_; | 1087 ParseInfoTree* parse_info_tree_; |
900 ParserErrorCollector tokenizer_error_collector_; | 1088 ParserErrorCollector tokenizer_error_collector_; |
901 io::Tokenizer tokenizer_; | 1089 io::Tokenizer tokenizer_; |
902 const Descriptor* root_message_type_; | 1090 const Descriptor* root_message_type_; |
903 SingularOverwritePolicy singular_overwrite_policy_; | 1091 SingularOverwritePolicy singular_overwrite_policy_; |
904 bool allow_unknown_field_; | 1092 const bool allow_case_insensitive_field_; |
| 1093 const bool allow_unknown_field_; |
| 1094 const bool allow_unknown_enum_; |
| 1095 const bool allow_field_number_; |
905 bool had_errors_; | 1096 bool had_errors_; |
906 }; | 1097 }; |
907 | 1098 |
908 #undef DO | 1099 #undef DO |
909 | 1100 |
910 // =========================================================================== | 1101 // =========================================================================== |
911 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted | 1102 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted |
912 // from the Printer found in //google/protobuf/io/printer.h | 1103 // from the Printer found in //google/protobuf/io/printer.h |
913 class TextFormat::Printer::TextGenerator { | 1104 class TextFormat::Printer::TextGenerator { |
914 public: | 1105 public: |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 // =========================================================================== | 1223 // =========================================================================== |
1033 | 1224 |
1034 TextFormat::Finder::~Finder() { | 1225 TextFormat::Finder::~Finder() { |
1035 } | 1226 } |
1036 | 1227 |
1037 TextFormat::Parser::Parser() | 1228 TextFormat::Parser::Parser() |
1038 : error_collector_(NULL), | 1229 : error_collector_(NULL), |
1039 finder_(NULL), | 1230 finder_(NULL), |
1040 parse_info_tree_(NULL), | 1231 parse_info_tree_(NULL), |
1041 allow_partial_(false), | 1232 allow_partial_(false), |
1042 allow_unknown_field_(false) { | 1233 allow_case_insensitive_field_(false), |
| 1234 allow_unknown_field_(false), |
| 1235 allow_unknown_enum_(false), |
| 1236 allow_field_number_(false), |
| 1237 allow_relaxed_whitespace_(false), |
| 1238 allow_singular_overwrites_(false) { |
1043 } | 1239 } |
1044 | 1240 |
1045 TextFormat::Parser::~Parser() {} | 1241 TextFormat::Parser::~Parser() {} |
1046 | 1242 |
1047 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, | 1243 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, |
1048 Message* output) { | 1244 Message* output) { |
1049 output->Clear(); | 1245 output->Clear(); |
| 1246 |
| 1247 ParserImpl::SingularOverwritePolicy overwrites_policy = |
| 1248 allow_singular_overwrites_ |
| 1249 ? ParserImpl::ALLOW_SINGULAR_OVERWRITES |
| 1250 : ParserImpl::FORBID_SINGULAR_OVERWRITES; |
| 1251 |
1050 ParserImpl parser(output->GetDescriptor(), input, error_collector_, | 1252 ParserImpl parser(output->GetDescriptor(), input, error_collector_, |
1051 finder_, parse_info_tree_, | 1253 finder_, parse_info_tree_, |
1052 ParserImpl::FORBID_SINGULAR_OVERWRITES, | 1254 overwrites_policy, |
1053 allow_unknown_field_); | 1255 allow_case_insensitive_field_, allow_unknown_field_, |
| 1256 allow_unknown_enum_, allow_field_number_, |
| 1257 allow_relaxed_whitespace_); |
1054 return MergeUsingImpl(input, output, &parser); | 1258 return MergeUsingImpl(input, output, &parser); |
1055 } | 1259 } |
1056 | 1260 |
1057 bool TextFormat::Parser::ParseFromString(const string& input, | 1261 bool TextFormat::Parser::ParseFromString(const string& input, |
1058 Message* output) { | 1262 Message* output) { |
1059 io::ArrayInputStream input_stream(input.data(), input.size()); | 1263 io::ArrayInputStream input_stream(input.data(), input.size()); |
1060 return Parse(&input_stream, output); | 1264 return Parse(&input_stream, output); |
1061 } | 1265 } |
1062 | 1266 |
1063 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, | 1267 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, |
1064 Message* output) { | 1268 Message* output) { |
1065 ParserImpl parser(output->GetDescriptor(), input, error_collector_, | 1269 ParserImpl parser(output->GetDescriptor(), input, error_collector_, |
1066 finder_, parse_info_tree_, | 1270 finder_, parse_info_tree_, |
1067 ParserImpl::ALLOW_SINGULAR_OVERWRITES, | 1271 ParserImpl::ALLOW_SINGULAR_OVERWRITES, |
1068 allow_unknown_field_); | 1272 allow_case_insensitive_field_, allow_unknown_field_, |
| 1273 allow_unknown_enum_, allow_field_number_, |
| 1274 allow_relaxed_whitespace_); |
1069 return MergeUsingImpl(input, output, &parser); | 1275 return MergeUsingImpl(input, output, &parser); |
1070 } | 1276 } |
1071 | 1277 |
1072 bool TextFormat::Parser::MergeFromString(const string& input, | 1278 bool TextFormat::Parser::MergeFromString(const string& input, |
1073 Message* output) { | 1279 Message* output) { |
1074 io::ArrayInputStream input_stream(input.data(), input.size()); | 1280 io::ArrayInputStream input_stream(input.data(), input.size()); |
1075 return Merge(&input_stream, output); | 1281 return Merge(&input_stream, output); |
1076 } | 1282 } |
1077 | 1283 |
1078 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input, | 1284 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */, |
1079 Message* output, | 1285 Message* output, |
1080 ParserImpl* parser_impl) { | 1286 ParserImpl* parser_impl) { |
1081 if (!parser_impl->Parse(output)) return false; | 1287 if (!parser_impl->Parse(output)) return false; |
1082 if (!allow_partial_ && !output->IsInitialized()) { | 1288 if (!allow_partial_ && !output->IsInitialized()) { |
1083 vector<string> missing_fields; | 1289 vector<string> missing_fields; |
1084 output->FindInitializationErrors(&missing_fields); | 1290 output->FindInitializationErrors(&missing_fields); |
1085 parser_impl->ReportError(-1, 0, "Message missing required fields: " + | 1291 parser_impl->ReportError(-1, 0, "Message missing required fields: " + |
1086 JoinStrings(missing_fields, ", ")); | 1292 Join(missing_fields, ", ")); |
1087 return false; | 1293 return false; |
1088 } | 1294 } |
1089 return true; | 1295 return true; |
1090 } | 1296 } |
1091 | 1297 |
1092 bool TextFormat::Parser::ParseFieldValueFromString( | 1298 bool TextFormat::Parser::ParseFieldValueFromString( |
1093 const string& input, | 1299 const string& input, |
1094 const FieldDescriptor* field, | 1300 const FieldDescriptor* field, |
1095 Message* output) { | 1301 Message* output) { |
1096 io::ArrayInputStream input_stream(input.data(), input.size()); | 1302 io::ArrayInputStream input_stream(input.data(), input.size()); |
1097 ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, | 1303 ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, |
1098 finder_, parse_info_tree_, | 1304 finder_, parse_info_tree_, |
1099 ParserImpl::ALLOW_SINGULAR_OVERWRITES, | 1305 ParserImpl::ALLOW_SINGULAR_OVERWRITES, |
1100 allow_unknown_field_); | 1306 allow_case_insensitive_field_, allow_unknown_field_, |
| 1307 allow_unknown_enum_, allow_field_number_, |
| 1308 allow_relaxed_whitespace_); |
1101 return parser.ParseField(field, output); | 1309 return parser.ParseField(field, output); |
1102 } | 1310 } |
1103 | 1311 |
1104 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, | 1312 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, |
1105 Message* output) { | 1313 Message* output) { |
1106 return Parser().Parse(input, output); | 1314 return Parser().Parse(input, output); |
1107 } | 1315 } |
1108 | 1316 |
1109 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, | 1317 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, |
1110 Message* output) { | 1318 Message* output) { |
1111 return Parser().Merge(input, output); | 1319 return Parser().Merge(input, output); |
1112 } | 1320 } |
1113 | 1321 |
1114 /* static */ bool TextFormat::ParseFromString(const string& input, | 1322 /* static */ bool TextFormat::ParseFromString(const string& input, |
1115 Message* output) { | 1323 Message* output) { |
1116 return Parser().ParseFromString(input, output); | 1324 return Parser().ParseFromString(input, output); |
1117 } | 1325 } |
1118 | 1326 |
1119 /* static */ bool TextFormat::MergeFromString(const string& input, | 1327 /* static */ bool TextFormat::MergeFromString(const string& input, |
1120 Message* output) { | 1328 Message* output) { |
1121 return Parser().MergeFromString(input, output); | 1329 return Parser().MergeFromString(input, output); |
1122 } | 1330 } |
1123 | 1331 |
1124 // =========================================================================== | 1332 // =========================================================================== |
1125 | 1333 |
| 1334 // The default implementation for FieldValuePrinter. The base class just |
| 1335 // does simple formatting. That way, deriving classes could decide to fallback |
| 1336 // to that behavior. |
| 1337 TextFormat::FieldValuePrinter::FieldValuePrinter() {} |
| 1338 TextFormat::FieldValuePrinter::~FieldValuePrinter() {} |
| 1339 string TextFormat::FieldValuePrinter::PrintBool(bool val) const { |
| 1340 return val ? "true" : "false"; |
| 1341 } |
| 1342 string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const { |
| 1343 return SimpleItoa(val); |
| 1344 } |
| 1345 string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const { |
| 1346 return SimpleItoa(val); |
| 1347 } |
| 1348 string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const { |
| 1349 return SimpleItoa(val); |
| 1350 } |
| 1351 string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const { |
| 1352 return SimpleItoa(val); |
| 1353 } |
| 1354 string TextFormat::FieldValuePrinter::PrintFloat(float val) const { |
| 1355 return SimpleFtoa(val); |
| 1356 } |
| 1357 string TextFormat::FieldValuePrinter::PrintDouble(double val) const { |
| 1358 return SimpleDtoa(val); |
| 1359 } |
| 1360 string TextFormat::FieldValuePrinter::PrintString(const string& val) const { |
| 1361 string printed("\""); |
| 1362 CEscapeAndAppend(val, &printed); |
| 1363 printed.push_back('\"'); |
| 1364 return printed; |
| 1365 } |
| 1366 string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const { |
| 1367 return PrintString(val); |
| 1368 } |
| 1369 string TextFormat::FieldValuePrinter::PrintEnum(int32 val, |
| 1370 const string& name) const { |
| 1371 return name; |
| 1372 } |
| 1373 string TextFormat::FieldValuePrinter::PrintFieldName( |
| 1374 const Message& message, |
| 1375 const Reflection* reflection, |
| 1376 const FieldDescriptor* field) const { |
| 1377 if (field->is_extension()) { |
| 1378 // We special-case MessageSet elements for compatibility with proto1. |
| 1379 if (field->containing_type()->options().message_set_wire_format() |
| 1380 && field->type() == FieldDescriptor::TYPE_MESSAGE |
| 1381 && field->is_optional() |
| 1382 && field->extension_scope() == field->message_type()) { |
| 1383 return StrCat("[", field->message_type()->full_name(), "]"); |
| 1384 } else { |
| 1385 return StrCat("[", field->full_name(), "]"); |
| 1386 } |
| 1387 } else if (field->type() == FieldDescriptor::TYPE_GROUP) { |
| 1388 // Groups must be serialized with their original capitalization. |
| 1389 return field->message_type()->name(); |
| 1390 } else { |
| 1391 return field->name(); |
| 1392 } |
| 1393 } |
| 1394 string TextFormat::FieldValuePrinter::PrintMessageStart( |
| 1395 const Message& message, |
| 1396 int field_index, |
| 1397 int field_count, |
| 1398 bool single_line_mode) const { |
| 1399 return single_line_mode ? " { " : " {\n"; |
| 1400 } |
| 1401 string TextFormat::FieldValuePrinter::PrintMessageEnd( |
| 1402 const Message& message, |
| 1403 int field_index, |
| 1404 int field_count, |
| 1405 bool single_line_mode) const { |
| 1406 return single_line_mode ? "} " : "}\n"; |
| 1407 } |
| 1408 |
| 1409 namespace { |
| 1410 // Our own specialization: for UTF8 escaped strings. |
| 1411 class FieldValuePrinterUtf8Escaping : public TextFormat::FieldValuePrinter { |
| 1412 public: |
| 1413 virtual string PrintString(const string& val) const { |
| 1414 return StrCat("\"", strings::Utf8SafeCEscape(val), "\""); |
| 1415 } |
| 1416 virtual string PrintBytes(const string& val) const { |
| 1417 return TextFormat::FieldValuePrinter::PrintString(val); |
| 1418 } |
| 1419 }; |
| 1420 |
| 1421 } // namespace |
| 1422 |
1126 TextFormat::Printer::Printer() | 1423 TextFormat::Printer::Printer() |
1127 : initial_indent_level_(0), | 1424 : initial_indent_level_(0), |
1128 single_line_mode_(false), | 1425 single_line_mode_(false), |
| 1426 use_field_number_(false), |
1129 use_short_repeated_primitives_(false), | 1427 use_short_repeated_primitives_(false), |
1130 utf8_string_escaping_(false) {} | 1428 hide_unknown_fields_(false), |
| 1429 print_message_fields_in_index_order_(false), |
| 1430 expand_any_(false), |
| 1431 truncate_string_field_longer_than_(0LL) { |
| 1432 SetUseUtf8StringEscaping(false); |
| 1433 } |
1131 | 1434 |
1132 TextFormat::Printer::~Printer() {} | 1435 TextFormat::Printer::~Printer() { |
| 1436 STLDeleteValues(&custom_printers_); |
| 1437 } |
| 1438 |
| 1439 void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) { |
| 1440 SetDefaultFieldValuePrinter(as_utf8 |
| 1441 ? new FieldValuePrinterUtf8Escaping() |
| 1442 : new FieldValuePrinter()); |
| 1443 } |
| 1444 |
| 1445 void TextFormat::Printer::SetDefaultFieldValuePrinter( |
| 1446 const FieldValuePrinter* printer) { |
| 1447 default_field_value_printer_.reset(printer); |
| 1448 } |
| 1449 |
| 1450 bool TextFormat::Printer::RegisterFieldValuePrinter( |
| 1451 const FieldDescriptor* field, |
| 1452 const FieldValuePrinter* printer) { |
| 1453 return field != NULL && printer != NULL && |
| 1454 custom_printers_.insert(std::make_pair(field, printer)).second; |
| 1455 } |
1133 | 1456 |
1134 bool TextFormat::Printer::PrintToString(const Message& message, | 1457 bool TextFormat::Printer::PrintToString(const Message& message, |
1135 string* output) const { | 1458 string* output) const { |
1136 GOOGLE_DCHECK(output) << "output specified is NULL"; | 1459 GOOGLE_DCHECK(output) << "output specified is NULL"; |
1137 | 1460 |
1138 output->clear(); | 1461 output->clear(); |
1139 io::StringOutputStream output_stream(output); | 1462 io::StringOutputStream output_stream(output); |
1140 | 1463 |
1141 bool result = Print(message, &output_stream); | 1464 return Print(message, &output_stream); |
1142 | |
1143 return result; | |
1144 } | 1465 } |
1145 | 1466 |
1146 bool TextFormat::Printer::PrintUnknownFieldsToString( | 1467 bool TextFormat::Printer::PrintUnknownFieldsToString( |
1147 const UnknownFieldSet& unknown_fields, | 1468 const UnknownFieldSet& unknown_fields, |
1148 string* output) const { | 1469 string* output) const { |
1149 GOOGLE_DCHECK(output) << "output specified is NULL"; | 1470 GOOGLE_DCHECK(output) << "output specified is NULL"; |
1150 | 1471 |
1151 output->clear(); | 1472 output->clear(); |
1152 io::StringOutputStream output_stream(output); | 1473 io::StringOutputStream output_stream(output); |
1153 return PrintUnknownFields(unknown_fields, &output_stream); | 1474 return PrintUnknownFields(unknown_fields, &output_stream); |
(...skipping 13 matching lines...) Expand all Loading... |
1167 const UnknownFieldSet& unknown_fields, | 1488 const UnknownFieldSet& unknown_fields, |
1168 io::ZeroCopyOutputStream* output) const { | 1489 io::ZeroCopyOutputStream* output) const { |
1169 TextGenerator generator(output, initial_indent_level_); | 1490 TextGenerator generator(output, initial_indent_level_); |
1170 | 1491 |
1171 PrintUnknownFields(unknown_fields, generator); | 1492 PrintUnknownFields(unknown_fields, generator); |
1172 | 1493 |
1173 // Output false if the generator failed internally. | 1494 // Output false if the generator failed internally. |
1174 return !generator.failed(); | 1495 return !generator.failed(); |
1175 } | 1496 } |
1176 | 1497 |
| 1498 namespace { |
| 1499 // Comparison functor for sorting FieldDescriptors by field index. |
| 1500 struct FieldIndexSorter { |
| 1501 bool operator()(const FieldDescriptor* left, |
| 1502 const FieldDescriptor* right) const { |
| 1503 return left->index() < right->index(); |
| 1504 } |
| 1505 }; |
| 1506 |
| 1507 } // namespace |
| 1508 |
| 1509 bool TextFormat::Printer::PrintAny(const Message& message, |
| 1510 TextGenerator& generator) const { |
| 1511 const FieldDescriptor* type_url_field; |
| 1512 const FieldDescriptor* value_field; |
| 1513 if (!internal::GetAnyFieldDescriptors(message, &type_url_field, |
| 1514 &value_field)) { |
| 1515 return false; |
| 1516 } |
| 1517 |
| 1518 const Reflection* reflection = message.GetReflection(); |
| 1519 |
| 1520 // Extract the full type name from the type_url field. |
| 1521 const string& type_url = reflection->GetString(message, type_url_field); |
| 1522 string full_type_name; |
| 1523 if (!internal::ParseAnyTypeUrl(type_url, &full_type_name)) { |
| 1524 return false; |
| 1525 } |
| 1526 |
| 1527 // Print the "value" in text. |
| 1528 const google::protobuf::Descriptor* value_descriptor = |
| 1529 message.GetDescriptor()->file()->pool()->FindMessageTypeByName( |
| 1530 full_type_name); |
| 1531 if (value_descriptor == NULL) { |
| 1532 GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found"; |
| 1533 return false; |
| 1534 } |
| 1535 DynamicMessageFactory factory; |
| 1536 google::protobuf::scoped_ptr<google::protobuf::Message> value_message( |
| 1537 factory.GetPrototype(value_descriptor)->New()); |
| 1538 string serialized_value = reflection->GetString(message, value_field); |
| 1539 if (!value_message->ParseFromString(serialized_value)) { |
| 1540 GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents"; |
| 1541 return false; |
| 1542 } |
| 1543 generator.Print(StrCat("[", type_url, "]")); |
| 1544 const FieldValuePrinter* printer = FindWithDefault( |
| 1545 custom_printers_, value_field, default_field_value_printer_.get()); |
| 1546 generator.Print( |
| 1547 printer->PrintMessageStart(message, -1, 0, single_line_mode_)); |
| 1548 generator.Indent(); |
| 1549 Print(*value_message, generator); |
| 1550 generator.Outdent(); |
| 1551 generator.Print(printer->PrintMessageEnd(message, -1, 0, single_line_mode_)); |
| 1552 return true; |
| 1553 } |
| 1554 |
1177 void TextFormat::Printer::Print(const Message& message, | 1555 void TextFormat::Printer::Print(const Message& message, |
1178 TextGenerator& generator) const { | 1556 TextGenerator& generator) const { |
| 1557 const Descriptor* descriptor = message.GetDescriptor(); |
1179 const Reflection* reflection = message.GetReflection(); | 1558 const Reflection* reflection = message.GetReflection(); |
| 1559 if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && |
| 1560 PrintAny(message, generator)) { |
| 1561 return; |
| 1562 } |
1180 vector<const FieldDescriptor*> fields; | 1563 vector<const FieldDescriptor*> fields; |
1181 reflection->ListFields(message, &fields); | 1564 reflection->ListFields(message, &fields); |
| 1565 if (print_message_fields_in_index_order_) { |
| 1566 std::sort(fields.begin(), fields.end(), FieldIndexSorter()); |
| 1567 } |
1182 for (int i = 0; i < fields.size(); i++) { | 1568 for (int i = 0; i < fields.size(); i++) { |
1183 PrintField(message, reflection, fields[i], generator); | 1569 PrintField(message, reflection, fields[i], generator); |
1184 } | 1570 } |
1185 PrintUnknownFields(reflection->GetUnknownFields(message), generator); | 1571 if (!hide_unknown_fields_) { |
| 1572 PrintUnknownFields(reflection->GetUnknownFields(message), generator); |
| 1573 } |
1186 } | 1574 } |
1187 | 1575 |
1188 void TextFormat::Printer::PrintFieldValueToString( | 1576 void TextFormat::Printer::PrintFieldValueToString( |
1189 const Message& message, | 1577 const Message& message, |
1190 const FieldDescriptor* field, | 1578 const FieldDescriptor* field, |
1191 int index, | 1579 int index, |
1192 string* output) const { | 1580 string* output) const { |
1193 | 1581 |
1194 GOOGLE_DCHECK(output) << "output specified is NULL"; | 1582 GOOGLE_DCHECK(output) << "output specified is NULL"; |
1195 | 1583 |
1196 output->clear(); | 1584 output->clear(); |
1197 io::StringOutputStream output_stream(output); | 1585 io::StringOutputStream output_stream(output); |
1198 TextGenerator generator(&output_stream, initial_indent_level_); | 1586 TextGenerator generator(&output_stream, initial_indent_level_); |
1199 | 1587 |
1200 PrintFieldValue(message, message.GetReflection(), field, index, generator); | 1588 PrintFieldValue(message, message.GetReflection(), field, index, generator); |
1201 } | 1589 } |
1202 | 1590 |
| 1591 class MapEntryMessageComparator { |
| 1592 public: |
| 1593 explicit MapEntryMessageComparator(const Descriptor* descriptor) |
| 1594 : field_(descriptor->field(0)) {} |
| 1595 |
| 1596 bool operator()(const Message* a, const Message* b) { |
| 1597 const Reflection* reflection = a->GetReflection(); |
| 1598 switch (field_->cpp_type()) { |
| 1599 case FieldDescriptor::CPPTYPE_BOOL: { |
| 1600 bool first = reflection->GetBool(*a, field_); |
| 1601 bool second = reflection->GetBool(*b, field_); |
| 1602 return first < second; |
| 1603 } |
| 1604 case FieldDescriptor::CPPTYPE_INT32: { |
| 1605 int32 first = reflection->GetInt32(*a, field_); |
| 1606 int32 second = reflection->GetInt32(*b, field_); |
| 1607 return first < second; |
| 1608 } |
| 1609 case FieldDescriptor::CPPTYPE_INT64: { |
| 1610 int64 first = reflection->GetInt64(*a, field_); |
| 1611 int64 second = reflection->GetInt64(*b, field_); |
| 1612 return first < second; |
| 1613 } |
| 1614 case FieldDescriptor::CPPTYPE_UINT32: { |
| 1615 uint32 first = reflection->GetUInt32(*a, field_); |
| 1616 uint32 second = reflection->GetUInt32(*b, field_); |
| 1617 return first < second; |
| 1618 } |
| 1619 case FieldDescriptor::CPPTYPE_UINT64: { |
| 1620 uint64 first = reflection->GetUInt64(*a, field_); |
| 1621 uint64 second = reflection->GetUInt64(*b, field_); |
| 1622 return first < second; |
| 1623 } |
| 1624 case FieldDescriptor::CPPTYPE_STRING: { |
| 1625 string first = reflection->GetString(*a, field_); |
| 1626 string second = reflection->GetString(*b, field_); |
| 1627 return first < second; |
| 1628 } |
| 1629 default: |
| 1630 GOOGLE_LOG(DFATAL) << "Invalid key for map field."; |
| 1631 return true; |
| 1632 } |
| 1633 } |
| 1634 |
| 1635 private: |
| 1636 const FieldDescriptor* field_; |
| 1637 }; |
| 1638 |
1203 void TextFormat::Printer::PrintField(const Message& message, | 1639 void TextFormat::Printer::PrintField(const Message& message, |
1204 const Reflection* reflection, | 1640 const Reflection* reflection, |
1205 const FieldDescriptor* field, | 1641 const FieldDescriptor* field, |
1206 TextGenerator& generator) const { | 1642 TextGenerator& generator) const { |
1207 if (use_short_repeated_primitives_ && | 1643 if (use_short_repeated_primitives_ && |
1208 field->is_repeated() && | 1644 field->is_repeated() && |
1209 field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && | 1645 field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && |
1210 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { | 1646 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { |
1211 PrintShortRepeatedField(message, reflection, field, generator); | 1647 PrintShortRepeatedField(message, reflection, field, generator); |
1212 return; | 1648 return; |
1213 } | 1649 } |
1214 | 1650 |
1215 int count = 0; | 1651 int count = 0; |
1216 | 1652 |
1217 if (field->is_repeated()) { | 1653 if (field->is_repeated()) { |
1218 count = reflection->FieldSize(message, field); | 1654 count = reflection->FieldSize(message, field); |
1219 } else if (reflection->HasField(message, field)) { | 1655 } else if (reflection->HasField(message, field)) { |
1220 count = 1; | 1656 count = 1; |
1221 } | 1657 } |
1222 | 1658 |
| 1659 std::vector<const Message*> sorted_map_field; |
| 1660 if (field->is_map()) { |
| 1661 const RepeatedPtrField<Message>& map_field = |
| 1662 reflection->GetRepeatedPtrField<Message>(message, field); |
| 1663 for (RepeatedPtrField<Message>::const_pointer_iterator it = |
| 1664 map_field.pointer_begin(); |
| 1665 it != map_field.pointer_end(); ++it) { |
| 1666 sorted_map_field.push_back(*it); |
| 1667 } |
| 1668 |
| 1669 MapEntryMessageComparator comparator(field->message_type()); |
| 1670 std::stable_sort(sorted_map_field.begin(), sorted_map_field.end(), |
| 1671 comparator); |
| 1672 } |
| 1673 |
1223 for (int j = 0; j < count; ++j) { | 1674 for (int j = 0; j < count; ++j) { |
| 1675 const int field_index = field->is_repeated() ? j : -1; |
| 1676 |
1224 PrintFieldName(message, reflection, field, generator); | 1677 PrintFieldName(message, reflection, field, generator); |
1225 | 1678 |
1226 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 1679 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
1227 if (single_line_mode_) { | 1680 const FieldValuePrinter* printer = FindWithDefault( |
1228 generator.Print(" { "); | 1681 custom_printers_, field, default_field_value_printer_.get()); |
1229 } else { | 1682 const Message& sub_message = |
1230 generator.Print(" {\n"); | 1683 field->is_repeated() |
1231 generator.Indent(); | 1684 ? (field->is_map() |
1232 } | 1685 ? *sorted_map_field[j] |
| 1686 : reflection->GetRepeatedMessage(message, field, j)) |
| 1687 : reflection->GetMessage(message, field); |
| 1688 generator.Print( |
| 1689 printer->PrintMessageStart( |
| 1690 sub_message, field_index, count, single_line_mode_)); |
| 1691 generator.Indent(); |
| 1692 Print(sub_message, generator); |
| 1693 generator.Outdent(); |
| 1694 generator.Print( |
| 1695 printer->PrintMessageEnd( |
| 1696 sub_message, field_index, count, single_line_mode_)); |
1233 } else { | 1697 } else { |
1234 generator.Print(": "); | 1698 generator.Print(": "); |
1235 } | 1699 // Write the field value. |
1236 | 1700 PrintFieldValue(message, reflection, field, field_index, generator); |
1237 // Write the field value. | |
1238 int field_index = j; | |
1239 if (!field->is_repeated()) { | |
1240 field_index = -1; | |
1241 } | |
1242 | |
1243 PrintFieldValue(message, reflection, field, field_index, generator); | |
1244 | |
1245 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | |
1246 if (single_line_mode_) { | |
1247 generator.Print("} "); | |
1248 } else { | |
1249 generator.Outdent(); | |
1250 generator.Print("}\n"); | |
1251 } | |
1252 } else { | |
1253 if (single_line_mode_) { | 1701 if (single_line_mode_) { |
1254 generator.Print(" "); | 1702 generator.Print(" "); |
1255 } else { | 1703 } else { |
1256 generator.Print("\n"); | 1704 generator.Print("\n"); |
1257 } | 1705 } |
1258 } | 1706 } |
1259 } | 1707 } |
1260 } | 1708 } |
1261 | 1709 |
1262 void TextFormat::Printer::PrintShortRepeatedField( | 1710 void TextFormat::Printer::PrintShortRepeatedField( |
(...skipping 14 matching lines...) Expand all Loading... |
1277 generator.Print("] "); | 1725 generator.Print("] "); |
1278 } else { | 1726 } else { |
1279 generator.Print("]\n"); | 1727 generator.Print("]\n"); |
1280 } | 1728 } |
1281 } | 1729 } |
1282 | 1730 |
1283 void TextFormat::Printer::PrintFieldName(const Message& message, | 1731 void TextFormat::Printer::PrintFieldName(const Message& message, |
1284 const Reflection* reflection, | 1732 const Reflection* reflection, |
1285 const FieldDescriptor* field, | 1733 const FieldDescriptor* field, |
1286 TextGenerator& generator) const { | 1734 TextGenerator& generator) const { |
1287 if (field->is_extension()) { | 1735 // if use_field_number_ is true, prints field number instead |
1288 generator.Print("["); | 1736 // of field name. |
1289 // We special-case MessageSet elements for compatibility with proto1. | 1737 if (use_field_number_) { |
1290 if (field->containing_type()->options().message_set_wire_format() | 1738 generator.Print(SimpleItoa(field->number())); |
1291 && field->type() == FieldDescriptor::TYPE_MESSAGE | 1739 return; |
1292 && field->is_optional() | |
1293 && field->extension_scope() == field->message_type()) { | |
1294 generator.Print(field->message_type()->full_name()); | |
1295 } else { | |
1296 generator.Print(field->full_name()); | |
1297 } | |
1298 generator.Print("]"); | |
1299 } else { | |
1300 if (field->type() == FieldDescriptor::TYPE_GROUP) { | |
1301 // Groups must be serialized with their original capitalization. | |
1302 generator.Print(field->message_type()->name()); | |
1303 } else { | |
1304 generator.Print(field->name()); | |
1305 } | |
1306 } | 1740 } |
| 1741 |
| 1742 const FieldValuePrinter* printer = FindWithDefault( |
| 1743 custom_printers_, field, default_field_value_printer_.get()); |
| 1744 generator.Print(printer->PrintFieldName(message, reflection, field)); |
1307 } | 1745 } |
1308 | 1746 |
1309 void TextFormat::Printer::PrintFieldValue( | 1747 void TextFormat::Printer::PrintFieldValue( |
1310 const Message& message, | 1748 const Message& message, |
1311 const Reflection* reflection, | 1749 const Reflection* reflection, |
1312 const FieldDescriptor* field, | 1750 const FieldDescriptor* field, |
1313 int index, | 1751 int index, |
1314 TextGenerator& generator) const { | 1752 TextGenerator& generator) const { |
1315 GOOGLE_DCHECK(field->is_repeated() || (index == -1)) | 1753 GOOGLE_DCHECK(field->is_repeated() || (index == -1)) |
1316 << "Index must be -1 for non-repeated fields"; | 1754 << "Index must be -1 for non-repeated fields"; |
1317 | 1755 |
| 1756 const FieldValuePrinter* printer |
| 1757 = FindWithDefault(custom_printers_, field, |
| 1758 default_field_value_printer_.get()); |
| 1759 |
1318 switch (field->cpp_type()) { | 1760 switch (field->cpp_type()) { |
1319 #define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \ | 1761 #define OUTPUT_FIELD(CPPTYPE, METHOD) \ |
1320 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ | 1762 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ |
1321 generator.Print(TO_STRING(field->is_repeated() ? \ | 1763 generator.Print(printer->Print##METHOD(field->is_repeated() \ |
1322 reflection->GetRepeated##METHOD(message, field, index) : \ | 1764 ? reflection->GetRepeated##METHOD(message, field, index) \ |
1323 reflection->Get##METHOD(message, field))); \ | 1765 : reflection->Get##METHOD(message, field))); \ |
1324 break; \ | 1766 break |
1325 | 1767 |
1326 OUTPUT_FIELD( INT32, Int32, SimpleItoa); | 1768 OUTPUT_FIELD( INT32, Int32); |
1327 OUTPUT_FIELD( INT64, Int64, SimpleItoa); | 1769 OUTPUT_FIELD( INT64, Int64); |
1328 OUTPUT_FIELD(UINT32, UInt32, SimpleItoa); | 1770 OUTPUT_FIELD(UINT32, UInt32); |
1329 OUTPUT_FIELD(UINT64, UInt64, SimpleItoa); | 1771 OUTPUT_FIELD(UINT64, UInt64); |
1330 OUTPUT_FIELD( FLOAT, Float, SimpleFtoa); | 1772 OUTPUT_FIELD( FLOAT, Float); |
1331 OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa); | 1773 OUTPUT_FIELD(DOUBLE, Double); |
| 1774 OUTPUT_FIELD( BOOL, Bool); |
1332 #undef OUTPUT_FIELD | 1775 #undef OUTPUT_FIELD |
1333 | 1776 |
1334 case FieldDescriptor::CPPTYPE_STRING: { | 1777 case FieldDescriptor::CPPTYPE_STRING: { |
1335 string scratch; | 1778 string scratch; |
1336 const string& value = field->is_repeated() ? | 1779 const string& value = field->is_repeated() |
1337 reflection->GetRepeatedStringReference( | 1780 ? reflection->GetRepeatedStringReference( |
1338 message, field, index, &scratch) : | 1781 message, field, index, &scratch) |
1339 reflection->GetStringReference(message, field, &scratch); | 1782 : reflection->GetStringReference(message, field, &scratch); |
| 1783 int64 size = value.size(); |
| 1784 if (truncate_string_field_longer_than_ > 0) { |
| 1785 size = std::min(truncate_string_field_longer_than_, |
| 1786 static_cast<int64>(value.size())); |
| 1787 } |
| 1788 string truncated_value(value.substr(0, size) + "...<truncated>..."); |
| 1789 const string* value_to_print = &value; |
| 1790 if (size < value.size()) { |
| 1791 value_to_print = &truncated_value; |
| 1792 } |
| 1793 if (field->type() == FieldDescriptor::TYPE_STRING) { |
| 1794 generator.Print(printer->PrintString(*value_to_print)); |
| 1795 } else { |
| 1796 GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES); |
| 1797 generator.Print(printer->PrintBytes(*value_to_print)); |
| 1798 } |
| 1799 break; |
| 1800 } |
1340 | 1801 |
1341 generator.Print("\""); | 1802 case FieldDescriptor::CPPTYPE_ENUM: { |
1342 if (utf8_string_escaping_) { | 1803 int enum_value = field->is_repeated() |
1343 generator.Print(strings::Utf8SafeCEscape(value)); | 1804 ? reflection->GetRepeatedEnumValue(message, field, index) |
1344 } else { | 1805 : reflection->GetEnumValue(message, field); |
1345 generator.Print(CEscape(value)); | 1806 const EnumValueDescriptor* enum_desc = |
1346 } | 1807 field->enum_type()->FindValueByNumber(enum_value); |
1347 generator.Print("\""); | 1808 if (enum_desc != NULL) { |
| 1809 generator.Print(printer->PrintEnum(enum_value, enum_desc->name())); |
| 1810 } else { |
| 1811 // Ordinarily, enum_desc should not be null, because proto2 has the |
| 1812 // invariant that set enum field values must be in-range, but with the |
| 1813 // new integer-based API for enums (or the RepeatedField<int> loophole), |
| 1814 // it is possible for the user to force an unknown integer value. So we |
| 1815 // simply use the integer value itself as the enum value name in this |
| 1816 // case. |
| 1817 generator.Print(printer->PrintEnum(enum_value, |
| 1818 StringPrintf("%d", enum_value))); |
| 1819 } |
| 1820 break; |
| 1821 } |
1348 | 1822 |
1349 break; | 1823 case FieldDescriptor::CPPTYPE_MESSAGE: |
1350 } | 1824 Print(field->is_repeated() |
1351 | 1825 ? reflection->GetRepeatedMessage(message, field, index) |
1352 case FieldDescriptor::CPPTYPE_BOOL: | 1826 : reflection->GetMessage(message, field), |
1353 if (field->is_repeated()) { | 1827 generator); |
1354 generator.Print(reflection->GetRepeatedBool(message, field, index) | 1828 break; |
1355 ? "true" : "false"); | |
1356 } else { | |
1357 generator.Print(reflection->GetBool(message, field) | |
1358 ? "true" : "false"); | |
1359 } | |
1360 break; | |
1361 | |
1362 case FieldDescriptor::CPPTYPE_ENUM: | |
1363 generator.Print(field->is_repeated() ? | |
1364 reflection->GetRepeatedEnum(message, field, index)->name() : | |
1365 reflection->GetEnum(message, field)->name()); | |
1366 break; | |
1367 | |
1368 case FieldDescriptor::CPPTYPE_MESSAGE: | |
1369 Print(field->is_repeated() ? | |
1370 reflection->GetRepeatedMessage(message, field, index) : | |
1371 reflection->GetMessage(message, field), | |
1372 generator); | |
1373 break; | |
1374 } | 1829 } |
1375 } | 1830 } |
1376 | 1831 |
1377 /* static */ bool TextFormat::Print(const Message& message, | 1832 /* static */ bool TextFormat::Print(const Message& message, |
1378 io::ZeroCopyOutputStream* output) { | 1833 io::ZeroCopyOutputStream* output) { |
1379 return Printer().Print(message, output); | 1834 return Printer().Print(message, output); |
1380 } | 1835 } |
1381 | 1836 |
1382 /* static */ bool TextFormat::PrintUnknownFields( | 1837 /* static */ bool TextFormat::PrintUnknownFields( |
1383 const UnknownFieldSet& unknown_fields, | 1838 const UnknownFieldSet& unknown_fields, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 generator.Print(SimpleItoa(field.varint())); | 1890 generator.Print(SimpleItoa(field.varint())); |
1436 if (single_line_mode_) { | 1891 if (single_line_mode_) { |
1437 generator.Print(" "); | 1892 generator.Print(" "); |
1438 } else { | 1893 } else { |
1439 generator.Print("\n"); | 1894 generator.Print("\n"); |
1440 } | 1895 } |
1441 break; | 1896 break; |
1442 case UnknownField::TYPE_FIXED32: { | 1897 case UnknownField::TYPE_FIXED32: { |
1443 generator.Print(field_number); | 1898 generator.Print(field_number); |
1444 generator.Print(": 0x"); | 1899 generator.Print(": 0x"); |
1445 char buffer[kFastToBufferSize]; | 1900 generator.Print( |
1446 generator.Print(FastHex32ToBuffer(field.fixed32(), buffer)); | 1901 StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8))); |
1447 if (single_line_mode_) { | 1902 if (single_line_mode_) { |
1448 generator.Print(" "); | 1903 generator.Print(" "); |
1449 } else { | 1904 } else { |
1450 generator.Print("\n"); | 1905 generator.Print("\n"); |
1451 } | 1906 } |
1452 break; | 1907 break; |
1453 } | 1908 } |
1454 case UnknownField::TYPE_FIXED64: { | 1909 case UnknownField::TYPE_FIXED64: { |
1455 generator.Print(field_number); | 1910 generator.Print(field_number); |
1456 generator.Print(": 0x"); | 1911 generator.Print(": 0x"); |
1457 char buffer[kFastToBufferSize]; | 1912 generator.Print( |
1458 generator.Print(FastHex64ToBuffer(field.fixed64(), buffer)); | 1913 StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16))); |
1459 if (single_line_mode_) { | 1914 if (single_line_mode_) { |
1460 generator.Print(" "); | 1915 generator.Print(" "); |
1461 } else { | 1916 } else { |
1462 generator.Print("\n"); | 1917 generator.Print("\n"); |
1463 } | 1918 } |
1464 break; | 1919 break; |
1465 } | 1920 } |
1466 case UnknownField::TYPE_LENGTH_DELIMITED: { | 1921 case UnknownField::TYPE_LENGTH_DELIMITED: { |
1467 generator.Print(field_number); | 1922 generator.Print(field_number); |
1468 const string& value = field.length_delimited(); | 1923 const string& value = field.length_delimited(); |
(...skipping 10 matching lines...) Expand all Loading... |
1479 PrintUnknownFields(embedded_unknown_fields, generator); | 1934 PrintUnknownFields(embedded_unknown_fields, generator); |
1480 if (single_line_mode_) { | 1935 if (single_line_mode_) { |
1481 generator.Print("} "); | 1936 generator.Print("} "); |
1482 } else { | 1937 } else { |
1483 generator.Outdent(); | 1938 generator.Outdent(); |
1484 generator.Print("}\n"); | 1939 generator.Print("}\n"); |
1485 } | 1940 } |
1486 } else { | 1941 } else { |
1487 // This field is not parseable as a Message. | 1942 // This field is not parseable as a Message. |
1488 // So it is probably just a plain string. | 1943 // So it is probably just a plain string. |
1489 generator.Print(": \""); | 1944 string printed(": \""); |
1490 generator.Print(CEscape(value)); | 1945 CEscapeAndAppend(value, &printed); |
1491 generator.Print("\""); | 1946 printed.append(single_line_mode_ ? "\" " : "\"\n"); |
1492 if (single_line_mode_) { | 1947 generator.Print(printed); |
1493 generator.Print(" "); | |
1494 } else { | |
1495 generator.Print("\n"); | |
1496 } | |
1497 } | 1948 } |
1498 break; | 1949 break; |
1499 } | 1950 } |
1500 case UnknownField::TYPE_GROUP: | 1951 case UnknownField::TYPE_GROUP: |
1501 generator.Print(field_number); | 1952 generator.Print(field_number); |
1502 if (single_line_mode_) { | 1953 if (single_line_mode_) { |
1503 generator.Print(" { "); | 1954 generator.Print(" { "); |
1504 } else { | 1955 } else { |
1505 generator.Print(" {\n"); | 1956 generator.Print(" {\n"); |
1506 generator.Indent(); | 1957 generator.Indent(); |
1507 } | 1958 } |
1508 PrintUnknownFields(field.group(), generator); | 1959 PrintUnknownFields(field.group(), generator); |
1509 if (single_line_mode_) { | 1960 if (single_line_mode_) { |
1510 generator.Print("} "); | 1961 generator.Print("} "); |
1511 } else { | 1962 } else { |
1512 generator.Outdent(); | 1963 generator.Outdent(); |
1513 generator.Print("}\n"); | 1964 generator.Print("}\n"); |
1514 } | 1965 } |
1515 break; | 1966 break; |
1516 } | 1967 } |
1517 } | 1968 } |
1518 } | 1969 } |
1519 | 1970 |
1520 } // namespace protobuf | 1971 } // namespace protobuf |
1521 } // namespace google | 1972 } // namespace google |
OLD | NEW |