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 // http://code.google.com/p/protobuf/ |
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. |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 308 } |
309 } | 309 } |
310 | 310 |
311 MessageGenerator::~MessageGenerator() {} | 311 MessageGenerator::~MessageGenerator() {} |
312 | 312 |
313 void MessageGenerator:: | 313 void MessageGenerator:: |
314 GenerateForwardDeclaration(io::Printer* printer) { | 314 GenerateForwardDeclaration(io::Printer* printer) { |
315 printer->Print("class $classname$;\n", | 315 printer->Print("class $classname$;\n", |
316 "classname", classname_); | 316 "classname", classname_); |
317 | 317 |
| 318 if (descriptor_->options().generate_visitors()) { |
| 319 printer->Print( |
| 320 "class $classname$_Visitor;\n" |
| 321 "class $classname$_Writer;\n" |
| 322 "class $classname$_Filler;\n" |
| 323 "class $classname$_Guide;\n" |
| 324 "class $classname$_Reader;\n" |
| 325 "class $classname$_Walker;\n", |
| 326 "classname", classname_); |
| 327 } |
| 328 |
318 for (int i = 0; i < descriptor_->nested_type_count(); i++) { | 329 for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
319 nested_generators_[i]->GenerateForwardDeclaration(printer); | 330 nested_generators_[i]->GenerateForwardDeclaration(printer); |
320 } | 331 } |
321 } | 332 } |
322 | 333 |
323 void MessageGenerator:: | 334 void MessageGenerator:: |
324 GenerateEnumDefinitions(io::Printer* printer) { | 335 GenerateEnumDefinitions(io::Printer* printer) { |
325 for (int i = 0; i < descriptor_->nested_type_count(); i++) { | 336 for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
326 nested_generators_[i]->GenerateEnumDefinitions(printer); | 337 nested_generators_[i]->GenerateEnumDefinitions(printer); |
327 } | 338 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 } else { | 555 } else { |
545 printer->Print( | 556 printer->Print( |
546 "::std::string GetTypeName() const;\n" | 557 "::std::string GetTypeName() const;\n" |
547 "\n"); | 558 "\n"); |
548 } | 559 } |
549 | 560 |
550 printer->Print( | 561 printer->Print( |
551 "// nested types ----------------------------------------------------\n" | 562 "// nested types ----------------------------------------------------\n" |
552 "\n"); | 563 "\n"); |
553 | 564 |
| 565 if (descriptor_->options().generate_visitors()) { |
| 566 printer->Print( |
| 567 "typedef $classname$_Visitor Visitor;\n" |
| 568 "typedef $classname$_Writer Writer;\n" |
| 569 "typedef $classname$_Filler Filler;\n" |
| 570 "typedef $classname$_Guide Guide;\n" |
| 571 "typedef $classname$_Reader Reader;\n" |
| 572 "typedef $classname$_Walker Walker;\n" |
| 573 "\n", |
| 574 "classname", classname_); |
| 575 } |
| 576 |
554 // Import all nested message classes into this class's scope with typedefs. | 577 // Import all nested message classes into this class's scope with typedefs. |
555 for (int i = 0; i < descriptor_->nested_type_count(); i++) { | 578 for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
556 const Descriptor* nested_type = descriptor_->nested_type(i); | 579 const Descriptor* nested_type = descriptor_->nested_type(i); |
557 printer->Print("typedef $nested_full_name$ $nested_name$;\n", | 580 printer->Print("typedef $nested_full_name$ $nested_name$;\n", |
558 "nested_name", nested_type->name(), | 581 "nested_name", nested_type->name(), |
559 "nested_full_name", ClassName(nested_type, false)); | 582 "nested_full_name", ClassName(nested_type, false)); |
560 } | 583 } |
561 | 584 |
562 if (descriptor_->nested_type_count() > 0) { | 585 if (descriptor_->nested_type_count() > 0) { |
563 printer->Print("\n"); | 586 printer->Print("\n"); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 "adddescriptorsname", | 689 "adddescriptorsname", |
667 GlobalAddDescriptorsName(descriptor_->file()->name())); | 690 GlobalAddDescriptorsName(descriptor_->file()->name())); |
668 printer->Print( | 691 printer->Print( |
669 "friend void $assigndescriptorsname$();\n" | 692 "friend void $assigndescriptorsname$();\n" |
670 "friend void $shutdownfilename$();\n" | 693 "friend void $shutdownfilename$();\n" |
671 "\n", | 694 "\n", |
672 "assigndescriptorsname", | 695 "assigndescriptorsname", |
673 GlobalAssignDescriptorsName(descriptor_->file()->name()), | 696 GlobalAssignDescriptorsName(descriptor_->file()->name()), |
674 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); | 697 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); |
675 | 698 |
| 699 if (descriptor_->options().generate_visitors()) { |
| 700 // Declare Filler and Walker as friends. |
| 701 // TODO(kenton): This is ONLY needed to deal with ctype'd fields being |
| 702 // hidden in the public release. If/when we find time to port them, |
| 703 // these friend decls can be removed. |
| 704 printer->Print( |
| 705 "friend class $classname$_Filler;\n" |
| 706 "friend class $classname$_Walker;\n", |
| 707 "classname", classname_); |
| 708 } |
| 709 |
676 printer->Print( | 710 printer->Print( |
677 "void InitAsDefaultInstance();\n" | 711 "void InitAsDefaultInstance();\n" |
678 "static $classname$* default_instance_;\n", | 712 "static $classname$* default_instance_;\n", |
679 "classname", classname_); | 713 "classname", classname_); |
680 | 714 |
681 printer->Outdent(); | 715 printer->Outdent(); |
682 printer->Print(vars, "};"); | 716 printer->Print("};\n"); |
| 717 |
| 718 if (descriptor_->options().generate_visitors()) { |
| 719 GenerateVisitorDefinition(printer); |
| 720 } |
683 } | 721 } |
684 | 722 |
685 void MessageGenerator:: | 723 void MessageGenerator:: |
686 GenerateInlineMethods(io::Printer* printer) { | 724 GenerateInlineMethods(io::Printer* printer) { |
687 for (int i = 0; i < descriptor_->nested_type_count(); i++) { | 725 for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
688 nested_generators_[i]->GenerateInlineMethods(printer); | 726 nested_generators_[i]->GenerateInlineMethods(printer); |
689 printer->Print(kThinSeparator); | 727 printer->Print(kThinSeparator); |
690 printer->Print("\n"); | 728 printer->Print("\n"); |
691 } | 729 } |
692 | 730 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 } else { | 956 } else { |
919 printer->Print( | 957 printer->Print( |
920 "::std::string $classname$::GetTypeName() const {\n" | 958 "::std::string $classname$::GetTypeName() const {\n" |
921 " return \"$type_name$\";\n" | 959 " return \"$type_name$\";\n" |
922 "}\n" | 960 "}\n" |
923 "\n", | 961 "\n", |
924 "classname", classname_, | 962 "classname", classname_, |
925 "type_name", descriptor_->full_name()); | 963 "type_name", descriptor_->full_name()); |
926 } | 964 } |
927 | 965 |
| 966 if (descriptor_->options().generate_visitors()) { |
| 967 GenerateVisitorMethods(printer); |
| 968 } |
928 } | 969 } |
929 | 970 |
930 void MessageGenerator:: | 971 void MessageGenerator:: |
931 GenerateOffsets(io::Printer* printer) { | 972 GenerateOffsets(io::Printer* printer) { |
932 printer->Print( | 973 printer->Print( |
933 "static const int $classname$_offsets_[$field_count$] = {\n", | 974 "static const int $classname$_offsets_[$field_count$] = {\n", |
934 "classname", classname_, | 975 "classname", classname_, |
935 "field_count", SimpleItoa(max(1, descriptor_->field_count()))); | 976 "field_count", SimpleItoa(max(1, descriptor_->field_count()))); |
936 printer->Indent(); | 977 printer->Indent(); |
937 | 978 |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 " ::google::protobuf::io::CodedInputStream* input) {\n" | 1421 " ::google::protobuf::io::CodedInputStream* input) {\n" |
1381 " return _extensions_.ParseMessageSet(input, default_instance_,\n" | 1422 " return _extensions_.ParseMessageSet(input, default_instance_,\n" |
1382 " mutable_unknown_fields());\n" | 1423 " mutable_unknown_fields());\n" |
1383 "}\n", | 1424 "}\n", |
1384 "classname", classname_); | 1425 "classname", classname_); |
1385 return; | 1426 return; |
1386 } | 1427 } |
1387 | 1428 |
1388 printer->Print( | 1429 printer->Print( |
1389 "bool $classname$::MergePartialFromCodedStream(\n" | 1430 "bool $classname$::MergePartialFromCodedStream(\n" |
1390 " ::google::protobuf::io::CodedInputStream* input) {\n" | 1431 " ::google::protobuf::io::CodedInputStream* input) {\n", |
| 1432 "classname", classname_); |
| 1433 printer->Indent(); |
| 1434 |
| 1435 GenerateMergeFromCodedStreamBody(printer, PARSE_TO_MESSAGE); |
| 1436 |
| 1437 printer->Outdent(); |
| 1438 printer->Print( |
| 1439 "}\n"); |
| 1440 } |
| 1441 |
| 1442 void MessageGenerator:: |
| 1443 GenerateMergeFromCodedStreamBody(io::Printer* printer, ParseMode mode) { |
| 1444 printer->Print( |
1391 "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n" | 1445 "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n" |
1392 " ::google::protobuf::uint32 tag;\n" | 1446 "::google::protobuf::uint32 tag;\n" |
1393 " while ((tag = input->ReadTag()) != 0) {\n", | 1447 "while ((tag = input->ReadTag()) != 0) {\n"); |
1394 "classname", classname_); | |
1395 | 1448 |
1396 printer->Indent(); | 1449 printer->Indent(); |
1397 printer->Indent(); | |
1398 | 1450 |
1399 if (descriptor_->field_count() > 0) { | 1451 if (descriptor_->field_count() > 0) { |
1400 // We don't even want to print the switch() if we have no fields because | 1452 // We don't even want to print the switch() if we have no fields because |
1401 // MSVC dislikes switch() statements that contain only a default value. | 1453 // MSVC dislikes switch() statements that contain only a default value. |
1402 | 1454 |
1403 // Note: If we just switched on the tag rather than the field number, we | 1455 // Note: If we just switched on the tag rather than the field number, we |
1404 // could avoid the need for the if() to check the wire type at the beginning | 1456 // could avoid the need for the if() to check the wire type at the beginning |
1405 // of each case. However, this is actually a bit slower in practice as it | 1457 // of each case. However, this is actually a bit slower in practice as it |
1406 // creates a jump table that is 8x larger and sparser, and meanwhile the | 1458 // creates a jump table that is 8x larger and sparser, and meanwhile the |
1407 // if()s are highly predictable. | 1459 // if()s are highly predictable. |
(...skipping 23 matching lines...) Expand all Loading... |
1431 "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]); | 1483 "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]); |
1432 | 1484 |
1433 if (i > 0 || (field->is_repeated() && !field->options().packed())) { | 1485 if (i > 0 || (field->is_repeated() && !field->options().packed())) { |
1434 printer->Print( | 1486 printer->Print( |
1435 " parse_$name$:\n", | 1487 " parse_$name$:\n", |
1436 "name", field->name()); | 1488 "name", field->name()); |
1437 } | 1489 } |
1438 | 1490 |
1439 printer->Indent(); | 1491 printer->Indent(); |
1440 if (field->options().packed()) { | 1492 if (field->options().packed()) { |
1441 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); | 1493 switch (mode) { |
| 1494 case PARSE_TO_MESSAGE: |
| 1495 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); |
| 1496 break; |
| 1497 case PARSE_TO_VISITOR: |
| 1498 field_generator.GenerateReaderCodeWithPacking(printer); |
| 1499 break; |
| 1500 } |
1442 } else { | 1501 } else { |
1443 field_generator.GenerateMergeFromCodedStream(printer); | 1502 switch (mode) { |
| 1503 case PARSE_TO_MESSAGE: |
| 1504 field_generator.GenerateMergeFromCodedStream(printer); |
| 1505 break; |
| 1506 case PARSE_TO_VISITOR: |
| 1507 field_generator.GenerateReaderCode(printer); |
| 1508 break; |
| 1509 } |
1444 } | 1510 } |
1445 printer->Outdent(); | 1511 printer->Outdent(); |
1446 | 1512 |
1447 // Emit code to parse unexpectedly packed or unpacked values. | 1513 // Emit code to parse unexpectedly packed or unpacked values. |
1448 if (field->is_packable() && field->options().packed()) { | 1514 if (field->is_packable() && field->options().packed()) { |
1449 printer->Print( | 1515 printer->Print( |
1450 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireTy
pe(tag)\n" | 1516 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireTy
pe(tag)\n" |
1451 " == ::google::protobuf::internal::WireFormatLite::\n" | 1517 " == ::google::protobuf::internal::WireFormatLite::\n" |
1452 " WIRETYPE_$wiretype$) {\n", | 1518 " WIRETYPE_$wiretype$) {\n", |
1453 "wiretype", | 1519 "wiretype", |
1454 kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]); | 1520 kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]); |
1455 printer->Indent(); | 1521 printer->Indent(); |
1456 field_generator.GenerateMergeFromCodedStream(printer); | 1522 switch (mode) { |
| 1523 case PARSE_TO_MESSAGE: |
| 1524 field_generator.GenerateMergeFromCodedStream(printer); |
| 1525 break; |
| 1526 case PARSE_TO_VISITOR: |
| 1527 field_generator.GenerateReaderCode(printer); |
| 1528 break; |
| 1529 } |
1457 printer->Outdent(); | 1530 printer->Outdent(); |
1458 } else if (field->is_packable() && !field->options().packed()) { | 1531 } else if (field->is_packable() && !field->options().packed()) { |
1459 printer->Print( | 1532 printer->Print( |
1460 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireTy
pe(tag)\n" | 1533 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireTy
pe(tag)\n" |
1461 " == ::google::protobuf::internal::WireFormatLite::\n" | 1534 " == ::google::protobuf::internal::WireFormatLite::\n" |
1462 " WIRETYPE_LENGTH_DELIMITED) {\n"); | 1535 " WIRETYPE_LENGTH_DELIMITED) {\n"); |
1463 printer->Indent(); | 1536 printer->Indent(); |
1464 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); | 1537 switch (mode) { |
| 1538 case PARSE_TO_MESSAGE: |
| 1539 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); |
| 1540 break; |
| 1541 case PARSE_TO_VISITOR: |
| 1542 field_generator.GenerateReaderCodeWithPacking(printer); |
| 1543 break; |
| 1544 } |
1465 printer->Outdent(); | 1545 printer->Outdent(); |
1466 } | 1546 } |
1467 | 1547 |
1468 printer->Print( | 1548 printer->Print( |
1469 "} else {\n" | 1549 "} else {\n" |
1470 " goto handle_uninterpreted;\n" | 1550 " goto handle_uninterpreted;\n" |
1471 "}\n"); | 1551 "}\n"); |
1472 | 1552 |
1473 // switch() is slow since it can't be predicted well. Insert some if()s | 1553 // switch() is slow since it can't be predicted well. Insert some if()s |
1474 // here that attempt to predict the next tag. | 1554 // here that attempt to predict the next tag. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1508 } | 1588 } |
1509 | 1589 |
1510 // Is this an end-group tag? If so, this must be the end of the message. | 1590 // Is this an end-group tag? If so, this must be the end of the message. |
1511 printer->Print( | 1591 printer->Print( |
1512 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" | 1592 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" |
1513 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" | 1593 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" |
1514 " return true;\n" | 1594 " return true;\n" |
1515 "}\n"); | 1595 "}\n"); |
1516 | 1596 |
1517 // Handle extension ranges. | 1597 // Handle extension ranges. |
1518 if (descriptor_->extension_range_count() > 0) { | 1598 // TODO(kenton): Support visiting extensions. |
| 1599 if (mode == PARSE_TO_MESSAGE && descriptor_->extension_range_count() > 0) { |
1519 printer->Print( | 1600 printer->Print( |
1520 "if ("); | 1601 "if ("); |
1521 for (int i = 0; i < descriptor_->extension_range_count(); i++) { | 1602 for (int i = 0; i < descriptor_->extension_range_count(); i++) { |
1522 const Descriptor::ExtensionRange* range = | 1603 const Descriptor::ExtensionRange* range = |
1523 descriptor_->extension_range(i); | 1604 descriptor_->extension_range(i); |
1524 if (i > 0) printer->Print(" ||\n "); | 1605 if (i > 0) printer->Print(" ||\n "); |
1525 | 1606 |
1526 uint32 start_tag = WireFormatLite::MakeTag( | 1607 uint32 start_tag = WireFormatLite::MakeTag( |
1527 range->start, static_cast<WireFormatLite::WireType>(0)); | 1608 range->start, static_cast<WireFormatLite::WireType>(0)); |
1528 uint32 end_tag = WireFormatLite::MakeTag( | 1609 uint32 end_tag = WireFormatLite::MakeTag( |
(...skipping 18 matching lines...) Expand all Loading... |
1547 } else { | 1628 } else { |
1548 printer->Print( | 1629 printer->Print( |
1549 " DO_(_extensions_.ParseField(tag, input, default_instance_));\n"); | 1630 " DO_(_extensions_.ParseField(tag, input, default_instance_));\n"); |
1550 } | 1631 } |
1551 printer->Print( | 1632 printer->Print( |
1552 " continue;\n" | 1633 " continue;\n" |
1553 "}\n"); | 1634 "}\n"); |
1554 } | 1635 } |
1555 | 1636 |
1556 // We really don't recognize this tag. Skip it. | 1637 // We really don't recognize this tag. Skip it. |
1557 if (HasUnknownFields(descriptor_->file())) { | 1638 // TODO(kenton): Support visiting unknown fields. |
| 1639 if (mode == PARSE_TO_MESSAGE && HasUnknownFields(descriptor_->file())) { |
1558 printer->Print( | 1640 printer->Print( |
1559 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" | 1641 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" |
1560 " input, tag, mutable_unknown_fields()));\n"); | 1642 " input, tag, mutable_unknown_fields()));\n"); |
1561 } else { | 1643 } else { |
1562 printer->Print( | 1644 printer->Print( |
1563 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
\n"); | 1645 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
\n"); |
1564 } | 1646 } |
1565 | 1647 |
1566 if (descriptor_->field_count() > 0) { | 1648 if (descriptor_->field_count() > 0) { |
1567 printer->Print("break;\n"); | 1649 printer->Print("break;\n"); |
1568 printer->Outdent(); | 1650 printer->Outdent(); |
1569 printer->Print("}\n"); // default: | 1651 printer->Print("}\n"); // default: |
1570 printer->Outdent(); | 1652 printer->Outdent(); |
1571 printer->Print("}\n"); // switch | 1653 printer->Print("}\n"); // switch |
1572 } | 1654 } |
1573 | 1655 |
1574 printer->Outdent(); | 1656 printer->Outdent(); |
1575 printer->Outdent(); | |
1576 printer->Print( | 1657 printer->Print( |
1577 " }\n" // while | 1658 "}\n" // while |
1578 " return true;\n" | 1659 "return true;\n" |
1579 "#undef DO_\n" | 1660 "#undef DO_\n"); |
1580 "}\n"); | |
1581 } | 1661 } |
1582 | 1662 |
1583 void MessageGenerator::GenerateSerializeOneField( | 1663 void MessageGenerator::GenerateSerializeOneField( |
1584 io::Printer* printer, const FieldDescriptor* field, bool to_array) { | 1664 io::Printer* printer, const FieldDescriptor* field, SerializeMode mode) { |
1585 PrintFieldComment(printer, field); | 1665 PrintFieldComment(printer, field); |
1586 | 1666 |
1587 if (!field->is_repeated()) { | 1667 if (!field->is_repeated()) { |
1588 printer->Print( | 1668 if (mode == SERIALIZE_TO_VISITOR) { |
1589 "if (has_$name$()) {\n", | 1669 printer->Print( |
1590 "name", FieldName(field)); | 1670 "if (message_.has_$name$()) {\n", |
| 1671 "name", FieldName(field)); |
| 1672 } else { |
| 1673 printer->Print( |
| 1674 "if (has_$name$()) {\n", |
| 1675 "name", FieldName(field)); |
| 1676 } |
1591 printer->Indent(); | 1677 printer->Indent(); |
1592 } | 1678 } |
1593 | 1679 |
1594 if (to_array) { | 1680 switch (mode) { |
1595 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray( | 1681 case SERIALIZE_TO_ARRAY: |
1596 printer); | 1682 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray( |
1597 } else { | 1683 printer); |
1598 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); | 1684 break; |
| 1685 case SERIALIZE_TO_STREAM: |
| 1686 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); |
| 1687 break; |
| 1688 case SERIALIZE_TO_VISITOR: |
| 1689 field_generators_.get(field).GenerateWalkerCode(printer); |
| 1690 break; |
1599 } | 1691 } |
1600 | 1692 |
1601 if (!field->is_repeated()) { | 1693 if (!field->is_repeated()) { |
1602 printer->Outdent(); | 1694 printer->Outdent(); |
1603 printer->Print("}\n"); | 1695 printer->Print("}\n"); |
1604 } | 1696 } |
1605 printer->Print("\n"); | 1697 printer->Print("\n"); |
1606 } | 1698 } |
1607 | 1699 |
1608 void MessageGenerator::GenerateSerializeOneExtensionRange( | 1700 void MessageGenerator::GenerateSerializeOneExtensionRange( |
1609 io::Printer* printer, const Descriptor::ExtensionRange* range, | 1701 io::Printer* printer, const Descriptor::ExtensionRange* range, |
1610 bool to_array) { | 1702 SerializeMode mode) { |
1611 map<string, string> vars; | 1703 map<string, string> vars; |
1612 vars["start"] = SimpleItoa(range->start); | 1704 vars["start"] = SimpleItoa(range->start); |
1613 vars["end"] = SimpleItoa(range->end); | 1705 vars["end"] = SimpleItoa(range->end); |
1614 printer->Print(vars, | 1706 printer->Print(vars, |
1615 "// Extension range [$start$, $end$)\n"); | 1707 "// Extension range [$start$, $end$)\n"); |
1616 if (to_array) { | 1708 switch (mode) { |
1617 printer->Print(vars, | 1709 case SERIALIZE_TO_ARRAY: |
1618 "target = _extensions_.SerializeWithCachedSizesToArray(\n" | 1710 printer->Print(vars, |
1619 " $start$, $end$, target);\n\n"); | 1711 "target = _extensions_.SerializeWithCachedSizesToArray(\n" |
1620 } else { | 1712 " $start$, $end$, target);\n\n"); |
1621 printer->Print(vars, | 1713 break; |
1622 "_extensions_.SerializeWithCachedSizes(\n" | 1714 case SERIALIZE_TO_STREAM: |
1623 " $start$, $end$, output);\n\n"); | 1715 printer->Print(vars, |
| 1716 "_extensions_.SerializeWithCachedSizes(\n" |
| 1717 " $start$, $end$, output);\n\n"); |
| 1718 break; |
| 1719 case SERIALIZE_TO_VISITOR: |
| 1720 // TODO(kenton): Support visiting extensions. |
| 1721 break; |
1624 } | 1722 } |
1625 } | 1723 } |
1626 | 1724 |
1627 void MessageGenerator:: | 1725 void MessageGenerator:: |
1628 GenerateSerializeWithCachedSizes(io::Printer* printer) { | 1726 GenerateSerializeWithCachedSizes(io::Printer* printer) { |
1629 if (descriptor_->options().message_set_wire_format()) { | 1727 if (descriptor_->options().message_set_wire_format()) { |
1630 // Special-case MessageSet. | 1728 // Special-case MessageSet. |
1631 printer->Print( | 1729 printer->Print( |
1632 "void $classname$::SerializeWithCachedSizes(\n" | 1730 "void $classname$::SerializeWithCachedSizes(\n" |
1633 " ::google::protobuf::io::CodedOutputStream* output) const {\n" | 1731 " ::google::protobuf::io::CodedOutputStream* output) const {\n" |
1634 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", | 1732 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", |
1635 "classname", classname_); | 1733 "classname", classname_); |
1636 if (HasUnknownFields(descriptor_->file())) { | 1734 if (HasUnknownFields(descriptor_->file())) { |
1637 printer->Print( | 1735 printer->Print( |
1638 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetI
tems(\n" | 1736 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetI
tems(\n" |
1639 " unknown_fields(), output);\n"); | 1737 " unknown_fields(), output);\n"); |
1640 } | 1738 } |
1641 printer->Print( | 1739 printer->Print( |
1642 "}\n"); | 1740 "}\n"); |
1643 return; | 1741 return; |
1644 } | 1742 } |
1645 | 1743 |
1646 printer->Print( | 1744 printer->Print( |
1647 "void $classname$::SerializeWithCachedSizes(\n" | 1745 "void $classname$::SerializeWithCachedSizes(\n" |
1648 " ::google::protobuf::io::CodedOutputStream* output) const {\n", | 1746 " ::google::protobuf::io::CodedOutputStream* output) const {\n", |
1649 "classname", classname_); | 1747 "classname", classname_); |
1650 printer->Indent(); | 1748 printer->Indent(); |
1651 | 1749 |
1652 GenerateSerializeWithCachedSizesBody(printer, false); | 1750 GenerateSerializeWithCachedSizesBody(printer, SERIALIZE_TO_STREAM); |
1653 | 1751 |
1654 printer->Outdent(); | 1752 printer->Outdent(); |
1655 printer->Print( | 1753 printer->Print( |
1656 "}\n"); | 1754 "}\n"); |
1657 } | 1755 } |
1658 | 1756 |
1659 void MessageGenerator:: | 1757 void MessageGenerator:: |
1660 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { | 1758 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { |
1661 if (descriptor_->options().message_set_wire_format()) { | 1759 if (descriptor_->options().message_set_wire_format()) { |
1662 // Special-case MessageSet. | 1760 // Special-case MessageSet. |
(...skipping 14 matching lines...) Expand all Loading... |
1677 "}\n"); | 1775 "}\n"); |
1678 return; | 1776 return; |
1679 } | 1777 } |
1680 | 1778 |
1681 printer->Print( | 1779 printer->Print( |
1682 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" | 1780 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" |
1683 " ::google::protobuf::uint8* target) const {\n", | 1781 " ::google::protobuf::uint8* target) const {\n", |
1684 "classname", classname_); | 1782 "classname", classname_); |
1685 printer->Indent(); | 1783 printer->Indent(); |
1686 | 1784 |
1687 GenerateSerializeWithCachedSizesBody(printer, true); | 1785 GenerateSerializeWithCachedSizesBody(printer, SERIALIZE_TO_ARRAY); |
1688 | 1786 |
1689 printer->Outdent(); | 1787 printer->Outdent(); |
1690 printer->Print( | 1788 printer->Print( |
1691 " return target;\n" | 1789 " return target;\n" |
1692 "}\n"); | 1790 "}\n"); |
1693 } | 1791 } |
1694 | 1792 |
1695 void MessageGenerator:: | 1793 void MessageGenerator:: |
1696 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { | 1794 GenerateSerializeWithCachedSizesBody(io::Printer* printer, SerializeMode mode) { |
1697 scoped_array<const FieldDescriptor*> ordered_fields( | 1795 scoped_array<const FieldDescriptor*> ordered_fields( |
1698 SortFieldsByNumber(descriptor_)); | 1796 SortFieldsByNumber(descriptor_)); |
1699 | 1797 |
1700 vector<const Descriptor::ExtensionRange*> sorted_extensions; | 1798 vector<const Descriptor::ExtensionRange*> sorted_extensions; |
1701 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { | 1799 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { |
1702 sorted_extensions.push_back(descriptor_->extension_range(i)); | 1800 sorted_extensions.push_back(descriptor_->extension_range(i)); |
1703 } | 1801 } |
1704 sort(sorted_extensions.begin(), sorted_extensions.end(), | 1802 sort(sorted_extensions.begin(), sorted_extensions.end(), |
1705 ExtensionRangeSorter()); | 1803 ExtensionRangeSorter()); |
1706 | 1804 |
1707 // Merge the fields and the extension ranges, both sorted by field number. | 1805 // Merge the fields and the extension ranges, both sorted by field number. |
1708 int i, j; | 1806 int i, j; |
1709 for (i = 0, j = 0; | 1807 for (i = 0, j = 0; |
1710 i < descriptor_->field_count() || j < sorted_extensions.size(); | 1808 i < descriptor_->field_count() || j < sorted_extensions.size(); |
1711 ) { | 1809 ) { |
1712 if (i == descriptor_->field_count()) { | 1810 if (i == descriptor_->field_count()) { |
1713 GenerateSerializeOneExtensionRange(printer, | 1811 GenerateSerializeOneExtensionRange(printer, |
1714 sorted_extensions[j++], | 1812 sorted_extensions[j++], |
1715 to_array); | 1813 mode); |
1716 } else if (j == sorted_extensions.size()) { | 1814 } else if (j == sorted_extensions.size()) { |
1717 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); | 1815 GenerateSerializeOneField(printer, ordered_fields[i++], mode); |
1718 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { | 1816 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { |
1719 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); | 1817 GenerateSerializeOneField(printer, ordered_fields[i++], mode); |
1720 } else { | 1818 } else { |
1721 GenerateSerializeOneExtensionRange(printer, | 1819 GenerateSerializeOneExtensionRange(printer, |
1722 sorted_extensions[j++], | 1820 sorted_extensions[j++], |
1723 to_array); | 1821 mode); |
1724 } | 1822 } |
1725 } | 1823 } |
1726 | 1824 |
1727 if (HasUnknownFields(descriptor_->file())) { | 1825 if (HasUnknownFields(descriptor_->file())) { |
1728 printer->Print("if (!unknown_fields().empty()) {\n"); | 1826 switch (mode) { |
1729 printer->Indent(); | 1827 case SERIALIZE_TO_ARRAY: |
1730 if (to_array) { | 1828 printer->Print( |
1731 printer->Print( | 1829 "if (!unknown_fields().empty()) {\n" |
1732 "target = " | 1830 " target = ::google::protobuf::internal::WireFormat::\n" |
1733 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToA
rray(\n" | 1831 " SerializeUnknownFieldsToArray(unknown_fields(), target);\n" |
1734 " unknown_fields(), target);\n"); | 1832 "}\n"); |
1735 } else { | 1833 break; |
1736 printer->Print( | 1834 case SERIALIZE_TO_STREAM: |
1737 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" | 1835 printer->Print( |
1738 " unknown_fields(), output);\n"); | 1836 "if (!unknown_fields().empty()) {\n" |
| 1837 " ::google::protobuf::internal::WireFormat::\n" |
| 1838 " SerializeUnknownFields(unknown_fields(), output);\n" |
| 1839 "}\n"); |
| 1840 break; |
| 1841 case SERIALIZE_TO_VISITOR: |
| 1842 // TODO(kenton): Support visiting unknown fields. |
| 1843 break; |
1739 } | 1844 } |
1740 printer->Outdent(); | |
1741 | |
1742 printer->Print( | |
1743 "}\n"); | |
1744 } | 1845 } |
1745 } | 1846 } |
1746 | 1847 |
1747 void MessageGenerator:: | 1848 void MessageGenerator:: |
1748 GenerateByteSize(io::Printer* printer) { | 1849 GenerateByteSize(io::Printer* printer) { |
1749 if (descriptor_->options().message_set_wire_format()) { | 1850 if (descriptor_->options().message_set_wire_format()) { |
1750 // Special-case MessageSet. | 1851 // Special-case MessageSet. |
1751 printer->Print( | 1852 printer->Print( |
1752 "int $classname$::ByteSize() const {\n" | 1853 "int $classname$::ByteSize() const {\n" |
1753 " int total_size = _extensions_.MessageSetByteSize();\n", | 1854 " int total_size = _extensions_.MessageSetByteSize();\n", |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1919 "\n" | 2020 "\n" |
1920 "if (!_extensions_.IsInitialized()) return false;"); | 2021 "if (!_extensions_.IsInitialized()) return false;"); |
1921 } | 2022 } |
1922 | 2023 |
1923 printer->Outdent(); | 2024 printer->Outdent(); |
1924 printer->Print( | 2025 printer->Print( |
1925 " return true;\n" | 2026 " return true;\n" |
1926 "}\n"); | 2027 "}\n"); |
1927 } | 2028 } |
1928 | 2029 |
| 2030 void MessageGenerator:: |
| 2031 GenerateVisitorDefinition(google::protobuf::io::Printer* printer) { |
| 2032 printer->Print("\n"); |
| 2033 printer->Print(kThinSeparator); |
| 2034 printer->Print( |
| 2035 "\n" |
| 2036 "class $classname$_Visitor {\n" |
| 2037 " public:\n" |
| 2038 " virtual ~$classname$_Visitor();\n" |
| 2039 "\n", |
| 2040 "classname", classname_); |
| 2041 |
| 2042 GenerateVisitorInterface(printer); |
| 2043 |
| 2044 printer->Print( |
| 2045 "};\n" |
| 2046 "\n" |
| 2047 "class $classname$_Writer : public $classname$_Visitor {\n" |
| 2048 " public:\n" |
| 2049 " $classname$_Writer(\n" |
| 2050 " ::google::protobuf::io::CodedOutputStream* output)\n" |
| 2051 " : output_(output) {}\n" |
| 2052 " virtual ~$classname$_Writer();\n" |
| 2053 "\n", |
| 2054 "classname", classname_); |
| 2055 |
| 2056 GenerateVisitorInterface(printer); |
| 2057 |
| 2058 printer->Print( |
| 2059 " private:\n" |
| 2060 " ::google::protobuf::io::CodedOutputStream* output_;\n" |
| 2061 "};\n" |
| 2062 "\n" |
| 2063 "class $classname$_Filler : public $classname$_Visitor {\n" |
| 2064 " public:\n" |
| 2065 " $classname$_Filler($classname$* message)\n" |
| 2066 " : message_(message) {}\n" |
| 2067 " virtual ~$classname$_Filler();\n" |
| 2068 "\n", |
| 2069 "classname", classname_); |
| 2070 |
| 2071 GenerateVisitorInterface(printer); |
| 2072 |
| 2073 printer->Print( |
| 2074 " private:\n" |
| 2075 " $classname$* message_;\n" |
| 2076 "};\n" |
| 2077 "\n" |
| 2078 "class $classname$_Guide {\n" |
| 2079 " public:\n" |
| 2080 " virtual ~$classname$_Guide();\n" |
| 2081 "\n" |
| 2082 " virtual bool Accept($classname$_Visitor* visitor) = 0;\n" |
| 2083 " virtual bool Fill($classname$* message) = 0;\n" |
| 2084 "};\n" |
| 2085 "\n" |
| 2086 "class $classname$_Reader : public $classname$_Guide {\n" |
| 2087 " public:\n" |
| 2088 " $classname$_Reader(::google::protobuf::io::CodedInputStream* input)\n" |
| 2089 " : input_(input) {}\n" |
| 2090 " virtual ~$classname$_Reader();\n" |
| 2091 "\n" |
| 2092 " virtual bool Accept($classname$_Visitor* visitor);\n" |
| 2093 " virtual bool Fill($classname$* message);\n" |
| 2094 " inline bool IsUsed() const { return input_ == NULL; }\n" |
| 2095 "\n" |
| 2096 " private:\n" |
| 2097 " ::google::protobuf::io::CodedInputStream* input_;\n" |
| 2098 "};\n" |
| 2099 "\n" |
| 2100 "class $classname$_Walker : public $classname$_Guide {\n" |
| 2101 " public:\n" |
| 2102 " $classname$_Walker(const $classname$& message)\n" |
| 2103 " : message_(message) {}\n" |
| 2104 " virtual ~$classname$_Walker();\n" |
| 2105 "\n" |
| 2106 " virtual bool Accept($classname$_Visitor* visitor);\n" |
| 2107 " virtual bool Fill($classname$* message);\n" |
| 2108 "\n" |
| 2109 " private:\n" |
| 2110 " const $classname$& message_;\n" |
| 2111 "};\n" |
| 2112 "\n", |
| 2113 "classname", classname_); |
| 2114 } |
| 2115 |
| 2116 void MessageGenerator:: |
| 2117 GenerateVisitorInterface(google::protobuf::io::Printer* printer) { |
| 2118 printer->Indent(); |
| 2119 for (int i = 0; i < descriptor_->field_count(); i++) { |
| 2120 const FieldDescriptor* field = descriptor_->field(i); |
| 2121 |
| 2122 PrintFieldComment(printer, field); |
| 2123 field_generators_.get(field).GenerateVisitInterface(printer); |
| 2124 printer->Print("\n"); |
| 2125 } |
| 2126 printer->Outdent(); |
| 2127 } |
| 2128 |
| 2129 void MessageGenerator:: |
| 2130 GenerateVisitorMethods(google::protobuf::io::Printer* printer) { |
| 2131 printer->Print("\n"); |
| 2132 printer->Print(kThinSeparator); |
| 2133 printer->Print( |
| 2134 "\n" |
| 2135 "$classname$_Visitor::~$classname$_Visitor() {}\n" |
| 2136 "$classname$_Writer::~$classname$_Writer() {}\n" |
| 2137 "$classname$_Filler::~$classname$_Filler() {}\n" |
| 2138 "\n", |
| 2139 "classname", classname_); |
| 2140 |
| 2141 for (int i = 0; i < descriptor_->field_count(); i++) { |
| 2142 const FieldDescriptor* field = descriptor_->field(i); |
| 2143 |
| 2144 PrintFieldComment(printer, field); |
| 2145 field_generators_.get(field).GenerateVisitMethods(printer); |
| 2146 printer->Print("\n"); |
| 2147 } |
| 2148 |
| 2149 printer->Print( |
| 2150 "$classname$_Guide::~$classname$_Guide() {}\n" |
| 2151 "\n" |
| 2152 "$classname$_Reader::~$classname$_Reader() {}\n" |
| 2153 "bool $classname$_Reader::Accept($classname$_Visitor* visitor) {\n" |
| 2154 " GOOGLE_CHECK(input_ != NULL) << \"Guide has already been used.\";\n" |
| 2155 " ::google::protobuf::io::CodedInputStream* input = input_;\n" |
| 2156 " input_ = NULL;\n", |
| 2157 "classname", classname_); |
| 2158 |
| 2159 printer->Indent(); |
| 2160 if (descriptor_->options().message_set_wire_format()) { |
| 2161 // TODO(kenton): Support visiting MessageSet? |
| 2162 } else { |
| 2163 GenerateMergeFromCodedStreamBody(printer, PARSE_TO_VISITOR); |
| 2164 } |
| 2165 printer->Outdent(); |
| 2166 |
| 2167 printer->Print( |
| 2168 " input_ = NULL;\n" |
| 2169 "}\n" |
| 2170 "bool $classname$_Reader::Fill($classname$* message) {\n" |
| 2171 " GOOGLE_CHECK(input_ != NULL) << \"Guide has already been used.\";\n" |
| 2172 " bool result = message->MergePartialFromCodedStream(input_);\n" |
| 2173 " input_ = NULL;\n" |
| 2174 " return result;\n" |
| 2175 "}\n" |
| 2176 "\n" |
| 2177 "$classname$_Walker::~$classname$_Walker() {}\n" |
| 2178 "bool $classname$_Walker::Accept($classname$_Visitor* visitor) {\n", |
| 2179 "classname", classname_); |
| 2180 |
| 2181 printer->Indent(); |
| 2182 GenerateSerializeWithCachedSizesBody(printer, SERIALIZE_TO_VISITOR); |
| 2183 printer->Outdent(); |
| 2184 |
| 2185 printer->Print( |
| 2186 " return true;\n" |
| 2187 "}\n" |
| 2188 "bool $classname$_Walker::Fill($classname$* message) {\n" |
| 2189 " message->MergeFrom(message_);\n" |
| 2190 " return true;\n" |
| 2191 "}\n" |
| 2192 "\n", |
| 2193 "classname", classname_); |
| 2194 } |
1929 | 2195 |
1930 } // namespace cpp | 2196 } // namespace cpp |
1931 } // namespace compiler | 2197 } // namespace compiler |
1932 } // namespace protobuf | 2198 } // namespace protobuf |
1933 } // namespace google | 2199 } // namespace google |
OLD | NEW |