@@ -403,8 +403,20 @@ size_t Reflection::SpaceUsedLong(const Message& message) const {
403
403
break;
404
404
405
405
case FieldDescriptor::CPPTYPE_STRING: {
406
- switch (field->options().ctype()) {
407
- default: // TODO(kenton): Support other string reps.
406
+ switch (internal::cpp::EffectiveStringCType(field)) {
407
+ case FieldOptions::CORD:
408
+ if (schema_.InRealOneof(field)) {
409
+ total_size += GetField<absl::Cord*>(message, field)
410
+ ->EstimatedMemoryUsage();
411
+
412
+ } else {
413
+ // sizeof(absl::Cord) is included to self.
414
+ total_size += GetField<absl::Cord>(message, field)
415
+ .EstimatedMemoryUsage() -
416
+ sizeof(absl::Cord);
417
+ }
418
+ break;
419
+ default:
408
420
case FieldOptions::STRING:
409
421
if (IsInlined(field)) {
410
422
const std::string* ptr =
@@ -501,7 +513,10 @@ struct OneofFieldMover {
501
513
to->SetString(from->GetString());
502
514
break;
503
515
}
504
- switch (field->options().ctype()) {
516
+ switch (internal::cpp::EffectiveStringCType(field)) {
517
+ case FieldOptions::CORD:
518
+ to->SetCord(from->GetCord());
519
+ break;
505
520
default:
506
521
case FieldOptions::STRING: {
507
522
to->SetArenaStringPtr(from->GetArenaStringPtr());
@@ -635,7 +650,12 @@ template <bool unsafe_shallow_swap>
635
650
void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs,
636
651
Message* rhs,
637
652
const FieldDescriptor* field) {
638
- switch (field->options().ctype()) {
653
+ switch (internal::cpp::EffectiveStringCType(field)) {
654
+ case FieldOptions::CORD:
655
+ // Always shallow swap for Cord.
656
+ std::swap(*r->MutableRaw<absl::Cord>(lhs, field),
657
+ *r->MutableRaw<absl::Cord>(rhs, field));
658
+ break;
639
659
default:
640
660
case FieldOptions::STRING: {
641
661
if (r->IsInlined(field)) {
@@ -891,6 +911,7 @@ void Reflection::SwapOneofField(Message* lhs, Message* rhs,
891
911
LOCAL_VAR_ACCESSOR(int, enum, Enum);
892
912
LOCAL_VAR_ACCESSOR(Message*, message, Message);
893
913
LOCAL_VAR_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
914
+ LOCAL_VAR_ACCESSOR(absl::Cord*, cord, Cord);
894
915
const std::string& GetString() const { return string_val; }
895
916
void SetString(const std::string& v) { string_val = v; }
896
917
Message* UnsafeGetMessage() const { return GetMessage(); }
@@ -908,6 +929,7 @@ void Reflection::SwapOneofField(Message* lhs, Message* rhs,
908
929
int type_enum;
909
930
Message* type_message;
910
931
internal::ArenaStringPtr type_arena_string_ptr;
932
+ absl::Cord* type_cord;
911
933
} oneof_val;
912
934
913
935
// std::string cannot be in union.
@@ -931,6 +953,7 @@ void Reflection::SwapOneofField(Message* lhs, Message* rhs,
931
953
MESSAGE_FIELD_ACCESSOR(bool, bool, Bool);
932
954
MESSAGE_FIELD_ACCESSOR(int, enum, Enum);
933
955
MESSAGE_FIELD_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
956
+ MESSAGE_FIELD_ACCESSOR(absl::Cord*, cord, Cord);
934
957
std::string GetString() const {
935
958
return reflection->GetString(*message, field);
936
959
}
@@ -1321,8 +1344,16 @@ void Reflection::ClearField(Message* message,
1321
1344
break;
1322
1345
1323
1346
case FieldDescriptor::CPPTYPE_STRING: {
1324
- switch (field->options().ctype()) {
1325
- default: // TODO(kenton): Support other string reps.
1347
+ switch (internal::cpp::EffectiveStringCType(field)) {
1348
+ case FieldOptions::CORD:
1349
+ if (field->has_default_value()) {
1350
+ *MutableRaw<absl::Cord>(message, field) =
1351
+ field->default_value_string();
1352
+ } else {
1353
+ MutableRaw<absl::Cord>(message, field)->Clear();
1354
+ }
1355
+ break;
1356
+ default:
1326
1357
case FieldOptions::STRING:
1327
1358
if (IsInlined(field)) {
1328
1359
// Currently, string with default value can' t be inlined. So we
@@ -1718,8 +1749,14 @@ std::string Reflection::GetString(const Message& message,
1718
1749
if (schema_.InRealOneof (field) && !HasOneofField (message, field)) {
1719
1750
return field->default_value_string ();
1720
1751
}
1721
- switch (field->options ().ctype ()) {
1722
- default : // TODO(kenton): Support other string reps.
1752
+ switch (internal::cpp::EffectiveStringCType (field)) {
1753
+ case FieldOptions::CORD:
1754
+ if (schema_.InRealOneof (field)) {
1755
+ return std::string (*GetField<absl::Cord*>(message, field));
1756
+ } else {
1757
+ return std::string (GetField<absl::Cord>(message, field));
1758
+ }
1759
+ default :
1723
1760
case FieldOptions::STRING:
1724
1761
if (IsInlined (field)) {
1725
1762
return GetField<InlinedStringField>(message, field).GetNoArena ();
@@ -1743,8 +1780,16 @@ const std::string& Reflection::GetStringReference(const Message& message,
1743
1780
if (schema_.InRealOneof (field) && !HasOneofField (message, field)) {
1744
1781
return field->default_value_string ();
1745
1782
}
1746
- switch (field->options ().ctype ()) {
1747
- default : // TODO(kenton): Support other string reps.
1783
+ switch (internal::cpp::EffectiveStringCType (field)) {
1784
+ case FieldOptions::CORD:
1785
+ if (schema_.InRealOneof (field)) {
1786
+ absl::CopyCordToString (*GetField<absl::Cord*>(message, field),
1787
+ scratch);
1788
+ } else {
1789
+ absl::CopyCordToString (GetField<absl::Cord>(message, field), scratch);
1790
+ }
1791
+ return *scratch;
1792
+ default :
1748
1793
case FieldOptions::STRING:
1749
1794
if (IsInlined (field)) {
1750
1795
return GetField<InlinedStringField>(message, field).GetNoArena ();
@@ -1756,6 +1801,39 @@ const std::string& Reflection::GetStringReference(const Message& message,
1756
1801
}
1757
1802
}
1758
1803
1804
+ absl::Cord Reflection::GetCord (const Message& message,
1805
+ const FieldDescriptor* field) const {
1806
+ USAGE_CHECK_ALL (GetCord, SINGULAR, STRING);
1807
+ if (field->is_extension ()) {
1808
+ return absl::Cord (GetExtensionSet (message).GetString (
1809
+ field->number (), field->default_value_string ()));
1810
+ } else {
1811
+ if (schema_.InRealOneof (field) && !HasOneofField (message, field)) {
1812
+ return absl::Cord (field->default_value_string ());
1813
+ }
1814
+ switch (internal::cpp::EffectiveStringCType (field)) {
1815
+ case FieldOptions::CORD:
1816
+ if (schema_.InRealOneof (field)) {
1817
+ return *GetField<absl::Cord*>(message, field);
1818
+ } else {
1819
+ return GetField<absl::Cord>(message, field);
1820
+ }
1821
+ default :
1822
+ case FieldOptions::STRING:
1823
+ if (IsInlined (field)) {
1824
+ return absl::Cord (
1825
+ GetField<InlinedStringField>(message, field).GetNoArena ());
1826
+ } else {
1827
+ const auto & str = GetField<ArenaStringPtr>(message, field);
1828
+ return absl::Cord (str.IsDefault () ? field->default_value_string ()
1829
+ : str.Get ());
1830
+ }
1831
+ }
1832
+
1833
+ ABSL_LOG (FATAL) << " Can't get here." ;
1834
+ return absl::Cord (); // Make compiler happy.
1835
+ }
1836
+ }
1759
1837
1760
1838
1761
1839
void Reflection::SetString (Message* message, const FieldDescriptor* field,
@@ -1765,8 +1843,20 @@ void Reflection::SetString(Message* message, const FieldDescriptor* field,
1765
1843
return MutableExtensionSet (message)->SetString (
1766
1844
field->number (), field->type (), std::move (value), field);
1767
1845
} else {
1768
- switch (field->options ().ctype ()) {
1769
- default : // TODO(kenton): Support other string reps.
1846
+ switch (internal::cpp::EffectiveStringCType (field)) {
1847
+ case FieldOptions::CORD:
1848
+ if (schema_.InRealOneof (field)) {
1849
+ if (!HasOneofField (*message, field)) {
1850
+ ClearOneof (message, field->containing_oneof ());
1851
+ *MutableField<absl::Cord*>(message, field) =
1852
+ Arena::Create<absl::Cord>(message->GetArenaForAllocation ());
1853
+ }
1854
+ *(*MutableField<absl::Cord*>(message, field)) = value;
1855
+ break ;
1856
+ }
1857
+ *MutableField<absl::Cord>(message, field) = value;
1858
+ break ;
1859
+ default :
1770
1860
case FieldOptions::STRING: {
1771
1861
if (IsInlined (field)) {
1772
1862
const uint32_t index = schema_.InlinedStringIndex (field);
@@ -1805,7 +1895,7 @@ void Reflection::SetString(Message* message, const FieldDescriptor* field,
1805
1895
MutableExtensionSet (message)->MutableString (
1806
1896
field->number (), field->type (), field));
1807
1897
} else {
1808
- switch (field-> options (). ctype ( )) {
1898
+ switch (internal::cpp::EffectiveStringCType (field )) {
1809
1899
case FieldOptions::CORD:
1810
1900
if (schema_.InRealOneof (field)) {
1811
1901
if (!HasOneofField (*message, field)) {
@@ -2721,8 +2811,11 @@ bool Reflection::HasBit(const Message& message,
2721
2811
// (which uses HasField()) needs to be consistent with this.
2722
2812
switch (field->cpp_type ()) {
2723
2813
case FieldDescriptor::CPPTYPE_STRING:
2724
- switch (field->options ().ctype ()) {
2725
- default : {
2814
+ switch (internal::cpp::EffectiveStringCType (field)) {
2815
+ case FieldOptions::CORD:
2816
+ return !GetField<const absl::Cord>(message, field).empty ();
2817
+ default :
2818
+ case FieldOptions::STRING: {
2726
2819
if (IsInlined (field)) {
2727
2820
return !GetField<InlinedStringField>(message, field)
2728
2821
.GetNoArena ()
@@ -2833,8 +2926,11 @@ void Reflection::ClearOneof(Message* message,
2833
2926
if (message->GetArenaForAllocation () == nullptr ) {
2834
2927
switch (field->cpp_type ()) {
2835
2928
case FieldDescriptor::CPPTYPE_STRING: {
2836
- switch (field->options ().ctype ()) {
2837
- default : // TODO(kenton): Support other string reps.
2929
+ switch (internal::cpp::EffectiveStringCType (field)) {
2930
+ case FieldOptions::CORD:
2931
+ delete *MutableRaw<absl::Cord*>(message, field);
2932
+ break ;
2933
+ default :
2838
2934
case FieldOptions::STRING: {
2839
2935
// Oneof string fields are never set as a default instance.
2840
2936
// We just need to pass some arbitrary default string to make it
0 commit comments