diff options
Diffstat (limited to 'csharp/src/Google.Protobuf/MessageParser.cs')
-rw-r--r-- | csharp/src/Google.Protobuf/MessageParser.cs | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs index 8889638b..4d35554a 100644 --- a/csharp/src/Google.Protobuf/MessageParser.cs +++ b/csharp/src/Google.Protobuf/MessageParser.cs @@ -42,10 +42,13 @@ namespace Google.Protobuf public class MessageParser { private Func<IMessage> factory; + // TODO: When we use a C# 7.1 compiler, make this private protected. + internal bool DiscardUnknownFields { get; } - internal MessageParser(Func<IMessage> factory) + internal MessageParser(Func<IMessage> factory, bool discardUnknownFields) { this.factory = factory; + DiscardUnknownFields = discardUnknownFields; } /// <summary> @@ -64,9 +67,22 @@ namespace Google.Protobuf /// <returns>The newly parsed message.</returns> public IMessage ParseFrom(byte[] data) { - ProtoPreconditions.CheckNotNull(data, "data"); IMessage message = factory(); - message.MergeFrom(data); + message.MergeFrom(data, DiscardUnknownFields); + return message; + } + + /// <summary> + /// Parses a message from a byte array slice. + /// </summary> + /// <param name="data">The byte array containing the message. Must not be null.</param> + /// <param name="offset">The offset of the slice to parse.</param> + /// <param name="length">The length of the slice to parse.</param> + /// <returns>The newly parsed message.</returns> + public IMessage ParseFrom(byte[] data, int offset, int length) + { + IMessage message = factory(); + message.MergeFrom(data, offset, length, DiscardUnknownFields); return message; } @@ -77,9 +93,8 @@ namespace Google.Protobuf /// <returns>The parsed message.</returns> public IMessage ParseFrom(ByteString data) { - ProtoPreconditions.CheckNotNull(data, "data"); IMessage message = factory(); - message.MergeFrom(data); + message.MergeFrom(data, DiscardUnknownFields); return message; } @@ -91,7 +106,7 @@ namespace Google.Protobuf public IMessage ParseFrom(Stream input) { IMessage message = factory(); - message.MergeFrom(input); + message.MergeFrom(input, DiscardUnknownFields); return message; } @@ -107,7 +122,7 @@ namespace Google.Protobuf public IMessage ParseDelimitedFrom(Stream input) { IMessage message = factory(); - message.MergeDelimitedFrom(input); + message.MergeDelimitedFrom(input, DiscardUnknownFields); return message; } @@ -119,7 +134,7 @@ namespace Google.Protobuf public IMessage ParseFrom(CodedInputStream input) { IMessage message = factory(); - message.MergeFrom(input); + MergeFrom(message, input); return message; } @@ -136,6 +151,29 @@ namespace Google.Protobuf JsonParser.Default.Merge(message, json); return message; } + + // TODO: When we're using a C# 7.1 compiler, make this private protected. + internal void MergeFrom(IMessage message, CodedInputStream codedInput) + { + bool originalDiscard = codedInput.DiscardUnknownFields; + try + { + codedInput.DiscardUnknownFields = DiscardUnknownFields; + message.MergeFrom(codedInput); + } + finally + { + codedInput.DiscardUnknownFields = originalDiscard; + } + } + + /// <summary> + /// Creates a new message parser which optionally discards unknown fields when parsing. + /// </summary> + /// <param name="discardUnknownFields">Whether or not to discard unknown fields when parsing.</param> + /// <returns>A newly configured message parser.</returns> + public MessageParser WithDiscardUnknownFields(bool discardUnknownFields) => + new MessageParser(factory, discardUnknownFields); } /// <summary> @@ -170,7 +208,11 @@ namespace Google.Protobuf /// to require a parameterless constructor: delegates are significantly faster to execute. /// </remarks> /// <param name="factory">Function to invoke when a new, empty message is required.</param> - public MessageParser(Func<T> factory) : base(() => factory()) + public MessageParser(Func<T> factory) : this(factory, false) + { + } + + internal MessageParser(Func<T> factory, bool discardUnknownFields) : base(() => factory(), discardUnknownFields) { this.factory = factory; } @@ -191,9 +233,22 @@ namespace Google.Protobuf /// <returns>The newly parsed message.</returns> public new T ParseFrom(byte[] data) { - ProtoPreconditions.CheckNotNull(data, "data"); T message = factory(); - message.MergeFrom(data); + message.MergeFrom(data, DiscardUnknownFields); + return message; + } + + /// <summary> + /// Parses a message from a byte array slice. + /// </summary> + /// <param name="data">The byte array containing the message. Must not be null.</param> + /// <param name="offset">The offset of the slice to parse.</param> + /// <param name="length">The length of the slice to parse.</param> + /// <returns>The newly parsed message.</returns> + public new T ParseFrom(byte[] data, int offset, int length) + { + T message = factory(); + message.MergeFrom(data, offset, length, DiscardUnknownFields); return message; } @@ -204,9 +259,8 @@ namespace Google.Protobuf /// <returns>The parsed message.</returns> public new T ParseFrom(ByteString data) { - ProtoPreconditions.CheckNotNull(data, "data"); T message = factory(); - message.MergeFrom(data); + message.MergeFrom(data, DiscardUnknownFields); return message; } @@ -218,7 +272,7 @@ namespace Google.Protobuf public new T ParseFrom(Stream input) { T message = factory(); - message.MergeFrom(input); + message.MergeFrom(input, DiscardUnknownFields); return message; } @@ -234,7 +288,7 @@ namespace Google.Protobuf public new T ParseDelimitedFrom(Stream input) { T message = factory(); - message.MergeDelimitedFrom(input); + message.MergeDelimitedFrom(input, DiscardUnknownFields); return message; } @@ -246,7 +300,7 @@ namespace Google.Protobuf public new T ParseFrom(CodedInputStream input) { T message = factory(); - message.MergeFrom(input); + MergeFrom(message, input); return message; } @@ -263,5 +317,13 @@ namespace Google.Protobuf JsonParser.Default.Merge(message, json); return message; } + + /// <summary> + /// Creates a new message parser which optionally discards unknown fields when parsing. + /// </summary> + /// <param name="discardUnknownFields">Whether or not to discard unknown fields when parsing.</param> + /// <returns>A newly configured message parser.</returns> + public new MessageParser<T> WithDiscardUnknownFields(bool discardUnknownFields) => + new MessageParser<T>(factory, discardUnknownFields); } } |