xref: /aosp_15_r20/external/protobuf/csharp/src/Google.Protobuf/MessageExtensions.cs (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
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 Google.Protobuf.Reflection;
34*1b3f573fSAndroid Build Coastguard Worker using System.Buffers;
35*1b3f573fSAndroid Build Coastguard Worker using System.Collections;
36*1b3f573fSAndroid Build Coastguard Worker using System;
37*1b3f573fSAndroid Build Coastguard Worker using System.IO;
38*1b3f573fSAndroid Build Coastguard Worker using System.Linq;
39*1b3f573fSAndroid Build Coastguard Worker using System.Security;
40*1b3f573fSAndroid Build Coastguard Worker 
41*1b3f573fSAndroid Build Coastguard Worker namespace Google.Protobuf
42*1b3f573fSAndroid Build Coastguard Worker {
43*1b3f573fSAndroid Build Coastguard Worker     /// <summary>
44*1b3f573fSAndroid Build Coastguard Worker     /// Extension methods on <see cref="IMessage"/> and <see cref="IMessage{T}"/>.
45*1b3f573fSAndroid Build Coastguard Worker     /// </summary>
46*1b3f573fSAndroid Build Coastguard Worker     public static class MessageExtensions
47*1b3f573fSAndroid Build Coastguard Worker     {
48*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
49*1b3f573fSAndroid Build Coastguard Worker         /// Merges data from the given byte array into an existing message.
50*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
51*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to merge the data into.</param>
52*1b3f573fSAndroid Build Coastguard Worker         /// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
MergeFrom(this IMessage message, byte[] data)53*1b3f573fSAndroid Build Coastguard Worker         public static void MergeFrom(this IMessage message, byte[] data) =>
54*1b3f573fSAndroid Build Coastguard Worker             MergeFrom(message, data, false, null);
55*1b3f573fSAndroid Build Coastguard Worker 
56*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
57*1b3f573fSAndroid Build Coastguard Worker         /// Merges data from the given byte array slice into an existing message.
58*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
59*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to merge the data into.</param>
60*1b3f573fSAndroid Build Coastguard Worker         /// <param name="data">The data containing the slice to merge, which must be protobuf-encoded binary data.</param>
61*1b3f573fSAndroid Build Coastguard Worker         /// <param name="offset">The offset of the slice to merge.</param>
62*1b3f573fSAndroid Build Coastguard Worker         /// <param name="length">The length of the slice to merge.</param>
MergeFrom(this IMessage message, byte[] data, int offset, int length)63*1b3f573fSAndroid Build Coastguard Worker         public static void MergeFrom(this IMessage message, byte[] data, int offset, int length) =>
64*1b3f573fSAndroid Build Coastguard Worker             MergeFrom(message, data, offset, length, false, null);
65*1b3f573fSAndroid Build Coastguard Worker 
66*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
67*1b3f573fSAndroid Build Coastguard Worker         /// Merges data from the given byte string into an existing message.
68*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
69*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to merge the data into.</param>
70*1b3f573fSAndroid Build Coastguard Worker         /// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
MergeFrom(this IMessage message, ByteString data)71*1b3f573fSAndroid Build Coastguard Worker         public static void MergeFrom(this IMessage message, ByteString data) =>
72*1b3f573fSAndroid Build Coastguard Worker             MergeFrom(message, data, false, null);
73*1b3f573fSAndroid Build Coastguard Worker 
74*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
75*1b3f573fSAndroid Build Coastguard Worker         /// Merges data from the given stream into an existing message.
76*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
77*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to merge the data into.</param>
78*1b3f573fSAndroid Build Coastguard Worker         /// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
MergeFrom(this IMessage message, Stream input)79*1b3f573fSAndroid Build Coastguard Worker         public static void MergeFrom(this IMessage message, Stream input) =>
80*1b3f573fSAndroid Build Coastguard Worker             MergeFrom(message, input, false, null);
81*1b3f573fSAndroid Build Coastguard Worker 
82*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
83*1b3f573fSAndroid Build Coastguard Worker         /// Merges data from the given span into an existing message.
84*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
85*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to merge the data into.</param>
86*1b3f573fSAndroid Build Coastguard Worker         /// <param name="span">Span containing the data to merge, which must be protobuf-encoded binary data.</param>
87*1b3f573fSAndroid Build Coastguard Worker         [SecuritySafeCritical]
MergeFrom(this IMessage message, ReadOnlySpan<byte> span)88*1b3f573fSAndroid Build Coastguard Worker         public static void MergeFrom(this IMessage message, ReadOnlySpan<byte> span) =>
89*1b3f573fSAndroid Build Coastguard Worker             MergeFrom(message, span, false, null);
90*1b3f573fSAndroid Build Coastguard Worker 
91*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
92*1b3f573fSAndroid Build Coastguard Worker         /// Merges length-delimited data from the given stream into an existing message.
93*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
94*1b3f573fSAndroid Build Coastguard Worker         /// <remarks>
95*1b3f573fSAndroid Build Coastguard Worker         /// The stream is expected to contain a length and then the data. Only the amount of data
96*1b3f573fSAndroid Build Coastguard Worker         /// specified by the length will be consumed.
97*1b3f573fSAndroid Build Coastguard Worker         /// </remarks>
98*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to merge the data into.</param>
99*1b3f573fSAndroid Build Coastguard Worker         /// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
MergeDelimitedFrom(this IMessage message, Stream input)100*1b3f573fSAndroid Build Coastguard Worker         public static void MergeDelimitedFrom(this IMessage message, Stream input) =>
101*1b3f573fSAndroid Build Coastguard Worker             MergeDelimitedFrom(message, input, false, null);
102*1b3f573fSAndroid Build Coastguard Worker 
103*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
104*1b3f573fSAndroid Build Coastguard Worker         /// Converts the given message into a byte array in protobuf encoding.
105*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
106*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to convert.</param>
107*1b3f573fSAndroid Build Coastguard Worker         /// <returns>The message data as a byte array.</returns>
ToByteArray(this IMessage message)108*1b3f573fSAndroid Build Coastguard Worker         public static byte[] ToByteArray(this IMessage message)
109*1b3f573fSAndroid Build Coastguard Worker         {
110*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
111*1b3f573fSAndroid Build Coastguard Worker             byte[] result = new byte[message.CalculateSize()];
112*1b3f573fSAndroid Build Coastguard Worker             CodedOutputStream output = new CodedOutputStream(result);
113*1b3f573fSAndroid Build Coastguard Worker             message.WriteTo(output);
114*1b3f573fSAndroid Build Coastguard Worker             output.CheckNoSpaceLeft();
115*1b3f573fSAndroid Build Coastguard Worker             return result;
116*1b3f573fSAndroid Build Coastguard Worker         }
117*1b3f573fSAndroid Build Coastguard Worker 
118*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
119*1b3f573fSAndroid Build Coastguard Worker         /// Writes the given message data to the given stream in protobuf encoding.
120*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
121*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to write to the stream.</param>
122*1b3f573fSAndroid Build Coastguard Worker         /// <param name="output">The stream to write to.</param>
WriteTo(this IMessage message, Stream output)123*1b3f573fSAndroid Build Coastguard Worker         public static void WriteTo(this IMessage message, Stream output)
124*1b3f573fSAndroid Build Coastguard Worker         {
125*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
126*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(output, "output");
127*1b3f573fSAndroid Build Coastguard Worker             CodedOutputStream codedOutput = new CodedOutputStream(output);
128*1b3f573fSAndroid Build Coastguard Worker             message.WriteTo(codedOutput);
129*1b3f573fSAndroid Build Coastguard Worker             codedOutput.Flush();
130*1b3f573fSAndroid Build Coastguard Worker         }
131*1b3f573fSAndroid Build Coastguard Worker 
132*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
133*1b3f573fSAndroid Build Coastguard Worker         /// Writes the length and then data of the given message to a stream.
134*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
135*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to write.</param>
136*1b3f573fSAndroid Build Coastguard Worker         /// <param name="output">The output stream to write to.</param>
WriteDelimitedTo(this IMessage message, Stream output)137*1b3f573fSAndroid Build Coastguard Worker         public static void WriteDelimitedTo(this IMessage message, Stream output)
138*1b3f573fSAndroid Build Coastguard Worker         {
139*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
140*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(output, "output");
141*1b3f573fSAndroid Build Coastguard Worker             CodedOutputStream codedOutput = new CodedOutputStream(output);
142*1b3f573fSAndroid Build Coastguard Worker             codedOutput.WriteLength(message.CalculateSize());
143*1b3f573fSAndroid Build Coastguard Worker             message.WriteTo(codedOutput);
144*1b3f573fSAndroid Build Coastguard Worker             codedOutput.Flush();
145*1b3f573fSAndroid Build Coastguard Worker         }
146*1b3f573fSAndroid Build Coastguard Worker 
147*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
148*1b3f573fSAndroid Build Coastguard Worker         /// Converts the given message into a byte string in protobuf encoding.
149*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
150*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to convert.</param>
151*1b3f573fSAndroid Build Coastguard Worker         /// <returns>The message data as a byte string.</returns>
ToByteString(this IMessage message)152*1b3f573fSAndroid Build Coastguard Worker         public static ByteString ToByteString(this IMessage message)
153*1b3f573fSAndroid Build Coastguard Worker         {
154*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
155*1b3f573fSAndroid Build Coastguard Worker             return ByteString.AttachBytes(message.ToByteArray());
156*1b3f573fSAndroid Build Coastguard Worker         }
157*1b3f573fSAndroid Build Coastguard Worker 
158*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
159*1b3f573fSAndroid Build Coastguard Worker         /// Writes the given message data to the given buffer writer in protobuf encoding.
160*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
161*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to write to the stream.</param>
162*1b3f573fSAndroid Build Coastguard Worker         /// <param name="output">The stream to write to.</param>
163*1b3f573fSAndroid Build Coastguard Worker         [SecuritySafeCritical]
WriteTo(this IMessage message, IBufferWriter<byte> output)164*1b3f573fSAndroid Build Coastguard Worker         public static void WriteTo(this IMessage message, IBufferWriter<byte> output)
165*1b3f573fSAndroid Build Coastguard Worker         {
166*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, nameof(message));
167*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(output, nameof(output));
168*1b3f573fSAndroid Build Coastguard Worker 
169*1b3f573fSAndroid Build Coastguard Worker             WriteContext.Initialize(output, out WriteContext ctx);
170*1b3f573fSAndroid Build Coastguard Worker             WritingPrimitivesMessages.WriteRawMessage(ref ctx, message);
171*1b3f573fSAndroid Build Coastguard Worker             ctx.Flush();
172*1b3f573fSAndroid Build Coastguard Worker         }
173*1b3f573fSAndroid Build Coastguard Worker 
174*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
175*1b3f573fSAndroid Build Coastguard Worker         /// Writes the given message data to the given span in protobuf encoding.
176*1b3f573fSAndroid Build Coastguard Worker         /// The size of the destination span needs to fit the serialized size
177*1b3f573fSAndroid Build Coastguard Worker         /// of the message exactly, otherwise an exception is thrown.
178*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
179*1b3f573fSAndroid Build Coastguard Worker         /// <param name="message">The message to write to the stream.</param>
180*1b3f573fSAndroid Build Coastguard Worker         /// <param name="output">The span to write to. Size must match size of the message exactly.</param>
181*1b3f573fSAndroid Build Coastguard Worker         [SecuritySafeCritical]
WriteTo(this IMessage message, Span<byte> output)182*1b3f573fSAndroid Build Coastguard Worker         public static void WriteTo(this IMessage message, Span<byte> output)
183*1b3f573fSAndroid Build Coastguard Worker         {
184*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, nameof(message));
185*1b3f573fSAndroid Build Coastguard Worker 
186*1b3f573fSAndroid Build Coastguard Worker             WriteContext.Initialize(ref output, out WriteContext ctx);
187*1b3f573fSAndroid Build Coastguard Worker             WritingPrimitivesMessages.WriteRawMessage(ref ctx, message);
188*1b3f573fSAndroid Build Coastguard Worker             ctx.CheckNoSpaceLeft();
189*1b3f573fSAndroid Build Coastguard Worker         }
190*1b3f573fSAndroid Build Coastguard Worker 
191*1b3f573fSAndroid Build Coastguard Worker         /// <summary>
192*1b3f573fSAndroid Build Coastguard Worker         /// Checks if all required fields in a message have values set. For proto3 messages, this returns true
193*1b3f573fSAndroid Build Coastguard Worker         /// </summary>
IsInitialized(this IMessage message)194*1b3f573fSAndroid Build Coastguard Worker         public static bool IsInitialized(this IMessage message)
195*1b3f573fSAndroid Build Coastguard Worker         {
196*1b3f573fSAndroid Build Coastguard Worker             if (message.Descriptor.File.Syntax == Syntax.Proto3)
197*1b3f573fSAndroid Build Coastguard Worker             {
198*1b3f573fSAndroid Build Coastguard Worker                 return true;
199*1b3f573fSAndroid Build Coastguard Worker             }
200*1b3f573fSAndroid Build Coastguard Worker 
201*1b3f573fSAndroid Build Coastguard Worker             if (!message.Descriptor.IsExtensionsInitialized(message))
202*1b3f573fSAndroid Build Coastguard Worker             {
203*1b3f573fSAndroid Build Coastguard Worker                 return false;
204*1b3f573fSAndroid Build Coastguard Worker             }
205*1b3f573fSAndroid Build Coastguard Worker 
206*1b3f573fSAndroid Build Coastguard Worker             return message.Descriptor
207*1b3f573fSAndroid Build Coastguard Worker                 .Fields
208*1b3f573fSAndroid Build Coastguard Worker                 .InDeclarationOrder()
209*1b3f573fSAndroid Build Coastguard Worker                 .All(f =>
210*1b3f573fSAndroid Build Coastguard Worker                 {
211*1b3f573fSAndroid Build Coastguard Worker                     if (f.IsMap)
212*1b3f573fSAndroid Build Coastguard Worker                     {
213*1b3f573fSAndroid Build Coastguard Worker                         var valueField = f.MessageType.Fields[2];
214*1b3f573fSAndroid Build Coastguard Worker                         if (valueField.FieldType == FieldType.Message)
215*1b3f573fSAndroid Build Coastguard Worker                         {
216*1b3f573fSAndroid Build Coastguard Worker                             var map = (IDictionary)f.Accessor.GetValue(message);
217*1b3f573fSAndroid Build Coastguard Worker                             return map.Values.Cast<IMessage>().All(IsInitialized);
218*1b3f573fSAndroid Build Coastguard Worker                         }
219*1b3f573fSAndroid Build Coastguard Worker                         else
220*1b3f573fSAndroid Build Coastguard Worker                         {
221*1b3f573fSAndroid Build Coastguard Worker                             return true;
222*1b3f573fSAndroid Build Coastguard Worker                         }
223*1b3f573fSAndroid Build Coastguard Worker                     }
224*1b3f573fSAndroid Build Coastguard Worker                     else if (f.IsRepeated && f.FieldType == FieldType.Message || f.FieldType == FieldType.Group)
225*1b3f573fSAndroid Build Coastguard Worker                     {
226*1b3f573fSAndroid Build Coastguard Worker                         var enumerable = (IEnumerable)f.Accessor.GetValue(message);
227*1b3f573fSAndroid Build Coastguard Worker                         return enumerable.Cast<IMessage>().All(IsInitialized);
228*1b3f573fSAndroid Build Coastguard Worker                     }
229*1b3f573fSAndroid Build Coastguard Worker                     else if (f.FieldType == FieldType.Message || f.FieldType == FieldType.Group)
230*1b3f573fSAndroid Build Coastguard Worker                     {
231*1b3f573fSAndroid Build Coastguard Worker                         if (f.Accessor.HasValue(message))
232*1b3f573fSAndroid Build Coastguard Worker                         {
233*1b3f573fSAndroid Build Coastguard Worker                             return ((IMessage)f.Accessor.GetValue(message)).IsInitialized();
234*1b3f573fSAndroid Build Coastguard Worker                         }
235*1b3f573fSAndroid Build Coastguard Worker                         else
236*1b3f573fSAndroid Build Coastguard Worker                         {
237*1b3f573fSAndroid Build Coastguard Worker                             return !f.IsRequired;
238*1b3f573fSAndroid Build Coastguard Worker                         }
239*1b3f573fSAndroid Build Coastguard Worker                     }
240*1b3f573fSAndroid Build Coastguard Worker                     else if (f.IsRequired)
241*1b3f573fSAndroid Build Coastguard Worker                     {
242*1b3f573fSAndroid Build Coastguard Worker                         return f.Accessor.HasValue(message);
243*1b3f573fSAndroid Build Coastguard Worker                     }
244*1b3f573fSAndroid Build Coastguard Worker                     else
245*1b3f573fSAndroid Build Coastguard Worker                     {
246*1b3f573fSAndroid Build Coastguard Worker                         return true;
247*1b3f573fSAndroid Build Coastguard Worker                     }
248*1b3f573fSAndroid Build Coastguard Worker                 });
249*1b3f573fSAndroid Build Coastguard Worker         }
250*1b3f573fSAndroid Build Coastguard Worker 
251*1b3f573fSAndroid Build Coastguard Worker         // Implementations allowing unknown fields to be discarded.
MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry)252*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry)
253*1b3f573fSAndroid Build Coastguard Worker         {
254*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
255*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(data, "data");
256*1b3f573fSAndroid Build Coastguard Worker             CodedInputStream input = new CodedInputStream(data);
257*1b3f573fSAndroid Build Coastguard Worker             input.DiscardUnknownFields = discardUnknownFields;
258*1b3f573fSAndroid Build Coastguard Worker             input.ExtensionRegistry = registry;
259*1b3f573fSAndroid Build Coastguard Worker             message.MergeFrom(input);
260*1b3f573fSAndroid Build Coastguard Worker             input.CheckReadEndOfStreamTag();
261*1b3f573fSAndroid Build Coastguard Worker         }
262*1b3f573fSAndroid Build Coastguard Worker 
MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry)263*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry)
264*1b3f573fSAndroid Build Coastguard Worker         {
265*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
266*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(data, "data");
267*1b3f573fSAndroid Build Coastguard Worker             CodedInputStream input = new CodedInputStream(data, offset, length);
268*1b3f573fSAndroid Build Coastguard Worker             input.DiscardUnknownFields = discardUnknownFields;
269*1b3f573fSAndroid Build Coastguard Worker             input.ExtensionRegistry = registry;
270*1b3f573fSAndroid Build Coastguard Worker             message.MergeFrom(input);
271*1b3f573fSAndroid Build Coastguard Worker             input.CheckReadEndOfStreamTag();
272*1b3f573fSAndroid Build Coastguard Worker         }
273*1b3f573fSAndroid Build Coastguard Worker 
MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry)274*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry)
275*1b3f573fSAndroid Build Coastguard Worker         {
276*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
277*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(data, "data");
278*1b3f573fSAndroid Build Coastguard Worker             CodedInputStream input = data.CreateCodedInput();
279*1b3f573fSAndroid Build Coastguard Worker             input.DiscardUnknownFields = discardUnknownFields;
280*1b3f573fSAndroid Build Coastguard Worker             input.ExtensionRegistry = registry;
281*1b3f573fSAndroid Build Coastguard Worker             message.MergeFrom(input);
282*1b3f573fSAndroid Build Coastguard Worker             input.CheckReadEndOfStreamTag();
283*1b3f573fSAndroid Build Coastguard Worker         }
284*1b3f573fSAndroid Build Coastguard Worker 
MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)285*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)
286*1b3f573fSAndroid Build Coastguard Worker         {
287*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
288*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(input, "input");
289*1b3f573fSAndroid Build Coastguard Worker             CodedInputStream codedInput = new CodedInputStream(input);
290*1b3f573fSAndroid Build Coastguard Worker             codedInput.DiscardUnknownFields = discardUnknownFields;
291*1b3f573fSAndroid Build Coastguard Worker             codedInput.ExtensionRegistry = registry;
292*1b3f573fSAndroid Build Coastguard Worker             message.MergeFrom(codedInput);
293*1b3f573fSAndroid Build Coastguard Worker             codedInput.CheckReadEndOfStreamTag();
294*1b3f573fSAndroid Build Coastguard Worker         }
295*1b3f573fSAndroid Build Coastguard Worker 
296*1b3f573fSAndroid Build Coastguard Worker         [SecuritySafeCritical]
MergeFrom(this IMessage message, ReadOnlySequence<byte> data, bool discardUnknownFields, ExtensionRegistry registry)297*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeFrom(this IMessage message, ReadOnlySequence<byte> data, bool discardUnknownFields, ExtensionRegistry registry)
298*1b3f573fSAndroid Build Coastguard Worker         {
299*1b3f573fSAndroid Build Coastguard Worker             ParseContext.Initialize(data, out ParseContext ctx);
300*1b3f573fSAndroid Build Coastguard Worker             ctx.DiscardUnknownFields = discardUnknownFields;
301*1b3f573fSAndroid Build Coastguard Worker             ctx.ExtensionRegistry = registry;
302*1b3f573fSAndroid Build Coastguard Worker             ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message);
303*1b3f573fSAndroid Build Coastguard Worker             ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state);
304*1b3f573fSAndroid Build Coastguard Worker         }
305*1b3f573fSAndroid Build Coastguard Worker 
306*1b3f573fSAndroid Build Coastguard Worker         [SecuritySafeCritical]
MergeFrom(this IMessage message, ReadOnlySpan<byte> data, bool discardUnknownFields, ExtensionRegistry registry)307*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeFrom(this IMessage message, ReadOnlySpan<byte> data, bool discardUnknownFields, ExtensionRegistry registry)
308*1b3f573fSAndroid Build Coastguard Worker         {
309*1b3f573fSAndroid Build Coastguard Worker             ParseContext.Initialize(data, out ParseContext ctx);
310*1b3f573fSAndroid Build Coastguard Worker             ctx.DiscardUnknownFields = discardUnknownFields;
311*1b3f573fSAndroid Build Coastguard Worker             ctx.ExtensionRegistry = registry;
312*1b3f573fSAndroid Build Coastguard Worker             ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message);
313*1b3f573fSAndroid Build Coastguard Worker             ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state);
314*1b3f573fSAndroid Build Coastguard Worker         }
315*1b3f573fSAndroid Build Coastguard Worker 
MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)316*1b3f573fSAndroid Build Coastguard Worker         internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry)
317*1b3f573fSAndroid Build Coastguard Worker         {
318*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(message, "message");
319*1b3f573fSAndroid Build Coastguard Worker             ProtoPreconditions.CheckNotNull(input, "input");
320*1b3f573fSAndroid Build Coastguard Worker             int size = (int) CodedInputStream.ReadRawVarint32(input);
321*1b3f573fSAndroid Build Coastguard Worker             Stream limitedStream = new LimitedInputStream(input, size);
322*1b3f573fSAndroid Build Coastguard Worker             MergeFrom(message, limitedStream, discardUnknownFields, registry);
323*1b3f573fSAndroid Build Coastguard Worker         }
324*1b3f573fSAndroid Build Coastguard Worker     }
325*1b3f573fSAndroid Build Coastguard Worker }
326