diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs
index d3e1ea9534..c05125c629 100644
--- a/csharp/src/AddressBook/Addressbook.cs
+++ b/csharp/src/AddressBook/Addressbook.cs
@@ -260,7 +260,9 @@ namespace Google.Protobuf.Examples.AddressBook {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -440,7 +442,9 @@ namespace Google.Protobuf.Examples.AddressBook {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Number = input.ReadString();
@@ -573,7 +577,9 @@ namespace Google.Protobuf.Examples.AddressBook {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
people_.AddEntriesFrom(input, _repeated_people_codec);
diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
index cd9b77abe5..1642669e92 100644
--- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
@@ -343,7 +343,9 @@ namespace Conformance {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
ProtobufPayload = input.ReadBytes();
@@ -683,7 +685,9 @@ namespace Conformance {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
ParseError = input.ReadString();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
index 6d3cd026d1..2844ca62ce 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
@@ -541,7 +541,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec);
@@ -737,7 +739,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (testMap_ == null) {
@@ -861,7 +865,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
mapInt32Message_.AddEntriesFrom(input, _map_mapInt32Message_codec);
@@ -1001,7 +1007,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
map1_.AddEntriesFrom(input, _map_map1_codec);
@@ -1350,7 +1358,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec);
@@ -1531,7 +1541,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
type_.AddEntriesFrom(input, _map_type_codec);
@@ -1666,7 +1678,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
entry_.AddEntriesFrom(input, _map_entry_codec);
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs
index d74422b59b..683dc41d0e 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs
@@ -2867,7 +2867,9 @@ namespace ProtobufTestMessages.Proto3 {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
OptionalInt32 = input.ReadInt32();
@@ -3582,7 +3584,9 @@ namespace ProtobufTestMessages.Proto3 {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
A = input.ReadInt32();
@@ -3723,7 +3727,9 @@ namespace ProtobufTestMessages.Proto3 {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
C = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs
index 2a9efe55ff..9b9ffe2560 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs
@@ -352,7 +352,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Field1 = input.ReadString();
@@ -478,7 +480,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -579,7 +583,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -680,7 +686,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -781,7 +789,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -882,7 +892,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -996,7 +1008,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1097,7 +1111,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1198,7 +1214,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1299,7 +1317,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1400,7 +1420,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1501,7 +1523,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1690,7 +1714,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Foo = input.ReadInt32();
@@ -1902,7 +1928,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (bar_ == null) {
@@ -2051,7 +2079,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Waldo = input.ReadInt32();
@@ -2185,7 +2215,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Qux = input.ReadInt32();
@@ -2293,7 +2325,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -2475,7 +2509,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
I = input.ReadInt32();
@@ -2615,7 +2651,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Fieldname = input.ReadInt32();
@@ -2723,7 +2761,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -2855,7 +2895,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
NestedField = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
index 6bf9715171..931dc2eb03 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
@@ -167,7 +167,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
D = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
index 97d181aff4..fee0120b42 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
@@ -155,7 +155,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
E = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
index f27ab64074..f8296b0fab 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
@@ -181,7 +181,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -284,7 +286,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -387,7 +391,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -554,7 +560,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = (global::UnitTest.Issues.TestProtos.NegativeEnum) input.ReadEnum();
@@ -669,7 +677,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -899,7 +909,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
PrimitiveValue = input.ReadInt32();
@@ -1056,7 +1068,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Item = input.ReadInt32();
@@ -1209,7 +1223,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Types_ = input.ReadInt32();
@@ -1323,7 +1339,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -1647,7 +1665,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
PlainString = input.ReadString();
@@ -1847,7 +1867,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -2047,7 +2069,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Text = input.ReadString();
@@ -2211,7 +2235,9 @@ namespace UnitTest.Issues.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
X = input.ReadInt32();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
index bbbee22c7b..1d4367b781 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
@@ -1387,7 +1387,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
SingleInt32 = input.ReadInt32();
@@ -1755,7 +1757,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Bb = input.ReadInt32();
@@ -1938,7 +1942,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (child_ == null) {
@@ -2082,7 +2088,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
DeprecatedInt32 = input.ReadInt32();
@@ -2215,7 +2223,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
C = input.ReadInt32();
@@ -2320,7 +2330,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -2451,7 +2463,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (foreignNested_ == null) {
@@ -2614,7 +2628,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
A = input.ReadInt32();
@@ -2774,7 +2790,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (a_ == null) {
@@ -2916,7 +2934,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (bb_ == null) {
@@ -3075,7 +3095,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (a_ == null) {
@@ -3211,7 +3233,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = (global::Google.Protobuf.TestProtos.TestEnumWithDupValue) input.ReadEnum();
@@ -3483,7 +3507,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
PrimitiveField = input.ReadInt32();
@@ -3724,7 +3750,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
MyInt = input.ReadInt64();
@@ -3899,7 +3927,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Bb = input.ReadInt32();
@@ -4037,7 +4067,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
SparseEnum = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum();
@@ -4169,7 +4201,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Data = input.ReadString();
@@ -4290,7 +4324,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
data_.AddEntriesFrom(input, _repeated_data_codec);
@@ -4419,7 +4455,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Data = input.ReadBytes();
@@ -4548,7 +4586,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Data = input.ReadBytes();
@@ -4680,7 +4720,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Data = input.ReadInt32();
@@ -4809,7 +4851,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Data = input.ReadUInt32();
@@ -4938,7 +4982,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Data = input.ReadInt64();
@@ -5067,7 +5113,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Data = input.ReadUInt64();
@@ -5196,7 +5244,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Data = input.ReadBool();
@@ -5413,7 +5463,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
FooInt = input.ReadInt32();
@@ -5755,7 +5807,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 722:
case 720: {
@@ -6154,7 +6208,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 722:
case 720: {
@@ -6435,7 +6491,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 98:
case 101: {
@@ -6593,7 +6651,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
A = input.ReadString();
@@ -6701,7 +6761,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -6802,7 +6864,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -6903,7 +6967,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -7004,7 +7070,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -7105,7 +7173,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -7206,7 +7276,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -7307,7 +7379,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
@@ -7438,7 +7512,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Text = input.ReadString();
@@ -7585,7 +7661,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
NestedText = input.ReadString();
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
index 45f8ece646..a36825dc32 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
@@ -788,7 +788,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
if (anyField_ == null) {
@@ -1316,7 +1318,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
anyField_.AddEntriesFrom(input, _repeated_anyField_codec);
@@ -2027,7 +2031,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
global::Google.Protobuf.WellKnownTypes.Any subBuilder = new global::Google.Protobuf.WellKnownTypes.Any();
@@ -2538,7 +2544,9 @@ namespace Google.Protobuf.TestProtos {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
anyField_.AddEntriesFrom(input, _map_anyField_codec);
diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb
index 94ff381705..69950675d8 100644
Binary files a/csharp/src/Google.Protobuf.Test/testprotos.pb and b/csharp/src/Google.Protobuf.Test/testprotos.pb differ
diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs
index 0a829545e2..0428fb54e6 100644
--- a/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -373,7 +373,7 @@ namespace Google.Protobuf
if (IsAtEnd)
{
lastTag = 0;
- return 0; // This is the only case in which we return 0.
+ return 0;
}
lastTag = ReadRawVarint32();
@@ -383,6 +383,10 @@ namespace Google.Protobuf
// If we actually read a tag with a field of 0, that's not a valid tag.
throw InvalidProtocolBufferException.InvalidTag();
}
+ if (ReachedLimit)
+ {
+ return 0;
+ }
return lastTag;
}
@@ -591,6 +595,20 @@ namespace Google.Protobuf
PopLimit(oldLimit);
}
+ ///
+ /// Reads an embedded group field from the stream.
+ ///
+ public void ReadGroup(IMessage builder)
+ {
+ if (recursionDepth >= recursionLimit)
+ {
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ }
+ ++recursionDepth;
+ builder.MergeFrom(this);
+ --recursionDepth;
+ }
+
///
/// Reads a bytes field value from the stream.
///
diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs
index 6211aac32c..f9ad29086b 100644
--- a/csharp/src/Google.Protobuf/CodedOutputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs
@@ -303,6 +303,15 @@ namespace Google.Protobuf
value.WriteTo(this);
}
+ ///
+ /// Writes a group, without a tag, to the stream.
+ ///
+ /// The value to write
+ public void WriteGroup(IMessage value)
+ {
+ value.WriteTo(this);
+ }
+
///
/// Write a byte string, without a tag, to the stream.
/// The data is length-prefixed.
diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
index 613ca9c48e..827bc71183 100644
--- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
+++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
@@ -208,6 +208,10 @@ namespace Google.Protobuf.Collections
{
output.WriteTag(tag);
writer(output, array[i]);
+ if (codec.EndTag != 0)
+ {
+ output.WriteTag(codec.EndTag);
+ }
}
}
}
diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs
index a11f2420e3..221ad5fd2d 100644
--- a/csharp/src/Google.Protobuf/FieldCodec.cs
+++ b/csharp/src/Google.Protobuf/FieldCodec.cs
@@ -225,6 +225,19 @@ namespace Google.Protobuf
(output, value) => output.WriteMessage(value), message => CodedOutputStream.ComputeMessageSize(message), tag);
}
+ ///
+ /// Retrieves a codec suitable for a group field with the given tag.
+ ///
+ /// The start group tag.
+ /// The end group tag.
+ /// A parser to use for the group message type.
+ /// A codec for given tag
+ public static FieldCodec ForGroup(uint startTag, uint endTag, MessageParser parser) where T : IMessage
+ {
+ return new FieldCodec(input => { T message = parser.CreateTemplate(); input.ReadGroup(message); return message; },
+ (output, value) => output.WriteGroup(value), message => CodedOutputStream.ComputeGroupSize(message), startTag, endTag);
+ }
+
///
/// Creates a codec for a wrapper type of a class - which must be string or ByteString.
///
@@ -235,7 +248,7 @@ namespace Google.Protobuf
input => WrapperCodecs.Read(input, nestedCodec),
(output, value) => WrapperCodecs.Write(output, value, nestedCodec),
value => WrapperCodecs.CalculateSize(value, nestedCodec),
- tag,
+ tag, 0,
null); // Default value for the wrapper
}
@@ -250,7 +263,7 @@ namespace Google.Protobuf
input => WrapperCodecs.Read(input, nestedCodec),
(output, value) => WrapperCodecs.Write(output, value.Value, nestedCodec),
value => value == null ? 0 : WrapperCodecs.CalculateSize(value.Value, nestedCodec),
- tag,
+ tag, 0,
null); // Default value for the wrapper
}
@@ -399,6 +412,14 @@ namespace Google.Protobuf
///
internal uint Tag { get; }
+ ///
+ /// Gets the end tag of the codec or 0 if there is no end tag
+ ///
+ ///
+ /// The end tag of the codec.
+ ///
+ internal uint EndTag { get; }
+
///
/// Default value for this codec. Usually the same for every instance of the same type, but
/// for string/ByteString wrapper fields the codec's default value is null, whereas for
@@ -424,7 +445,8 @@ namespace Google.Protobuf
Func reader,
Action writer,
Func sizeCalculator,
- uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault)
+ uint tag,
+ uint endTag = 0) : this(reader, writer, sizeCalculator, tag, endTag, DefaultDefault)
{
}
@@ -433,6 +455,7 @@ namespace Google.Protobuf
Action writer,
Func sizeCalculator,
uint tag,
+ uint endTag,
T defaultValue)
{
ValueReader = reader;
@@ -455,6 +478,10 @@ namespace Google.Protobuf
{
output.WriteTag(Tag);
ValueWriter(output, value);
+ if (EndTag != 0)
+ {
+ output.WriteTag(EndTag);
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index 0c33e63df4..f101cd3526 100644
--- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -302,7 +302,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
file_.AddEntriesFrom(input, _repeated_file_codec);
@@ -733,7 +735,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -1098,7 +1102,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -1357,7 +1363,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Start = input.ReadInt32();
@@ -1560,7 +1568,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Start = input.ReadInt32();
@@ -1693,7 +1703,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 7994: {
uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
@@ -2200,7 +2212,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -2487,7 +2501,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -2732,7 +2748,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -2948,7 +2966,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Start = input.ReadInt32();
@@ -3177,7 +3197,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -3385,7 +3407,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -3735,7 +3759,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -6923,7 +6949,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 18: {
name_.AddEntriesFrom(input, _repeated_name_codec);
@@ -7136,7 +7164,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
NamePart_ = input.ReadString();
@@ -7315,7 +7345,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
location_.AddEntriesFrom(input, _repeated_location_codec);
@@ -7623,7 +7655,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10:
case 8: {
@@ -7776,7 +7810,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
annotation_.AddEntriesFrom(input, _repeated_annotation_codec);
@@ -8027,7 +8063,9 @@ namespace Google.Protobuf.Reflection {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10:
case 8: {
diff --git a/csharp/src/Google.Protobuf/UnknownField.cs b/csharp/src/Google.Protobuf/UnknownField.cs
index 0d6eed6357..2b13fdb3ec 100644
--- a/csharp/src/Google.Protobuf/UnknownField.cs
+++ b/csharp/src/Google.Protobuf/UnknownField.cs
@@ -55,6 +55,7 @@ namespace Google.Protobuf
private List fixed32List;
private List fixed64List;
private List lengthDelimitedList;
+ private List groupList;
///
/// Creates a new UnknownField.
@@ -77,7 +78,8 @@ namespace Google.Protobuf
&& Lists.Equals(varintList, otherField.varintList)
&& Lists.Equals(fixed32List, otherField.fixed32List)
&& Lists.Equals(fixed64List, otherField.fixed64List)
- && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList);
+ && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList)
+ && Lists.Equals(groupList, otherField.groupList);
}
///
@@ -90,6 +92,7 @@ namespace Google.Protobuf
hash = hash * 47 + Lists.GetHashCode(fixed32List);
hash = hash * 47 + Lists.GetHashCode(fixed64List);
hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList);
+ hash = hash * 47 + Lists.GetHashCode(groupList);
return hash;
}
@@ -133,6 +136,15 @@ namespace Google.Protobuf
output.WriteBytes(value);
}
}
+ if (groupList != null)
+ {
+ foreach (UnknownFieldSet value in groupList)
+ {
+ output.WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
+ value.WriteTo(output);
+ output.WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
+ }
+ }
}
///
@@ -168,6 +180,14 @@ namespace Google.Protobuf
result += CodedOutputStream.ComputeBytesSize(value);
}
}
+ if (groupList != null)
+ {
+ result += CodedOutputStream.ComputeTagSize(fieldNumber) * 2 * groupList.Count;
+ foreach (UnknownFieldSet value in groupList)
+ {
+ result += value.CalculateSize();
+ }
+ }
return result;
}
@@ -182,6 +202,7 @@ namespace Google.Protobuf
fixed32List = AddAll(fixed32List, other.fixed32List);
fixed64List = AddAll(fixed64List, other.fixed64List);
lengthDelimitedList = AddAll(lengthDelimitedList, other.lengthDelimitedList);
+ groupList = AddAll(groupList, other.groupList);
return this;
}
@@ -245,6 +266,12 @@ namespace Google.Protobuf
return this;
}
+ internal UnknownField AddGroup(UnknownFieldSet value)
+ {
+ groupList = Add(groupList, value);
+ return this;
+ }
+
///
/// Adds to the , creating
/// a new list if is null. The list is returned - either
diff --git a/csharp/src/Google.Protobuf/UnknownFieldSet.cs b/csharp/src/Google.Protobuf/UnknownFieldSet.cs
index 6404c3c08f..9121567621 100644
--- a/csharp/src/Google.Protobuf/UnknownFieldSet.cs
+++ b/csharp/src/Google.Protobuf/UnknownFieldSet.cs
@@ -183,7 +183,7 @@ namespace Google.Protobuf
///
/// The coded input stream containing the field
/// false if the tag is an "end group" tag, true otherwise
- private void MergeFieldFrom(CodedInputStream input)
+ private bool MergeFieldFrom(CodedInputStream input)
{
uint tag = input.LastTag;
int number = WireFormat.GetTagFieldNumber(tag);
@@ -193,34 +193,40 @@ namespace Google.Protobuf
{
ulong uint64 = input.ReadUInt64();
GetOrAddField(number).AddVarint(uint64);
- return;
+ return true;
}
case WireFormat.WireType.Fixed32:
{
uint uint32 = input.ReadFixed32();
GetOrAddField(number).AddFixed32(uint32);
- return;
+ return true;
}
case WireFormat.WireType.Fixed64:
{
ulong uint64 = input.ReadFixed64();
GetOrAddField(number).AddFixed64(uint64);
- return;
+ return true;
}
case WireFormat.WireType.LengthDelimited:
{
ByteString bytes = input.ReadBytes();
GetOrAddField(number).AddLengthDelimited(bytes);
- return;
+ return true;
}
case WireFormat.WireType.StartGroup:
{
- input.SkipGroup(tag);
- return;
+ uint endTag = WireFormat.MakeTag(number, WireFormat.WireType.EndGroup);
+ UnknownFieldSet set = new UnknownFieldSet();
+ while (input.ReadTag() != endTag)
+ {
+ set.MergeFieldFrom(input);
+ }
+ GetOrAddField(number).AddGroup(set);
+ return true;
}
case WireFormat.WireType.EndGroup:
{
- throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing.");
+ return false;
}
default:
throw new InvalidOperationException("Wire Type is invalid.");
@@ -248,8 +254,34 @@ namespace Google.Protobuf
{
unknownFields = new UnknownFieldSet();
}
- unknownFields.MergeFieldFrom(input);
+ if (!unknownFields.MergeFieldFrom(input))
+ {
+ throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); // match the old code-gen
+ }
return unknownFields;
+ }
+
+ ///
+ /// Create a new UnknownFieldSet if unknownFields is null.
+ /// Parse a single field from and merge it
+ /// into unknownFields. If is configured to discard unknown fields,
+ /// will be returned as-is and the field will be skipped.
+ ///
+ /// The UnknownFieldSet which need to be merged
+ /// The coded input stream containing the field
+ /// The merged UnknownFieldSet
+ public static bool MergeFieldFrom(ref UnknownFieldSet unknownFields, CodedInputStream input)
+ {
+ if (input.DiscardUnknownFields)
+ {
+ input.SkipLastField();
+ return true;
+ }
+ if (unknownFields == null)
+ {
+ unknownFields = new UnknownFieldSet();
+ }
+ return unknownFields.MergeFieldFrom(input);
}
///
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
index dd9911067e..b1ed0bc307 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
@@ -292,7 +292,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
TypeUrl = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
index 438e1db8da..a566e40640 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
@@ -345,7 +345,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -661,7 +663,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -925,7 +929,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
index 2858b532b6..691ca334ea 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
@@ -254,7 +254,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Seconds = input.ReadInt64();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
index 2113add9bc..03ffc4a057 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
@@ -143,7 +143,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index 6ad31a50ea..8114aa3924 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -352,7 +352,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
paths_.AddEntriesFrom(input, _repeated_paths_codec);
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
index 124ddaa712..2cae68631d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
@@ -165,7 +165,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
FileName = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
index 194b81e965..9667472522 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
@@ -189,7 +189,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
fields_.AddEntriesFrom(input, _map_fields_codec);
@@ -513,7 +515,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
kind_ = input.ReadEnum();
@@ -673,7 +677,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
values_.AddEntriesFrom(input, _repeated_values_codec);
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index 984e226fd4..9e37e9dda7 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -273,7 +273,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Seconds = input.ReadInt64();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
index 52bd343ba8..adea910634 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
@@ -328,7 +328,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -723,7 +725,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Kind = (global::Google.Protobuf.WellKnownTypes.Field.Types.Kind) input.ReadEnum();
@@ -1100,7 +1104,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -1300,7 +1306,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
@@ -1480,7 +1488,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Name = input.ReadString();
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
index 25a65aa72c..679eb0f234 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
@@ -177,7 +177,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 9: {
Value = input.ReadDouble();
@@ -314,7 +316,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 13: {
Value = input.ReadFloat();
@@ -451,7 +455,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = input.ReadInt64();
@@ -588,7 +594,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = input.ReadUInt64();
@@ -725,7 +733,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = input.ReadInt32();
@@ -862,7 +872,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = input.ReadUInt32();
@@ -999,7 +1011,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 8: {
Value = input.ReadBool();
@@ -1136,7 +1150,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Value = input.ReadString();
@@ -1273,7 +1289,9 @@ namespace Google.Protobuf.WellKnownTypes {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+ if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {
+ return;
+ }
break;
case 10: {
Value = input.ReadBytes();
diff --git a/docs/third_party.md b/docs/third_party.md
index 49db21b7a2..a2bb0342be 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -170,3 +170,4 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d
* [Make protoc plugins in NodeJS](https://github.com/konsumer/node-protoc-plugin)
* [ProfaneDB - A Protocol Buffers database](https://profanedb.gitlab.io)
* [Protocol Buffer property-based testing utility and example message generator (Python / Hypothesis)](https://github.com/CurataEng/hypothesis-protobuf)
+* [Protolock - CLI utility to prevent backward-incompatible changes to .proto files](https://github.com/nilslice/protolock)
diff --git a/examples/Makefile b/examples/Makefile
index 1ff7fa7fc5..4ad605641d 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -5,6 +5,7 @@
all: cpp java python
cpp: add_person_cpp list_people_cpp
+dart: add_person_dart list_people_dart
go: add_person_go list_people_go
gotest: add_person_gotest list_people_gotest
java: add_person_java list_people_java
@@ -16,6 +17,8 @@ clean:
rm -f protoc_middleman addressbook.pb.cc addressbook.pb.h addressbook_pb2.py com/example/tutorial/AddressBookProtos.java
rm -f *.pyc
rm -f protoc_middleman_go tutorial/*.pb.go add_person_go list_people_go
+ rm -f protoc_middleman_dart dart_tutorial/*.pb*.dart
+ rmdir dart_tutorial 2>/dev/null || true
rmdir tutorial 2>/dev/null || true
rmdir com/example/tutorial 2>/dev/null || true
rmdir com/example 2>/dev/null || true
@@ -30,6 +33,12 @@ protoc_middleman_go: addressbook.proto
protoc $$PROTO_PATH --go_out=tutorial addressbook.proto
@touch protoc_middleman_go
+protoc_middleman_dart: addressbook.proto
+ mkdir -p dart_tutorial # make directory for the dart package
+ protoc -I ../src/:. --dart_out=dart_tutorial addressbook.proto ../src/google/protobuf/timestamp.proto
+ pub get
+ @touch protoc_middleman_dart
+
add_person_cpp: add_person.cc protoc_middleman
pkg-config --cflags protobuf # fails if protobuf is not installed
c++ add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf`
@@ -38,6 +47,10 @@ list_people_cpp: list_people.cc protoc_middleman
pkg-config --cflags protobuf # fails if protobuf is not installed
c++ list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf`
+add_person_dart: add_person.dart protoc_middleman_dart
+
+list_people_dart: list_people.dart protoc_middleman_dart
+
add_person_go: add_person.go protoc_middleman_go
go build -o add_person_go add_person.go
diff --git a/examples/README.md b/examples/README.md
index 20f285cdd7..3eb63527b7 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -119,6 +119,26 @@ is created if it does not exist. To view the data, run:
./list_people_go addressbook.data
-Observe that the C++, Python, and Java examples in this directory run in a
+Observe that the C++, Python, Java, and Dart examples in this directory run in a
similar way and can view/modify files created by the Go example and vice
versa.
+
+### Dart
+
+First, follow the instructions in [../README.md](../README.md) to install the Protocol Buffer Compiler (protoc).
+
+Then, install the Dart Protocol Buffer plugin as described [here](https://github.com/dart-lang/dart-protoc-plugin#how-to-build-and-use).
+Note, the executable `bin/protoc-gen-dart` must be in your `PATH` for `protoc` to find it.
+
+Build the Dart samples in this directory with `make dart`.
+
+To run the examples:
+
+```sh
+$ dart add_person.dart addessbook.data
+$ dart list_people.dart addressbook.data
+```
+
+The two programs take a protocol buffer encoded file as their parameter.
+The first can be used to add a person to the file. The file is created
+if it does not exist. The second displays the data in the file.
diff --git a/examples/add_person.dart b/examples/add_person.dart
new file mode 100644
index 0000000000..a93ec60540
--- /dev/null
+++ b/examples/add_person.dart
@@ -0,0 +1,70 @@
+import 'dart:io';
+
+import 'dart_tutorial/addressbook.pb.dart';
+
+// This function fills in a Person message based on user input.
+Person promtForAddress() {
+ Person person = Person();
+
+ print('Enter person ID: ');
+ String input = stdin.readLineSync();
+ person.id = int.parse(input);
+
+ print('Enter name');
+ person.name = stdin.readLineSync();
+
+ print('Enter email address (blank for none) : ');
+ String email = stdin.readLineSync();
+ if (email.isNotEmpty) {
+ person.email = email;
+ }
+
+ while (true) {
+ print('Enter a phone number (or leave blank to finish): ');
+ String number = stdin.readLineSync();
+ if (number.isEmpty) break;
+
+ Person_PhoneNumber phoneNumber = Person_PhoneNumber();
+
+ phoneNumber.number = number;
+ print('Is this a mobile, home, or work phone? ');
+
+ String type = stdin.readLineSync();
+ switch (type) {
+ case 'mobile':
+ phoneNumber.type = Person_PhoneType.MOBILE;
+ break;
+ case 'home':
+ phoneNumber.type = Person_PhoneType.HOME;
+ break;
+ case 'work':
+ phoneNumber.type = Person_PhoneType.WORK;
+ break;
+ default:
+ print('Unknown phone type. Using default.');
+ }
+ person.phones.add(phoneNumber);
+ }
+
+ return person;
+}
+
+// Reads the entire address book from a file, adds one person based
+// on user input, then writes it back out to the same file.
+main(List arguments) {
+ if (arguments.length != 1) {
+ print('Usage: add_person ADDRESS_BOOK_FILE');
+ exit(-1);
+ }
+
+ File file = File(arguments.first);
+ AddressBook addressBook;
+ if (!file.existsSync()) {
+ print('File not found. Creating new file.');
+ addressBook = AddressBook();
+ } else {
+ addressBook = AddressBook.fromBuffer(file.readAsBytesSync());
+ }
+ addressBook.people.add(promtForAddress());
+ file.writeAsBytes(addressBook.writeToBuffer());
+}
diff --git a/examples/list_people.dart b/examples/list_people.dart
new file mode 100644
index 0000000000..dd5bb41005
--- /dev/null
+++ b/examples/list_people.dart
@@ -0,0 +1,47 @@
+import 'dart:io';
+
+import 'dart_tutorial/addressbook.pb.dart';
+import 'dart_tutorial/addressbook.pbenum.dart';
+
+// Iterates though all people in the AddressBook and prints info about them.
+void printAddressBook(AddressBook addressBook) {
+ for (Person person in addressBook.people) {
+ print('Person ID: ${person.id}');
+ print(' Name: ${person.name}');
+ if (person.hasEmail()) {
+ print(' E-mail address:${person.email}');
+ }
+
+ for (Person_PhoneNumber phoneNumber in person.phones) {
+ switch (phoneNumber.type) {
+ case Person_PhoneType.MOBILE:
+ print(' Mobile phone #: ');
+ break;
+ case Person_PhoneType.HOME:
+ print(' Home phone #: ');
+ break;
+ case Person_PhoneType.WORK:
+ print(' Work phone #: ');
+ break;
+ default:
+ print(' Unknown phone #: ');
+ break;
+ }
+ print(phoneNumber.number);
+ }
+ }
+}
+
+// Reads the entire address book from a file and prints all
+// the information inside.
+main(List arguments) {
+ if (arguments.length != 1) {
+ print('Usage: list_person ADDRESS_BOOK_FILE');
+ exit(-1);
+ }
+
+ // Read the existing address book.
+ File file = new File(arguments.first);
+ AddressBook addressBook = new AddressBook.fromBuffer(file.readAsBytesSync());
+ printAddressBook(addressBook);
+}
diff --git a/examples/pubspec.yaml b/examples/pubspec.yaml
new file mode 100644
index 0000000000..0c36dbdcd3
--- /dev/null
+++ b/examples/pubspec.yaml
@@ -0,0 +1,5 @@
+name: addressbook
+description: dartlang.org example code.
+
+dependencies:
+ protobuf:
diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh
index 6d0a5588c9..ea2d6fee8c 100755
--- a/objectivec/DevTools/full_mac_build.sh
+++ b/objectivec/DevTools/full_mac_build.sh
@@ -239,27 +239,11 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
# just pick a mix of OS Versions and 32/64 bit.
# NOTE: Different Xcode have different simulated hardware/os support.
case "${XCODE_VERSION}" in
- 6.* )
- echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 8.0 or higher." 1>&2
- exit 10
- ;;
- 7.* )
- echo "ERROR: Xcode 7.x no longer supported for building, please use 8.0 or higher." 1>&2
+ [6-8].* )
+ echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2
+ echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
exit 11
;;
- 8.0* )
- # The 8.* device seem to hang and never start under Xcode 8.
- XCODEBUILD_TEST_BASE_IOS+=(
- -destination "platform=iOS Simulator,name=iPhone 4s,OS=9.0" # 32bit
- -destination "platform=iOS Simulator,name=iPhone 7,OS=10.0" # 64bit
- )
- ;;
- 8.[1-3]* )
- XCODEBUILD_TEST_BASE_IOS+=(
- -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
- -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
- )
- ;;
9.[0-2]* )
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
@@ -317,13 +301,9 @@ if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
XCODEBUILD_TEST_BASE_OSX+=( -quiet )
fi
case "${XCODE_VERSION}" in
- 6.* )
- echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 8.0 or higher." 1>&2
- exit 10
- ;;
- 7.* )
- echo "ERROR: The unittests include Swift code that is now Swift 3.0." 1>&2
- echo "ERROR: Xcode 8.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
+ [6-8].* )
+ echo "ERROR: The unittests include Swift code that is now Swift 4.0." 1>&2
+ echo "ERROR: Xcode 9.0 or higher is required to build the test suite, but the library works with Xcode 7.x." 1>&2
exit 11
;;
esac
diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m
index ad46ef4f03..a349f87b99 100644
--- a/objectivec/GPBDescriptor.m
+++ b/objectivec/GPBDescriptor.m
@@ -819,6 +819,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
return;
}
uint32_t *offsets = malloc(valueCount_ * sizeof(uint32_t));
+ if (!offsets) return;
const char *scan = valueNames_;
for (uint32_t i = 0; i < valueCount_; ++i) {
offsets[i] = (uint32_t)(scan - valueNames_);
@@ -851,6 +852,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
nameAsCStr += prefixLen;
if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+ if (nameOffsets_ == NULL) return NO;
// Find it.
for (uint32_t i = 0; i < valueCount_; ++i) {
@@ -867,6 +869,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
- (BOOL)getValue:(int32_t *)outValue forEnumTextFormatName:(NSString *)textFormatName {
if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+ if (nameOffsets_ == NULL) return NO;
for (uint32_t i = 0; i < valueCount_; ++i) {
int32_t value = values_[i];
@@ -905,6 +908,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
- (NSString *)getEnumNameForIndex:(uint32_t)index {
if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+ if (nameOffsets_ == NULL) return nil;
if (index >= valueCount_) {
return nil;
@@ -916,6 +920,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
- (NSString *)getEnumTextFormatNameForIndex:(uint32_t)index {
if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+ if (nameOffsets_ == NULL) return nil;
if (index >= valueCount_) {
return nil;
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
index faf562ba45..556bb2c46e 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
@@ -640,7 +640,7 @@
LastUpgradeCheck = 0930;
TargetAttributes = {
8BBEA4A5147C727100C4ADB7 = {
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 0940;
TestTargetID = 8B9A5EA41831993600A9D33B;
};
F45BBC141B0CE3C6002D064D = {
@@ -852,7 +852,7 @@
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
@@ -878,7 +878,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
WARNING_CFLAGS = (
"$(inherited)",
"-Wno-documentation-unknown-command",
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
index 3847bcc80d..940802a8dc 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
@@ -647,7 +647,7 @@
LastUpgradeCheck = 0930;
TargetAttributes = {
8BBEA4A5147C727100C4ADB7 = {
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 0940;
TestTargetID = 8B9A5EA41831993600A9D33B;
};
F45BBC0E1B0CDB50002D064D = {
@@ -866,7 +866,7 @@
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
WARNING_CFLAGS = (
"$(inherited)",
@@ -900,7 +900,7 @@
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
WARNING_CFLAGS = (
"$(inherited)",
diff --git a/objectivec/Tests/GPBMessageTests.m b/objectivec/Tests/GPBMessageTests.m
index 8ebbe6ded8..caf206f378 100644
--- a/objectivec/Tests/GPBMessageTests.m
+++ b/objectivec/Tests/GPBMessageTests.m
@@ -1980,6 +1980,51 @@
EnumTestMsg_MyEnum_NegTwo);
}
+- (void)testReservedWordNaming {
+ // objectivec_helpers.cc has some special handing to make sure that
+ // some "reserved" objc names get renamed in a way so they
+ // don't conflict.
+ //
+ // This "test" confirms that the expected names are generated,
+ // otherwise the test itself will fail to compile.
+ self_Class *msg = [self_Class message];
+
+ // Some ObjC/C/C++ keywords.
+ msg.className_p = msg.hasClassName_p;
+ msg.cmd = msg.hasCmd;
+ msg.nullable_p = msg.hasNullable_p;
+ msg.typeof_p = msg.hasTypeof_p;
+ msg.instancetype_p = msg.hasInstancetype_p;
+ msg.nil_p = msg.hasNil_p;
+ msg.instancetype_p = msg.hasInstancetype_p;
+ msg.public_p = msg.hasPublic_p;
+
+ // Some that would override NSObject methods
+ msg.camltype = msg.hasCamltype;
+ msg.isNsdictionary = msg.hasIsNsdictionary;
+ msg.dealloc_p = msg.hasDealloc_p;
+ msg.zone_p = msg.hasZone_p;
+ msg.accessibilityLabel_p = msg.hasAccessibilityLabel_p;
+
+ // Some that we shouldn't need to handle.
+ msg.atomic = msg.hasAtomic;
+ msg.nonatomic = msg.hasNonatomic;
+ msg.strong = msg.hasStrong;
+ msg.nullResettable = msg.hasNullResettable;
+
+ // Some that would override GPBMessage methods
+ msg.clear_p = msg.hasClear_p;
+ msg.data_p = msg.hasData_p;
+
+ // Some MacTypes
+ msg.fixed = msg.hasFixed;
+ msg.style = msg.hasStyle;
+
+ // Some C Identifiers
+ msg.generic = msg.hasGeneric;
+ msg.block = msg.hasBlock;
+}
+
- (void)testOneBasedEnumHolder {
// Test case for https://github.com/protocolbuffers/protobuf/issues/1453
// Message with no explicit defaults, but a non zero default for an enum.
diff --git a/objectivec/Tests/unittest_objc.proto b/objectivec/Tests/unittest_objc.proto
index 2202e6ca5d..b0ab8d8991 100644
--- a/objectivec/Tests/unittest_objc.proto
+++ b/objectivec/Tests/unittest_objc.proto
@@ -103,37 +103,89 @@ message self {
}
// Singular
- optional bool id = 1;
- optional bool _cmd = 2;
- optional bool in = 3;
- optional bool out = 4;
- optional bool inout = 5;
- optional bool bycopy = 6;
- optional bool byref = 7;
- optional bool oneway = 8;
- optional bool dealloc = 9;
- optional bool zone = 10;
- optional bool isProxy = 11;
- optional bool copy = 12;
- optional bool readonly = 13;
- optional bool default = 14;
- optional bool assign = 15;
- optional bool getter = 16;
- optional bool setter = 17;
- optional bool weak = 18;
- optional bool public = 19;
- optional bool case = 20;
-
- optional autorelease SubEnum = 25;
-
- optional group New = 50 {
- optional string copy = 51;
- }
- optional group MutableCopy = 60 {
- optional int32 extensionRegistry = 61;
+ // Objective C Keywords
+ optional bool id = 1;
+ optional bool _cmd = 2;
+ // super is used as submessage above
+ optional bool in = 4;
+ optional bool out = 5;
+ optional bool inout = 6;
+ optional bool bycopy = 7;
+ optional bool byref = 8;
+ optional bool oneway = 9;
+ optional bool self = 10;
+ optional bool instancetype = 11;
+ optional bool nullable = 12;
+ optional bool nonnull = 13;
+ optional bool nil = 14;
+ // Nil and nil can't be in the same message
+ optional bool YES = 16;
+ optional bool NO = 17;
+ optional bool weak = 18;
+
+ // Some C/C++ Keywords
+ optional bool case = 30;
+ optional bool if = 31;
+ optional bool and_eq = 32;
+ optional bool public = 33;
+ optional bool private = 34;
+ optional bool typename = 35;
+ optional bool static_cast = 36;
+ optional bool typeof = 37;
+ optional bool restrict = 38;
+ optional bool NULL = 39;
+
+ // Some NSObject Methods
+ optional bool dealloc = 110;
+ optional bool isProxy = 111;
+ optional bool copy = 112;
+ optional bool description = 113;
+ optional bool zone = 114;
+ optional bool className = 115;
+ optional bool __retain_OA = 116;
+ optional bool CAMLType = 117;
+ optional bool isNSDictionary__ = 118;
+ optional bool accessibilityLabel = 119;
+
+ // Some Objc "keywords" that we shouldn't
+ // have to worry about because they
+ // can only appear in specialized areas.
+ optional bool assign = 200;
+ optional bool getter = 201;
+ optional bool setter = 202;
+ optional bool atomic = 203;
+ optional bool nonatomic = 204;
+ optional bool strong = 205;
+ optional bool null_resettable = 206;
+ optional bool readonly = 207;
+
+ // Some GPBMessage methods
+ optional bool clear = 300;
+ optional bool data = 301;
+ optional bool descriptor = 302;
+ optional bool delimitedData = 303;
+
+ // Some MacTypes
+ optional bool Fixed = 400;
+ optional bool Point = 401;
+ optional bool FixedPoint = 402;
+ optional bool Style = 403;
+
+ // C/C++ reserved identifiers
+ optional bool _Generic = 500;
+ optional bool __block = 501;
+
+ // Try a keyword as a type
+ optional autorelease SubEnum = 1000;
+
+ optional group New = 2000 {
+ optional string copy = 1;
+ }
+ optional group MutableCopy = 2001 {
+ optional int32 extensionRegistry = 1;
}
- extensions 90 to 94;
+ extensions 3000 to 3999;
}
@@ -177,11 +229,11 @@ enum Time {
}
extend self {
- repeated int32 debugDescription = 90 [packed = true];
- repeated int64 finalize = 91 [packed = true];
- repeated uint32 hash = 92 [packed = true];
- repeated uint64 classForCoder = 93 [packed = true];
- repeated sint32 byref = 94 [packed = true];
+ repeated int32 debugDescription = 3000 [packed = true];
+ repeated int64 finalize = 3001 [packed = true];
+ repeated uint32 hash = 3002 [packed = true];
+ repeated uint64 classForCoder = 3003 [packed = true];
+ repeated sint32 byref = 3004 [packed = true];
}
// Test handing of fields that start with init* since Xcode 5's ARC support
diff --git a/src/Makefile.am b/src/Makefile.am
index 5f075d9925..ddaeee27e3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -424,6 +424,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/objectivec/objectivec_message.h \
google/protobuf/compiler/objectivec/objectivec_message_field.cc \
google/protobuf/compiler/objectivec/objectivec_message_field.h \
+ google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h \
google/protobuf/compiler/objectivec/objectivec_oneof.cc \
google/protobuf/compiler/objectivec/objectivec_oneof.h \
google/protobuf/compiler/objectivec/objectivec_primitive_field.cc \
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index 124e673b35..be1cd115a5 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -539,7 +539,9 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
} else {
printer->Print(
"default:\n"
- " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n"
+ " if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {\n"
+ " return;\n"
+ " }\n"
" break;\n");
}
for (int i = 0; i < fields_by_number().size(); i++) {
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
index 1671460367..899cd7bf7b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
@@ -37,6 +37,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -56,6 +58,21 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
variables_["has_property_check"] = name() + "_ != null";
variables_["has_not_property_check"] = name() + "_ == null";
}
+
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_GROUP) {
+ int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()) / 2;
+ uint tag = internal::WireFormatLite::MakeTag(
+ descriptor_->number(),
+ internal::WireFormatLite::WIRETYPE_END_GROUP);
+ uint8 tag_array[5];
+ io::CodedOutputStream::WriteTagToArray(tag, tag_array);
+ string tag_bytes = SimpleItoa(tag_array[0]);
+ for (int i = 1; i < tag_size; i++) {
+ tag_bytes += ", " + SimpleItoa(tag_array[i]);
+ }
+ variables_["end_tag"] = SimpleItoa(tag);
+ variables_["end_tag_bytes"] = tag_bytes;
+ }
}
MessageFieldGenerator::~MessageFieldGenerator() {
@@ -114,25 +131,47 @@ void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
variables_,
"if ($has_not_property_check$) {\n"
" $property_name$ = new $type_name$();\n"
- "}\n"
- "input.ReadMessage($property_name$);\n");
+ "}\n");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(variables_, "input.ReadMessage($property_name$);\n");
+ } else {
+ printer->Print(variables_, "input.ReadGroup($property_name$);\n");
+ }
}
void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
- printer->Print(
- variables_,
- "if ($has_property_check$) {\n"
- " output.WriteRawTag($tag_bytes$);\n"
- " output.WriteMessage($property_name$);\n"
- "}\n");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.WriteMessage($property_name$);\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " output.WriteRawTag($tag_bytes$);\n"
+ " output.WriteGroup($property_name$);\n"
+ " output.WriteRawTag($end_tag_bytes$);\n"
+ "}\n");
+ }
}
void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
- printer->Print(
- variables_,
- "if ($has_property_check$) {\n"
- " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n"
- "}\n");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n"
+ "}\n");
+ } else {
+ printer->Print(
+ variables_,
+ "if ($has_property_check$) {\n"
+ " size += $tag_size$ + $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n"
+ "}\n");
+ }
}
void MessageFieldGenerator::WriteHash(io::Printer* printer) {
@@ -160,9 +199,15 @@ void MessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) {
}
void MessageFieldGenerator::GenerateCodecCode(io::Printer* printer) {
- printer->Print(
- variables_,
- "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)");
+ } else {
+ printer->Print(
+ variables_,
+ "pb::FieldCodec.ForGroup($tag$, $end_tag$, $type_name$.Parser)");
+ }
}
MessageOneofFieldGenerator::MessageOneofFieldGenerator(
@@ -228,9 +273,13 @@ void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
"$type_name$ subBuilder = new $type_name$();\n"
"if ($has_property_check$) {\n"
" subBuilder.MergeFrom($property_name$);\n"
- "}\n"
- "input.ReadMessage(subBuilder);\n"
- "$property_name$ = subBuilder;\n");
+ "}\n");
+ if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) {
+ printer->Print("input.ReadMessage(subBuilder);\n");
+ } else {
+ printer->Print("input.ReadGroup(subBuilder);\n");
+ }
+ printer->Print(variables_, "$property_name$ = subBuilder;\n");
}
void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/objectivec/method_dump.sh b/src/google/protobuf/compiler/objectivec/method_dump.sh
new file mode 100755
index 0000000000..193825dbc1
--- /dev/null
+++ b/src/google/protobuf/compiler/objectivec/method_dump.sh
@@ -0,0 +1,179 @@
+#!/bin/bash
+
+# Updates objectivec_nsobject_methods.h by generating a list of all of the properties
+# and methods on NSObject that Protobufs should not overload from iOS and macOS combined.
+#
+# The rules:
+# - No property should ever be overloaded.
+# - Do not overload any methods that have 0 args such as "autorelease".
+# - Do not overload any methods that start with "set[A-Z]" and have 1 arg such as
+# "setValuesForKeysWithDictionary:". Note that these will end up in the list as just
+# the "proto field" name, so "setValuesForKeysWithDictionary:" will become
+# "valuesForKeysWithDictionary".
+
+set -eu
+
+trim() {
+ local var="$*"
+ # remove leading whitespace characters
+ var="${var#"${var%%[![:space:]]*}"}"
+ # remove trailing whitespace characters
+ var="${var%"${var##*[![:space:]]}"}"
+ echo -n "$var"
+}
+
+objc_code=$(cat <<'END_CODE'
+#import
+#import
+
+int main(int argc, const char * argv[]) {
+ @autoreleasepool {
+ Class cls = [NSObject class];
+
+ // List out the protocols on NSObject just so we are aware if they change.
+ unsigned int protocolCount;
+ __unsafe_unretained Protocol **protocols =
+ class_copyProtocolList(cls, &protocolCount);
+ for (unsigned int i = 0; i < protocolCount; i++) {
+ printf("// Protocol: %s\n", protocol_getName(protocols[i]));
+ }
+ free(protocols);
+
+ // Grab all the properties.
+ unsigned int propCount;
+ objc_property_t *props = class_copyPropertyList(cls, &propCount);
+ NSMutableSet *reservedNames = [[NSMutableSet alloc] init];
+ for (unsigned int i = 0; i < propCount; ++i) {
+ NSString *propertyName = [NSString stringWithUTF8String:property_getName(props[i])];
+ [reservedNames addObject:propertyName];
+ }
+ free(props);
+
+ // Note that methods have 2 defaults args (_cmd and SEL) so a method "0 arg method"
+ // actually has 2.
+ unsigned int methodCount;
+ Method *methods = class_copyMethodList(cls, &methodCount);
+ for (unsigned int i = 0; i < methodCount; ++i) {
+ int argCount = method_getNumberOfArguments(methods[i]);
+ NSString *methodName =
+ [NSString stringWithUTF8String:sel_getName(method_getName(methods[i]))];
+ if (argCount == 2) {
+ [reservedNames addObject:methodName];
+ }
+ if (argCount == 3 && [methodName hasPrefix:@"set"] && methodName.length > 4) {
+ NSString *firstLetter = [methodName substringWithRange:NSMakeRange(3,1)];
+ NSString *lowerFirstLetter = [firstLetter lowercaseString];
+ if ([lowerFirstLetter isEqual:firstLetter]) {
+ // Make sure the next letter is a capital letter so we do not take things like
+ // settingSomething:
+ continue;
+ }
+ // -5 because 3 for set, 1 for the firstLetter and 1 for the colon on the end.
+ NSString *restOfString =
+ [methodName substringWithRange:NSMakeRange(4, methodName.length - 5)];
+ methodName = [lowerFirstLetter stringByAppendingString:restOfString];
+ [reservedNames addObject:methodName];
+ }
+ }
+ free(methods);
+
+ SEL sortSelector = @selector(caseInsensitiveCompare:);
+ NSArray *array = [reservedNames.allObjects sortedArrayUsingSelector:sortSelector];
+ for (NSString *item in array) {
+ // Some items with _ in them get returned in quotes, so do not add more.
+ if ([item hasPrefix:@"\""]) {
+ printf("\t%s,\n", item.UTF8String);
+ } else {
+ printf("\t\"%s\",\n", item.UTF8String);
+ }
+ }
+ }
+ return 0;
+}
+END_CODE
+)
+
+file_header=$(cat <<'END_HEADER'
+// NSObject methods
+// Autogenerated by method_dump.sh. Do not edit by hand.
+// Date: %DATE%
+// macOS: %MACOS%
+// iOS: %IOS%
+
+const char* const kNSObjectMethodsList[] = {
+END_HEADER
+)
+
+file_footer=$(cat <<'END_FOOTER'
+};
+END_FOOTER
+)
+
+# Check to make sure we are updating the correct file.
+if [[ ! -e "objectivec_nsobject_methods.h" ]]; then
+ echo "error: Must be run in the src/google/protobuf/compiler/objectivec directory"
+ exit 1
+fi
+
+temp_dir=$(mktemp -d)
+
+echo "$objc_code" >> "$temp_dir"/method_dump.m
+
+# Compile up iphonesimulator and macos version of cmd line app.
+iphone_simulator_sdk=$(xcrun --sdk iphonesimulator --show-sdk-path)
+clang -isysroot "$iphone_simulator_sdk" -o "$temp_dir"/method_dump_ios \
+ -framework Foundation -framework UIKit "$temp_dir"/method_dump.m
+macos_sdk=$(xcrun --sdk macosx --show-sdk-path)
+clang -isysroot "$macos_sdk" -o "$temp_dir"/method_dump_macos -framework Foundation \
+ -framework Cocoa "$temp_dir"/method_dump.m
+
+# Create a device of the latest phone and iphonesimulator SDK and run our iOS cmd line.
+device_type=$(xcrun simctl list devicetypes | grep \.iPhone- | tail -1 | sed 's/.*(\(.*\))/\1/')
+# runtimes come with a space at the end (for Xcode 10) so let's trim all of our input to
+# be safe.
+device_type=$(trim "$device_type")
+runtime=$(xcrun simctl list runtimes | grep \.iOS- | tail -1 | \
+ sed 's/.*\(com\.apple.\CoreSimulator\.SimRuntime\.iOS.*\)/\1/')
+runtime=$(trim "$runtime")
+uuid=$(uuidgen)
+device_name="method_dump_device_$uuid"
+device=$(xcrun simctl create "$device_name" "$device_type" "$runtime")
+xcrun simctl spawn "$device" "$temp_dir"/method_dump_ios > "$temp_dir"/methods_unsorted_ios.txt
+xcrun simctl delete "$device"
+
+# Run the Mac version
+"$temp_dir"/method_dump_macos >> "$temp_dir"/methods_unsorted_macos.txt
+
+# Generate sorted output
+echo "$file_header" | sed -e "s|%DATE%|$(date)|" -e "s|%MACOS%|$(basename $macos_sdk)|" \
+ -e "s|%IOS%|$(basename $iphone_simulator_sdk)|" > "$temp_dir"/methods_sorted.txt
+sort -u "$temp_dir"/methods_unsorted_ios.txt \
+ "$temp_dir"/methods_unsorted_macos.txt >> "$temp_dir"/methods_sorted.txt
+echo $"$file_footer" >> "$temp_dir"/methods_sorted.txt
+
+# Check for differences. Turn off error checking because we expect diff to fail when
+# there are no differences.
+set +e
+diff_out=$(diff -I "^//.*$" "$temp_dir"/methods_sorted.txt objectivec_nsobject_methods.h)
+removed_methods=$(echo "$diff_out" | grep '^>.*$')
+set -e
+if [[ -n "$removed_methods" ]]; then
+ echo "error: Methods removed from NSObject"
+ echo "It appears that some methods may have been removed from NSObject."
+ echo "This could mean that there may be some backwards compatibility issues."
+ echo "You could potentially build apps that may not work on earlier systems than:"
+ echo "$iphone_simulator_sdk"
+ echo "$macos_sdk"
+ echo "If they declare protobuf types that use any of the following as names:"
+ echo "$removed_methods"
+ echo ""
+ echo "New Version: $temp_dir/methods_sorted.txt"
+ echo "Old Version: objectivec_nsobject_methods.h"
+ exit 1
+fi
+if [[ -n "$diff_out" ]]; then
+ echo "Added Methods:"
+ echo "$(echo "$diff_out" | grep '^<.*$' | sed -e 's/^< "\(.*\)",$/ \1/')"
+fi;
+cp "$temp_dir"/methods_sorted.txt objectivec_nsobject_methods.h
+rm -rf "$temp_dir"
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 5357e94bba..a67840c042 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -43,6 +43,7 @@
#include
#include
+#include
#include
#include
#include
@@ -170,65 +171,90 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) {
}
const char* const kReservedWordList[] = {
- // Objective C "keywords" that aren't in C
- // From
- // http://stackoverflow.com/questions/1873630/reserved-keywords-in-objective-c
- "id", "_cmd", "super", "in", "out", "inout", "bycopy", "byref", "oneway",
- "self",
-
- // C/C++ keywords (Incl C++ 0x11)
- // From http://en.cppreference.com/w/cpp/keywords
- "and", "and_eq", "alignas", "alignof", "asm", "auto", "bitand", "bitor",
- "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
- "compl", "const", "constexpr", "const_cast", "continue", "decltype",
- "default", "delete", "double", "dynamic_cast", "else", "enum", "explicit",
- "export", "extern ", "false", "float", "for", "friend", "goto", "if",
- "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not",
- "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected",
- "public", "register", "reinterpret_cast", "return", "short", "signed",
- "sizeof", "static", "static_assert", "static_cast", "struct", "switch",
- "template", "this", "thread_local", "throw", "true", "try", "typedef",
- "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
- "volatile", "wchar_t", "while", "xor", "xor_eq",
-
- // C99 keywords
- // From
- // http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fkeyw.htm
- "restrict",
-
- // Objective-C Runtime typedefs
- // From
- "Category", "Ivar", "Method", "Protocol",
-
- // NSObject Methods
- // new is covered by C++ keywords.
- "description", "debugDescription", "finalize", "hash", "dealloc", "init",
- "class", "superclass", "retain", "release", "autorelease", "retainCount",
- "zone", "isProxy", "copy", "mutableCopy", "classForCoder",
-
- // GPBMessage Methods
- // Only need to add instance methods that may conflict with
- // method declared in protos. The main cases are methods
- // that take no arguments, or setFoo:/hasFoo: type methods.
- "clear", "data", "delimitedData", "descriptor", "extensionRegistry",
- "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize",
- "sortedExtensionsInUse", "unknownFields",
-
- // MacTypes.h names
- "Fixed", "Fract", "Size", "LogicalAddress", "PhysicalAddress", "ByteCount",
- "ByteOffset", "Duration", "AbsoluteTime", "OptionBits", "ItemCount",
- "PBVersion", "ScriptCode", "LangCode", "RegionCode", "OSType",
- "ProcessSerialNumber", "Point", "Rect", "FixedPoint", "FixedRect", "Style",
- "StyleParameter", "StyleField", "TimeScale", "TimeBase", "TimeRecord",
+ // Note NSObject Methods:
+ // These are brought in from objectivec_nsobject_methods.h that is generated
+ // using method_dump.sh. See kNSObjectMethods below.
+
+ // Objective C "keywords" that aren't in C
+ // From
+ // http://stackoverflow.com/questions/1873630/reserved-keywords-in-objective-c
+ // with some others added on.
+ "id", "_cmd", "super", "in", "out", "inout", "bycopy", "byref", "oneway",
+ "self", "instancetype", "nullable", "nonnull", "nil", "Nil",
+ "YES", "NO", "weak",
+
+ // C/C++ keywords (Incl C++ 0x11)
+ // From http://en.cppreference.com/w/cpp/keywords
+ "and", "and_eq", "alignas", "alignof", "asm", "auto", "bitand", "bitor",
+ "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
+ "compl", "const", "constexpr", "const_cast", "continue", "decltype",
+ "default", "delete", "double", "dynamic_cast", "else", "enum", "explicit",
+ "export", "extern ", "false", "float", "for", "friend", "goto", "if",
+ "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not",
+ "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected",
+ "public", "register", "reinterpret_cast", "return", "short", "signed",
+ "sizeof", "static", "static_assert", "static_cast", "struct", "switch",
+ "template", "this", "thread_local", "throw", "true", "try", "typedef",
+ "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
+ "volatile", "wchar_t", "while", "xor", "xor_eq",
+
+ // C99 keywords
+ // From
+ // http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fkeyw.htm
+ "restrict",
+
+ // GCC/Clang extension
+ "typeof",
+
+ // Not a keyword, but will break you
+ "NULL",
+
+ // Objective-C Runtime typedefs
+ // From
+ "Category", "Ivar", "Method", "Protocol",
+
+ // GPBMessage Methods
+ // Only need to add instance methods that may conflict with
+ // method declared in protos. The main cases are methods
+ // that take no arguments, or setFoo:/hasFoo: type methods.
+ "clear", "data", "delimitedData", "descriptor", "extensionRegistry",
+ "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize",
+ "sortedExtensionsInUse", "unknownFields",
+
+ // MacTypes.h names
+ "Fixed", "Fract", "Size", "LogicalAddress", "PhysicalAddress", "ByteCount",
+ "ByteOffset", "Duration", "AbsoluteTime", "OptionBits", "ItemCount",
+ "PBVersion", "ScriptCode", "LangCode", "RegionCode", "OSType",
+ "ProcessSerialNumber", "Point", "Rect", "FixedPoint", "FixedRect", "Style",
+ "StyleParameter", "StyleField", "TimeScale", "TimeBase", "TimeRecord",
};
-std::unordered_set kReservedWords =
- MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
+// returns true is input starts with __ or _[A-Z] which are reserved identifiers
+// in C/ C++. All calls should go through UnderscoresToCamelCase before getting here
+// but this verifies and allows for future expansion if we decide to redefine what a
+// reserved C identifier is (for example the GNU list
+// https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html )
+bool IsReservedCIdentifier(const string& input) {
+ if (input.length() > 2) {
+ if (input.at(0) == '_') {
+ if (isupper(input.at(1)) || input.at(1) == '_') {
+ return true;
+ }
+ }
+ }
+ return false;
+}
string SanitizeNameForObjC(const string& input,
const string& extension,
string* out_suffix_added) {
- if (kReservedWords.count(input) > 0) {
+ static const std::unordered_set kReservedWords =
+ MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
+ static const std::unordered_set kNSObjectMethods =
+ MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList));
+ if (IsReservedCIdentifier(input) ||
+ (kReservedWords.count(input) > 0) ||
+ (kNSObjectMethods.count(input) > 0)) {
if (out_suffix_added) *out_suffix_added = extension;
return input + extension;
}
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h b/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
new file mode 100644
index 0000000000..163304665c
--- /dev/null
+++ b/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
@@ -0,0 +1,197 @@
+// NSObject methods
+// Autogenerated by method_dump.sh. Do not edit by hand.
+// Date: Thu Nov 1 14:12:16 PDT 2018
+// macOS: MacOSX10.14.sdk
+// iOS: iPhoneSimulator12.1.sdk
+
+const char* const kNSObjectMethodsList[] = {
+ "CAMLType",
+ "CA_copyRenderValue",
+ "CA_prepareRenderValue",
+ "NS_copyCGImage",
+ "NS_tiledLayerVisibleRect",
+ "___tryRetain_OA",
+ "__autorelease_OA",
+ "__dealloc_zombie",
+ "__release_OA",
+ "__retain_OA",
+ "_accessibilityFinalize",
+ "_accessibilityIsTableViewDescendant",
+ "_accessibilityUIElementSpecifier",
+ "_accessibilityUseConvenienceAPI",
+ "_allowsDirectEncoding",
+ "_asScriptTerminologyNameArray",
+ "_asScriptTerminologyNameString",
+ "_bindingAdaptor",
+ "_cfTypeID",
+ "_copyDescription",
+ "_destroyObserverList",
+ "_didEndKeyValueObserving",
+ "_implicitObservationInfo",
+ "_internalAccessibilityAttributedHint",
+ "_internalAccessibilityAttributedLabel",
+ "_internalAccessibilityAttributedValue",
+ "_isAXConnector",
+ "_isAccessibilityContainerSectionCandidate",
+ "_isAccessibilityContentNavigatorSectionCandidate",
+ "_isAccessibilityContentSectionCandidate",
+ "_isAccessibilityTopLevelNavigatorSectionCandidate",
+ "_isDeallocating",
+ "_isKVOA",
+ "_isToManyChangeInformation",
+ "_ivarDescription",
+ "_localClassNameForClass",
+ "_methodDescription",
+ "_observerStorage",
+ "_overrideUseFastBlockObservers",
+ "_propertyDescription",
+ "_releaseBindingAdaptor",
+ "_scriptingCount",
+ "_scriptingCountNonrecursively",
+ "_scriptingDebugDescription",
+ "_scriptingExists",
+ "_scriptingShouldCheckObjectIndexes",
+ "_shortMethodDescription",
+ "_shouldSearchChildrenForSection",
+ "_traitStorageList",
+ "_tryRetain",
+ "_ui_descriptionBuilder",
+ "_uikit_variesByTraitCollections",
+ "_web_description",
+ "_webkit_invokeOnMainThread",
+ "_willBeginKeyValueObserving",
+ "accessibilityActivate",
+ "accessibilityActivationPoint",
+ "accessibilityAllowsOverriddenAttributesWhenIgnored",
+ "accessibilityAssistiveTechnologyFocusedIdentifiers",
+ "accessibilityAttributedHint",
+ "accessibilityAttributedLabel",
+ "accessibilityAttributedValue",
+ "accessibilityContainer",
+ "accessibilityContainerType",
+ "accessibilityCustomActions",
+ "accessibilityCustomRotors",
+ "accessibilityDecrement",
+ "accessibilityDragSourceDescriptors",
+ "accessibilityDropPointDescriptors",
+ "accessibilityElementCount",
+ "accessibilityElementDidBecomeFocused",
+ "accessibilityElementDidLoseFocus",
+ "accessibilityElementIsFocused",
+ "accessibilityElements",
+ "accessibilityElementsHidden",
+ "accessibilityFrame",
+ "accessibilityHeaderElements",
+ "accessibilityHint",
+ "accessibilityIdentification",
+ "accessibilityIdentifier",
+ "accessibilityIncrement",
+ "accessibilityLabel",
+ "accessibilityLanguage",
+ "accessibilityLocalizedStringKey",
+ "accessibilityNavigationStyle",
+ "accessibilityOverriddenAttributes",
+ "accessibilityParameterizedAttributeNames",
+ "accessibilityPath",
+ "accessibilityPerformEscape",
+ "accessibilityPerformMagicTap",
+ "accessibilityPresenterProcessIdentifier",
+ "accessibilityShouldUseUniqueId",
+ "accessibilitySupportsNotifications",
+ "accessibilitySupportsOverriddenAttributes",
+ "accessibilityTemporaryChildren",
+ "accessibilityTraits",
+ "accessibilityValue",
+ "accessibilityViewIsModal",
+ "accessibilityVisibleArea",
+ "allPropertyKeys",
+ "allowsWeakReference",
+ "attributeKeys",
+ "autoContentAccessingProxy",
+ "autorelease",
+ "awakeFromNib",
+ "boolValueSafe",
+ "bs_encoded",
+ "bs_isPlistableType",
+ "bs_secureEncoded",
+ "cl_json_serializeKey",
+ "class",
+ "classCode",
+ "classDescription",
+ "classForArchiver",
+ "classForCoder",
+ "classForKeyedArchiver",
+ "classForPortCoder",
+ "className",
+ "clearProperties",
+ "copy",
+ "dealloc",
+ "debugDescription",
+ "defaultAccessibilityTraits",
+ "description",
+ "doubleValueSafe",
+ "entityName",
+ "exposedBindings",
+ "finalize",
+ "finishObserving",
+ "flushKeyBindings",
+ "hash",
+ "init",
+ "int64ValueSafe",
+ "isAccessibilityElement",
+ "isAccessibilityElementByDefault",
+ "isElementAccessibilityExposedToInterfaceBuilder",
+ "isFault",
+ "isNSArray__",
+ "isNSCFConstantString__",
+ "isNSData__",
+ "isNSDate__",
+ "isNSDictionary__",
+ "isNSNumber__",
+ "isNSObject__",
+ "isNSOrderedSet__",
+ "isNSSet__",
+ "isNSString__",
+ "isNSTimeZone__",
+ "isNSValue__",
+ "isProxy",
+ "mutableCopy",
+ "nilValueForKey",
+ "objectSpecifier",
+ "observationInfo",
+ "pep_onDetachedThread",
+ "pep_onMainThread",
+ "pep_onMainThreadIfNecessary",
+ "prepareForInterfaceBuilder",
+ "release",
+ "releaseOnMainThread",
+ "retain",
+ "retainCount",
+ "retainWeakReference",
+ "scriptingProperties",
+ "self",
+ "shouldGroupAccessibilityChildren",
+ "storedAccessibilityActivationPoint",
+ "storedAccessibilityContainerType",
+ "storedAccessibilityElementsHidden",
+ "storedAccessibilityFrame",
+ "storedAccessibilityNavigationStyle",
+ "storedAccessibilityTraits",
+ "storedAccessibilityViewIsModal",
+ "storedIsAccessibilityElement",
+ "storedShouldGroupAccessibilityChildren",
+ "stringValueSafe",
+ "superclass",
+ "toManyRelationshipKeys",
+ "toOneRelationshipKeys",
+ "traitStorageList",
+ "un_safeBoolValue",
+ "userInterfaceItemIdentifier",
+ "utf8ValueSafe",
+ "valuesForKeysWithDictionary",
+ "zone",
+// Protocol: CAAnimatableValue
+// Protocol: CARenderValue
+// Protocol: NSObject
+// Protocol: ROCKRemoteInvocationInterface
+};
diff --git a/src/google/protobuf/implicit_weak_message.cc b/src/google/protobuf/implicit_weak_message.cc
index 5cc718f945..b26f44124e 100644
--- a/src/google/protobuf/implicit_weak_message.cc
+++ b/src/google/protobuf/implicit_weak_message.cc
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include