1*1b3f573fSAndroid Build Coastguard Worker #region Copyright notice and license 2*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format 3*1b3f573fSAndroid Build Coastguard Worker // Copyright 2015 Google Inc. All rights reserved. 4*1b3f573fSAndroid Build Coastguard Worker // https://developers.google.com/protocol-buffers/ 5*1b3f573fSAndroid Build Coastguard Worker // 6*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without 7*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are 8*1b3f573fSAndroid Build Coastguard Worker // met: 9*1b3f573fSAndroid Build Coastguard Worker // 10*1b3f573fSAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright 11*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer. 12*1b3f573fSAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above 13*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer 14*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the 15*1b3f573fSAndroid Build Coastguard Worker // distribution. 16*1b3f573fSAndroid Build Coastguard Worker // * Neither the name of Google Inc. nor the names of its 17*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from 18*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission. 19*1b3f573fSAndroid Build Coastguard Worker // 20*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31*1b3f573fSAndroid Build Coastguard Worker #endregion 32*1b3f573fSAndroid Build Coastguard Worker 33*1b3f573fSAndroid Build Coastguard Worker using System; 34*1b3f573fSAndroid Build Coastguard Worker using System.Buffers; 35*1b3f573fSAndroid Build Coastguard Worker using System.IO; 36*1b3f573fSAndroid Build Coastguard Worker using System.Security; 37*1b3f573fSAndroid Build Coastguard Worker 38*1b3f573fSAndroid Build Coastguard Worker namespace Google.Protobuf 39*1b3f573fSAndroid Build Coastguard Worker { 40*1b3f573fSAndroid Build Coastguard Worker /// <summary> 41*1b3f573fSAndroid Build Coastguard Worker /// A general message parser, typically used by reflection-based code as all the methods 42*1b3f573fSAndroid Build Coastguard Worker /// return simple <see cref="IMessage"/>. 43*1b3f573fSAndroid Build Coastguard Worker /// </summary> 44*1b3f573fSAndroid Build Coastguard Worker public class MessageParser 45*1b3f573fSAndroid Build Coastguard Worker { 46*1b3f573fSAndroid Build Coastguard Worker private Func<IMessage> factory; 47*1b3f573fSAndroid Build Coastguard Worker // TODO: When we use a C# 7.1 compiler, make this private protected. 48*1b3f573fSAndroid Build Coastguard Worker internal bool DiscardUnknownFields { get; } 49*1b3f573fSAndroid Build Coastguard Worker 50*1b3f573fSAndroid Build Coastguard Worker internal ExtensionRegistry Extensions { get; } 51*1b3f573fSAndroid Build Coastguard Worker MessageParser(Func<IMessage> factory, bool discardUnknownFields, ExtensionRegistry extensions)52*1b3f573fSAndroid Build Coastguard Worker internal MessageParser(Func<IMessage> factory, bool discardUnknownFields, ExtensionRegistry extensions) 53*1b3f573fSAndroid Build Coastguard Worker { 54*1b3f573fSAndroid Build Coastguard Worker this.factory = factory; 55*1b3f573fSAndroid Build Coastguard Worker DiscardUnknownFields = discardUnknownFields; 56*1b3f573fSAndroid Build Coastguard Worker Extensions = extensions; 57*1b3f573fSAndroid Build Coastguard Worker } 58*1b3f573fSAndroid Build Coastguard Worker 59*1b3f573fSAndroid Build Coastguard Worker /// <summary> 60*1b3f573fSAndroid Build Coastguard Worker /// Creates a template instance ready for population. 61*1b3f573fSAndroid Build Coastguard Worker /// </summary> 62*1b3f573fSAndroid Build Coastguard Worker /// <returns>An empty message.</returns> CreateTemplate()63*1b3f573fSAndroid Build Coastguard Worker internal IMessage CreateTemplate() 64*1b3f573fSAndroid Build Coastguard Worker { 65*1b3f573fSAndroid Build Coastguard Worker return factory(); 66*1b3f573fSAndroid Build Coastguard Worker } 67*1b3f573fSAndroid Build Coastguard Worker 68*1b3f573fSAndroid Build Coastguard Worker /// <summary> 69*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from a byte array. 70*1b3f573fSAndroid Build Coastguard Worker /// </summary> 71*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The byte array containing the message. Must not be null.</param> 72*1b3f573fSAndroid Build Coastguard Worker /// <returns>The newly parsed message.</returns> ParseFrom(byte[] data)73*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(byte[] data) 74*1b3f573fSAndroid Build Coastguard Worker { 75*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 76*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 77*1b3f573fSAndroid Build Coastguard Worker return message; 78*1b3f573fSAndroid Build Coastguard Worker } 79*1b3f573fSAndroid Build Coastguard Worker 80*1b3f573fSAndroid Build Coastguard Worker /// <summary> 81*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from a byte array slice. 82*1b3f573fSAndroid Build Coastguard Worker /// </summary> 83*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The byte array containing the message. Must not be null.</param> 84*1b3f573fSAndroid Build Coastguard Worker /// <param name="offset">The offset of the slice to parse.</param> 85*1b3f573fSAndroid Build Coastguard Worker /// <param name="length">The length of the slice to parse.</param> 86*1b3f573fSAndroid Build Coastguard Worker /// <returns>The newly parsed message.</returns> ParseFrom(byte[] data, int offset, int length)87*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(byte[] data, int offset, int length) 88*1b3f573fSAndroid Build Coastguard Worker { 89*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 90*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, offset, length, DiscardUnknownFields, Extensions); 91*1b3f573fSAndroid Build Coastguard Worker return message; 92*1b3f573fSAndroid Build Coastguard Worker } 93*1b3f573fSAndroid Build Coastguard Worker 94*1b3f573fSAndroid Build Coastguard Worker /// <summary> 95*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given byte string. 96*1b3f573fSAndroid Build Coastguard Worker /// </summary> 97*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The data to parse.</param> 98*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseFrom(ByteString data)99*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(ByteString data) 100*1b3f573fSAndroid Build Coastguard Worker { 101*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 102*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 103*1b3f573fSAndroid Build Coastguard Worker return message; 104*1b3f573fSAndroid Build Coastguard Worker } 105*1b3f573fSAndroid Build Coastguard Worker 106*1b3f573fSAndroid Build Coastguard Worker /// <summary> 107*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given stream. 108*1b3f573fSAndroid Build Coastguard Worker /// </summary> 109*1b3f573fSAndroid Build Coastguard Worker /// <param name="input">The stream to parse.</param> 110*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseFrom(Stream input)111*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(Stream input) 112*1b3f573fSAndroid Build Coastguard Worker { 113*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 114*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(input, DiscardUnknownFields, Extensions); 115*1b3f573fSAndroid Build Coastguard Worker return message; 116*1b3f573fSAndroid Build Coastguard Worker } 117*1b3f573fSAndroid Build Coastguard Worker 118*1b3f573fSAndroid Build Coastguard Worker /// <summary> 119*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given sequence. 120*1b3f573fSAndroid Build Coastguard Worker /// </summary> 121*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The data to parse.</param> 122*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> 123*1b3f573fSAndroid Build Coastguard Worker [SecuritySafeCritical] ParseFrom(ReadOnlySequence<byte> data)124*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(ReadOnlySequence<byte> data) 125*1b3f573fSAndroid Build Coastguard Worker { 126*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 127*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 128*1b3f573fSAndroid Build Coastguard Worker return message; 129*1b3f573fSAndroid Build Coastguard Worker } 130*1b3f573fSAndroid Build Coastguard Worker 131*1b3f573fSAndroid Build Coastguard Worker /// <summary> 132*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given span. 133*1b3f573fSAndroid Build Coastguard Worker /// </summary> 134*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The data to parse.</param> 135*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> 136*1b3f573fSAndroid Build Coastguard Worker [SecuritySafeCritical] ParseFrom(ReadOnlySpan<byte> data)137*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(ReadOnlySpan<byte> data) 138*1b3f573fSAndroid Build Coastguard Worker { 139*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 140*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 141*1b3f573fSAndroid Build Coastguard Worker return message; 142*1b3f573fSAndroid Build Coastguard Worker } 143*1b3f573fSAndroid Build Coastguard Worker 144*1b3f573fSAndroid Build Coastguard Worker /// <summary> 145*1b3f573fSAndroid Build Coastguard Worker /// Parses a length-delimited message from the given stream. 146*1b3f573fSAndroid Build Coastguard Worker /// </summary> 147*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 148*1b3f573fSAndroid Build Coastguard Worker /// The stream is expected to contain a length and then the data. Only the amount of data 149*1b3f573fSAndroid Build Coastguard Worker /// specified by the length will be consumed. 150*1b3f573fSAndroid Build Coastguard Worker /// </remarks> 151*1b3f573fSAndroid Build Coastguard Worker /// <param name="input">The stream to parse.</param> 152*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseDelimitedFrom(Stream input)153*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseDelimitedFrom(Stream input) 154*1b3f573fSAndroid Build Coastguard Worker { 155*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 156*1b3f573fSAndroid Build Coastguard Worker message.MergeDelimitedFrom(input, DiscardUnknownFields, Extensions); 157*1b3f573fSAndroid Build Coastguard Worker return message; 158*1b3f573fSAndroid Build Coastguard Worker } 159*1b3f573fSAndroid Build Coastguard Worker 160*1b3f573fSAndroid Build Coastguard Worker /// <summary> 161*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given coded input stream. 162*1b3f573fSAndroid Build Coastguard Worker /// </summary> 163*1b3f573fSAndroid Build Coastguard Worker /// <param name="input">The stream to parse.</param> 164*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseFrom(CodedInputStream input)165*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseFrom(CodedInputStream input) 166*1b3f573fSAndroid Build Coastguard Worker { 167*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 168*1b3f573fSAndroid Build Coastguard Worker MergeFrom(message, input); 169*1b3f573fSAndroid Build Coastguard Worker return message; 170*1b3f573fSAndroid Build Coastguard Worker } 171*1b3f573fSAndroid Build Coastguard Worker 172*1b3f573fSAndroid Build Coastguard Worker /// <summary> 173*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given JSON. 174*1b3f573fSAndroid Build Coastguard Worker /// </summary> 175*1b3f573fSAndroid Build Coastguard Worker /// <param name="json">The JSON to parse.</param> 176*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> 177*1b3f573fSAndroid Build Coastguard Worker /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception> 178*1b3f573fSAndroid Build Coastguard Worker /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception> ParseJson(string json)179*1b3f573fSAndroid Build Coastguard Worker public IMessage ParseJson(string json) 180*1b3f573fSAndroid Build Coastguard Worker { 181*1b3f573fSAndroid Build Coastguard Worker IMessage message = factory(); 182*1b3f573fSAndroid Build Coastguard Worker JsonParser.Default.Merge(message, json); 183*1b3f573fSAndroid Build Coastguard Worker return message; 184*1b3f573fSAndroid Build Coastguard Worker } 185*1b3f573fSAndroid Build Coastguard Worker 186*1b3f573fSAndroid Build Coastguard Worker // TODO: When we're using a C# 7.1 compiler, make this private protected. MergeFrom(IMessage message, CodedInputStream codedInput)187*1b3f573fSAndroid Build Coastguard Worker internal void MergeFrom(IMessage message, CodedInputStream codedInput) 188*1b3f573fSAndroid Build Coastguard Worker { 189*1b3f573fSAndroid Build Coastguard Worker bool originalDiscard = codedInput.DiscardUnknownFields; 190*1b3f573fSAndroid Build Coastguard Worker ExtensionRegistry originalRegistry = codedInput.ExtensionRegistry; 191*1b3f573fSAndroid Build Coastguard Worker try 192*1b3f573fSAndroid Build Coastguard Worker { 193*1b3f573fSAndroid Build Coastguard Worker codedInput.DiscardUnknownFields = DiscardUnknownFields; 194*1b3f573fSAndroid Build Coastguard Worker codedInput.ExtensionRegistry = Extensions; 195*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(codedInput); 196*1b3f573fSAndroid Build Coastguard Worker } 197*1b3f573fSAndroid Build Coastguard Worker finally 198*1b3f573fSAndroid Build Coastguard Worker { 199*1b3f573fSAndroid Build Coastguard Worker codedInput.DiscardUnknownFields = originalDiscard; 200*1b3f573fSAndroid Build Coastguard Worker codedInput.ExtensionRegistry = originalRegistry; 201*1b3f573fSAndroid Build Coastguard Worker } 202*1b3f573fSAndroid Build Coastguard Worker } 203*1b3f573fSAndroid Build Coastguard Worker 204*1b3f573fSAndroid Build Coastguard Worker /// <summary> 205*1b3f573fSAndroid Build Coastguard Worker /// Creates a new message parser which optionally discards unknown fields when parsing. 206*1b3f573fSAndroid Build Coastguard Worker /// </summary> 207*1b3f573fSAndroid Build Coastguard Worker /// <param name="discardUnknownFields">Whether or not to discard unknown fields when parsing.</param> 208*1b3f573fSAndroid Build Coastguard Worker /// <returns>A newly configured message parser.</returns> 209*1b3f573fSAndroid Build Coastguard Worker public MessageParser WithDiscardUnknownFields(bool discardUnknownFields) => 210*1b3f573fSAndroid Build Coastguard Worker new MessageParser(factory, discardUnknownFields, Extensions); 211*1b3f573fSAndroid Build Coastguard Worker 212*1b3f573fSAndroid Build Coastguard Worker /// <summary> 213*1b3f573fSAndroid Build Coastguard Worker /// Creates a new message parser which registers extensions from the specified registry upon creating the message instance 214*1b3f573fSAndroid Build Coastguard Worker /// </summary> 215*1b3f573fSAndroid Build Coastguard Worker /// <param name="registry">The extensions to register</param> 216*1b3f573fSAndroid Build Coastguard Worker /// <returns>A newly configured message parser.</returns> 217*1b3f573fSAndroid Build Coastguard Worker public MessageParser WithExtensionRegistry(ExtensionRegistry registry) => 218*1b3f573fSAndroid Build Coastguard Worker new MessageParser(factory, DiscardUnknownFields, registry); 219*1b3f573fSAndroid Build Coastguard Worker } 220*1b3f573fSAndroid Build Coastguard Worker 221*1b3f573fSAndroid Build Coastguard Worker /// <summary> 222*1b3f573fSAndroid Build Coastguard Worker /// A parser for a specific message type. 223*1b3f573fSAndroid Build Coastguard Worker /// </summary> 224*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 225*1b3f573fSAndroid Build Coastguard Worker /// <p> 226*1b3f573fSAndroid Build Coastguard Worker /// This delegates most behavior to the 227*1b3f573fSAndroid Build Coastguard Worker /// <see cref="IMessage.MergeFrom"/> implementation within the original type, but 228*1b3f573fSAndroid Build Coastguard Worker /// provides convenient overloads to parse from a variety of sources. 229*1b3f573fSAndroid Build Coastguard Worker /// </p> 230*1b3f573fSAndroid Build Coastguard Worker /// <p> 231*1b3f573fSAndroid Build Coastguard Worker /// Most applications will never need to create their own instances of this type; 232*1b3f573fSAndroid Build Coastguard Worker /// instead, use the static <c>Parser</c> property of a generated message type to obtain a 233*1b3f573fSAndroid Build Coastguard Worker /// parser for that type. 234*1b3f573fSAndroid Build Coastguard Worker /// </p> 235*1b3f573fSAndroid Build Coastguard Worker /// </remarks> 236*1b3f573fSAndroid Build Coastguard Worker /// <typeparam name="T">The type of message to be parsed.</typeparam> 237*1b3f573fSAndroid Build Coastguard Worker public sealed class MessageParser<T> : MessageParser where T : IMessage<T> 238*1b3f573fSAndroid Build Coastguard Worker { 239*1b3f573fSAndroid Build Coastguard Worker // Implementation note: all the methods here *could* just delegate up to the base class and cast the result. 240*1b3f573fSAndroid Build Coastguard Worker // The current implementation avoids a virtual method call and a cast, which *may* be significant in some cases. 241*1b3f573fSAndroid Build Coastguard Worker // Benchmarking work is required to measure the significance - but it's only a few lines of code in any case. 242*1b3f573fSAndroid Build Coastguard Worker // The API wouldn't change anyway - just the implementation - so this work can be deferred. 243*1b3f573fSAndroid Build Coastguard Worker private readonly Func<T> factory; 244*1b3f573fSAndroid Build Coastguard Worker 245*1b3f573fSAndroid Build Coastguard Worker /// <summary> 246*1b3f573fSAndroid Build Coastguard Worker /// Creates a new parser. 247*1b3f573fSAndroid Build Coastguard Worker /// </summary> 248*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 249*1b3f573fSAndroid Build Coastguard Worker /// The factory method is effectively an optimization over using a generic constraint 250*1b3f573fSAndroid Build Coastguard Worker /// to require a parameterless constructor: delegates are significantly faster to execute. 251*1b3f573fSAndroid Build Coastguard Worker /// </remarks> 252*1b3f573fSAndroid Build Coastguard Worker /// <param name="factory">Function to invoke when a new, empty message is required.</param> MessageParser(Func<T> factory)253*1b3f573fSAndroid Build Coastguard Worker public MessageParser(Func<T> factory) : this(factory, false, null) 254*1b3f573fSAndroid Build Coastguard Worker { 255*1b3f573fSAndroid Build Coastguard Worker } 256*1b3f573fSAndroid Build Coastguard Worker MessageParser(Func<T> factory, bool discardUnknownFields, ExtensionRegistry extensions)257*1b3f573fSAndroid Build Coastguard Worker internal MessageParser(Func<T> factory, bool discardUnknownFields, ExtensionRegistry extensions) : base(() => factory(), discardUnknownFields, extensions) 258*1b3f573fSAndroid Build Coastguard Worker { 259*1b3f573fSAndroid Build Coastguard Worker this.factory = factory; 260*1b3f573fSAndroid Build Coastguard Worker } 261*1b3f573fSAndroid Build Coastguard Worker 262*1b3f573fSAndroid Build Coastguard Worker /// <summary> 263*1b3f573fSAndroid Build Coastguard Worker /// Creates a template instance ready for population. 264*1b3f573fSAndroid Build Coastguard Worker /// </summary> 265*1b3f573fSAndroid Build Coastguard Worker /// <returns>An empty message.</returns> CreateTemplate()266*1b3f573fSAndroid Build Coastguard Worker internal new T CreateTemplate() 267*1b3f573fSAndroid Build Coastguard Worker { 268*1b3f573fSAndroid Build Coastguard Worker return factory(); 269*1b3f573fSAndroid Build Coastguard Worker } 270*1b3f573fSAndroid Build Coastguard Worker 271*1b3f573fSAndroid Build Coastguard Worker /// <summary> 272*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from a byte array. 273*1b3f573fSAndroid Build Coastguard Worker /// </summary> 274*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The byte array containing the message. Must not be null.</param> 275*1b3f573fSAndroid Build Coastguard Worker /// <returns>The newly parsed message.</returns> ParseFrom(byte[] data)276*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(byte[] data) 277*1b3f573fSAndroid Build Coastguard Worker { 278*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 279*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 280*1b3f573fSAndroid Build Coastguard Worker return message; 281*1b3f573fSAndroid Build Coastguard Worker } 282*1b3f573fSAndroid Build Coastguard Worker 283*1b3f573fSAndroid Build Coastguard Worker /// <summary> 284*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from a byte array slice. 285*1b3f573fSAndroid Build Coastguard Worker /// </summary> 286*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The byte array containing the message. Must not be null.</param> 287*1b3f573fSAndroid Build Coastguard Worker /// <param name="offset">The offset of the slice to parse.</param> 288*1b3f573fSAndroid Build Coastguard Worker /// <param name="length">The length of the slice to parse.</param> 289*1b3f573fSAndroid Build Coastguard Worker /// <returns>The newly parsed message.</returns> ParseFrom(byte[] data, int offset, int length)290*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(byte[] data, int offset, int length) 291*1b3f573fSAndroid Build Coastguard Worker { 292*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 293*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, offset, length, DiscardUnknownFields, Extensions); 294*1b3f573fSAndroid Build Coastguard Worker return message; 295*1b3f573fSAndroid Build Coastguard Worker } 296*1b3f573fSAndroid Build Coastguard Worker 297*1b3f573fSAndroid Build Coastguard Worker /// <summary> 298*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given byte string. 299*1b3f573fSAndroid Build Coastguard Worker /// </summary> 300*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The data to parse.</param> 301*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseFrom(ByteString data)302*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(ByteString data) 303*1b3f573fSAndroid Build Coastguard Worker { 304*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 305*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 306*1b3f573fSAndroid Build Coastguard Worker return message; 307*1b3f573fSAndroid Build Coastguard Worker } 308*1b3f573fSAndroid Build Coastguard Worker 309*1b3f573fSAndroid Build Coastguard Worker /// <summary> 310*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given stream. 311*1b3f573fSAndroid Build Coastguard Worker /// </summary> 312*1b3f573fSAndroid Build Coastguard Worker /// <param name="input">The stream to parse.</param> 313*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseFrom(Stream input)314*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(Stream input) 315*1b3f573fSAndroid Build Coastguard Worker { 316*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 317*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(input, DiscardUnknownFields, Extensions); 318*1b3f573fSAndroid Build Coastguard Worker return message; 319*1b3f573fSAndroid Build Coastguard Worker } 320*1b3f573fSAndroid Build Coastguard Worker 321*1b3f573fSAndroid Build Coastguard Worker /// <summary> 322*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given sequence. 323*1b3f573fSAndroid Build Coastguard Worker /// </summary> 324*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The data to parse.</param> 325*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> 326*1b3f573fSAndroid Build Coastguard Worker [SecuritySafeCritical] ParseFrom(ReadOnlySequence<byte> data)327*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(ReadOnlySequence<byte> data) 328*1b3f573fSAndroid Build Coastguard Worker { 329*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 330*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 331*1b3f573fSAndroid Build Coastguard Worker return message; 332*1b3f573fSAndroid Build Coastguard Worker } 333*1b3f573fSAndroid Build Coastguard Worker 334*1b3f573fSAndroid Build Coastguard Worker /// <summary> 335*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given span. 336*1b3f573fSAndroid Build Coastguard Worker /// </summary> 337*1b3f573fSAndroid Build Coastguard Worker /// <param name="data">The data to parse.</param> 338*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> 339*1b3f573fSAndroid Build Coastguard Worker [SecuritySafeCritical] ParseFrom(ReadOnlySpan<byte> data)340*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(ReadOnlySpan<byte> data) 341*1b3f573fSAndroid Build Coastguard Worker { 342*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 343*1b3f573fSAndroid Build Coastguard Worker message.MergeFrom(data, DiscardUnknownFields, Extensions); 344*1b3f573fSAndroid Build Coastguard Worker return message; 345*1b3f573fSAndroid Build Coastguard Worker } 346*1b3f573fSAndroid Build Coastguard Worker 347*1b3f573fSAndroid Build Coastguard Worker /// <summary> 348*1b3f573fSAndroid Build Coastguard Worker /// Parses a length-delimited message from the given stream. 349*1b3f573fSAndroid Build Coastguard Worker /// </summary> 350*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 351*1b3f573fSAndroid Build Coastguard Worker /// The stream is expected to contain a length and then the data. Only the amount of data 352*1b3f573fSAndroid Build Coastguard Worker /// specified by the length will be consumed. 353*1b3f573fSAndroid Build Coastguard Worker /// </remarks> 354*1b3f573fSAndroid Build Coastguard Worker /// <param name="input">The stream to parse.</param> 355*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseDelimitedFrom(Stream input)356*1b3f573fSAndroid Build Coastguard Worker public new T ParseDelimitedFrom(Stream input) 357*1b3f573fSAndroid Build Coastguard Worker { 358*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 359*1b3f573fSAndroid Build Coastguard Worker message.MergeDelimitedFrom(input, DiscardUnknownFields, Extensions); 360*1b3f573fSAndroid Build Coastguard Worker return message; 361*1b3f573fSAndroid Build Coastguard Worker } 362*1b3f573fSAndroid Build Coastguard Worker 363*1b3f573fSAndroid Build Coastguard Worker /// <summary> 364*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given coded input stream. 365*1b3f573fSAndroid Build Coastguard Worker /// </summary> 366*1b3f573fSAndroid Build Coastguard Worker /// <param name="input">The stream to parse.</param> 367*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> ParseFrom(CodedInputStream input)368*1b3f573fSAndroid Build Coastguard Worker public new T ParseFrom(CodedInputStream input) 369*1b3f573fSAndroid Build Coastguard Worker { 370*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 371*1b3f573fSAndroid Build Coastguard Worker MergeFrom(message, input); 372*1b3f573fSAndroid Build Coastguard Worker return message; 373*1b3f573fSAndroid Build Coastguard Worker } 374*1b3f573fSAndroid Build Coastguard Worker 375*1b3f573fSAndroid Build Coastguard Worker /// <summary> 376*1b3f573fSAndroid Build Coastguard Worker /// Parses a message from the given JSON. 377*1b3f573fSAndroid Build Coastguard Worker /// </summary> 378*1b3f573fSAndroid Build Coastguard Worker /// <param name="json">The JSON to parse.</param> 379*1b3f573fSAndroid Build Coastguard Worker /// <returns>The parsed message.</returns> 380*1b3f573fSAndroid Build Coastguard Worker /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception> 381*1b3f573fSAndroid Build Coastguard Worker /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception> ParseJson(string json)382*1b3f573fSAndroid Build Coastguard Worker public new T ParseJson(string json) 383*1b3f573fSAndroid Build Coastguard Worker { 384*1b3f573fSAndroid Build Coastguard Worker T message = factory(); 385*1b3f573fSAndroid Build Coastguard Worker JsonParser.Default.Merge(message, json); 386*1b3f573fSAndroid Build Coastguard Worker return message; 387*1b3f573fSAndroid Build Coastguard Worker } 388*1b3f573fSAndroid Build Coastguard Worker 389*1b3f573fSAndroid Build Coastguard Worker /// <summary> 390*1b3f573fSAndroid Build Coastguard Worker /// Creates a new message parser which optionally discards unknown fields when parsing. 391*1b3f573fSAndroid Build Coastguard Worker /// </summary> 392*1b3f573fSAndroid Build Coastguard Worker /// <param name="discardUnknownFields">Whether or not to discard unknown fields when parsing.</param> 393*1b3f573fSAndroid Build Coastguard Worker /// <returns>A newly configured message parser.</returns> 394*1b3f573fSAndroid Build Coastguard Worker public new MessageParser<T> WithDiscardUnknownFields(bool discardUnknownFields) => 395*1b3f573fSAndroid Build Coastguard Worker new MessageParser<T>(factory, discardUnknownFields, Extensions); 396*1b3f573fSAndroid Build Coastguard Worker 397*1b3f573fSAndroid Build Coastguard Worker /// <summary> 398*1b3f573fSAndroid Build Coastguard Worker /// Creates a new message parser which registers extensions from the specified registry upon creating the message instance 399*1b3f573fSAndroid Build Coastguard Worker /// </summary> 400*1b3f573fSAndroid Build Coastguard Worker /// <param name="registry">The extensions to register</param> 401*1b3f573fSAndroid Build Coastguard Worker /// <returns>A newly configured message parser.</returns> 402*1b3f573fSAndroid Build Coastguard Worker public new MessageParser<T> WithExtensionRegistry(ExtensionRegistry registry) => 403*1b3f573fSAndroid Build Coastguard Worker new MessageParser<T>(factory, DiscardUnknownFields, registry); 404*1b3f573fSAndroid Build Coastguard Worker } 405*1b3f573fSAndroid Build Coastguard Worker } 406