diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs index e1d4d7809ad6..718c3edcb80e 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs @@ -261,6 +261,18 @@ public void RequiredFields() Assert.True(message.IsInitialized()); } + /// + /// Code was accidentally left in message parser that threw exceptions when missing required fields after parsing. + /// We've decided to not throw exceptions on missing fields, instead leaving it up to the consumer how they + /// want to check and handle missing fields. + /// + [Test] + public void RequiredFieldsNoThrow() + { + Assert.DoesNotThrow(() => TestRequired.Parser.ParseFrom(new byte[0])); + Assert.DoesNotThrow(() => (TestRequired.Parser as MessageParser).ParseFrom(new byte[0])); + } + [Test] public void RequiredFieldsInExtensions() { diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs index f9ad29086bda..1d76d276029d 100644 --- a/csharp/src/Google.Protobuf/CodedOutputStream.cs +++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs @@ -89,7 +89,7 @@ public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length private CodedOutputStream(byte[] buffer, int offset, int length) { this.output = null; - this.buffer = buffer; + this.buffer = ProtoPreconditions.CheckNotNull(buffer, nameof(buffer)); this.position = offset; this.limit = offset + length; leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index 2b4c5f0a8038..5aaefe7a890f 100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs @@ -133,7 +133,7 @@ static JsonFormatter() /// The settings. public JsonFormatter(Settings settings) { - this.settings = settings; + this.settings = ProtoPreconditions.CheckNotNull(settings, nameof(settings)); } /// diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs index fb594f2a4343..3f88ea38f177 100644 --- a/csharp/src/Google.Protobuf/JsonParser.cs +++ b/csharp/src/Google.Protobuf/JsonParser.cs @@ -110,7 +110,7 @@ private static void MergeWrapperField(JsonParser parser, IMessage message, JsonT /// The settings. public JsonParser(Settings settings) { - this.settings = settings; + this.settings = ProtoPreconditions.CheckNotNull(settings, nameof(settings)); } /// diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs index 76a350ce4c61..06d0f1059c7a 100644 --- a/csharp/src/Google.Protobuf/MessageParser.cs +++ b/csharp/src/Google.Protobuf/MessageParser.cs @@ -72,7 +72,6 @@ public IMessage ParseFrom(byte[] data) { IMessage message = factory(); message.MergeFrom(data, DiscardUnknownFields, Extensions); - CheckMergedRequiredFields(message); return message; } @@ -87,7 +86,6 @@ public IMessage ParseFrom(byte[] data, int offset, int length) { IMessage message = factory(); message.MergeFrom(data, offset, length, DiscardUnknownFields, Extensions); - CheckMergedRequiredFields(message); return message; } @@ -100,7 +98,6 @@ public IMessage ParseFrom(ByteString data) { IMessage message = factory(); message.MergeFrom(data, DiscardUnknownFields, Extensions); - CheckMergedRequiredFields(message); return message; } @@ -113,7 +110,6 @@ public IMessage ParseFrom(Stream input) { IMessage message = factory(); message.MergeFrom(input, DiscardUnknownFields, Extensions); - CheckMergedRequiredFields(message); return message; } @@ -130,7 +126,6 @@ public IMessage ParseDelimitedFrom(Stream input) { IMessage message = factory(); message.MergeDelimitedFrom(input, DiscardUnknownFields, Extensions); - CheckMergedRequiredFields(message); return message; } @@ -143,7 +138,6 @@ public IMessage ParseFrom(CodedInputStream input) { IMessage message = factory(); MergeFrom(message, input); - CheckMergedRequiredFields(message); return message; } @@ -176,12 +170,6 @@ internal void MergeFrom(IMessage message, CodedInputStream codedInput) } } - internal static void CheckMergedRequiredFields(IMessage message) - { - if (!message.IsInitialized()) - throw new InvalidOperationException("Parsed message does not contain all required fields"); - } - /// /// Creates a new message parser which optionally discards unknown fields when parsing. /// diff --git a/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs b/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs index 38e33d7ff2bd..9664559df249 100644 --- a/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs +++ b/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs @@ -107,13 +107,14 @@ internal void CrossLink() { descriptor.CrossLink(); - IList _; - if (!declarationOrder.TryGetValue(descriptor.ExtendeeType, out _)) + IList list; + if (!declarationOrder.TryGetValue(descriptor.ExtendeeType, out list)) { - declarationOrder.Add(descriptor.ExtendeeType, new List()); + list = new List(); + declarationOrder.Add(descriptor.ExtendeeType, list); } - declarationOrder[descriptor.ExtendeeType].Add(descriptor); + list.Add(descriptor); } extensionsByTypeInDeclarationOrder = declarationOrder