using System; using System.Buffers; using System.Buffers.Binary; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Google.Protobuf.Collections; using Google.Protobuf.Reflection; using Google.Protobuf.WellKnownTypes; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a17c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dcb6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665c5ae9cb6")] [assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a17c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dcb6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665c5ae9cb6")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: AssemblyCompany("Google Inc.")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2015, Google Inc.")] [assembly: AssemblyDescription("C# runtime library for Protocol Buffers - Google's data interchange format.")] [assembly: AssemblyFileVersion("3.21.9.0")] [assembly: AssemblyInformationalVersion("3.21.9+d96db0e9d8ef9e9c754ee1ffac58654969f3b662")] [assembly: AssemblyProduct("Google.Protobuf")] [assembly: AssemblyTitle("Google Protocol Buffers")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/protocolbuffers/protobuf.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.21.9.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)] internal sealed class DynamicallyAccessedMembersAttribute : Attribute { public DynamicallyAccessedMemberTypes MemberTypes { get; } public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) { MemberTypes = memberTypes; } } [Flags] internal enum DynamicallyAccessedMemberTypes { None = 0, PublicParameterlessConstructor = 1, PublicConstructors = 3, NonPublicConstructors = 4, PublicMethods = 8, NonPublicMethods = 0x10, PublicFields = 0x20, NonPublicFields = 0x40, PublicNestedTypes = 0x80, NonPublicNestedTypes = 0x100, PublicProperties = 0x200, NonPublicProperties = 0x400, PublicEvents = 0x800, NonPublicEvents = 0x1000, Interfaces = 0x2000, All = -1 } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)] internal sealed class RequiresUnreferencedCodeAttribute : Attribute { public string Message { get; } public string Url { get; set; } public RequiresUnreferencedCodeAttribute(string message) { Message = message; } } [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] internal sealed class UnconditionalSuppressMessageAttribute : Attribute { public string Category { get; } public string CheckId { get; } public string Scope { get; set; } public string Target { get; set; } public string MessageId { get; set; } public string Justification { get; set; } public UnconditionalSuppressMessageAttribute(string category, string checkId) { Category = category; CheckId = checkId; } } } namespace Google.Protobuf { internal static class ByteArray { private const int CopyThreshold = 12; internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count) { if (count > 12) { Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count); return; } int num = srcOffset + count; for (int i = srcOffset; i < num; i++) { dst[dstOffset++] = src[i]; } } internal static void Reverse(byte[] bytes) { int num = 0; int num2 = bytes.Length - 1; while (num < num2) { byte b = bytes[num]; bytes[num] = bytes[num2]; bytes[num2] = b; num++; num2--; } } } [SecuritySafeCritical] public sealed class ByteString : IEnumerable, IEnumerable, IEquatable { private static readonly ByteString empty = new ByteString(new byte[0]); private readonly ReadOnlyMemory bytes; public static ByteString Empty => empty; public int Length => bytes.Length; public bool IsEmpty => Length == 0; public ReadOnlySpan Span => bytes.Span; public ReadOnlyMemory Memory => bytes; public byte this[int index] => bytes.Span[index]; internal static ByteString AttachBytes(ReadOnlyMemory bytes) { return new ByteString(bytes); } internal static ByteString AttachBytes(byte[] bytes) { return AttachBytes(bytes.AsMemory()); } private ByteString(ReadOnlyMemory bytes) { this.bytes = bytes; } public byte[] ToByteArray() { return bytes.ToArray(); } public string ToBase64() { if (MemoryMarshal.TryGetArray(bytes, out var segment)) { return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count); } return Convert.ToBase64String(bytes.ToArray()); } public static ByteString FromBase64(string bytes) { if (!(bytes == "")) { return new ByteString(Convert.FromBase64String(bytes)); } return Empty; } public static ByteString FromStream(Stream stream) { ProtoPreconditions.CheckNotNull(stream, "stream"); MemoryStream memoryStream = new MemoryStream(stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0); stream.CopyTo(memoryStream); return AttachBytes(memoryStream.ToArray()); } public static Task FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { ProtoPreconditions.CheckNotNull(stream, "stream"); return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); } public static ByteString CopyFrom(params byte[] bytes) { return new ByteString((byte[])bytes.Clone()); } public static ByteString CopyFrom(byte[] bytes, int offset, int count) { byte[] array = new byte[count]; ByteArray.Copy(bytes, offset, array, 0, count); return new ByteString(array); } public static ByteString CopyFrom(ReadOnlySpan bytes) { return new ByteString(bytes.ToArray()); } public static ByteString CopyFrom(string text, Encoding encoding) { return new ByteString(encoding.GetBytes(text)); } public static ByteString CopyFromUtf8(string text) { return CopyFrom(text, Encoding.UTF8); } public string ToString(Encoding encoding) { if (MemoryMarshal.TryGetArray(bytes, out var segment)) { return encoding.GetString(segment.Array, segment.Offset, segment.Count); } byte[] array = bytes.ToArray(); return encoding.GetString(array, 0, array.Length); } public string ToStringUtf8() { return ToString(Encoding.UTF8); } [SecuritySafeCritical] public IEnumerator GetEnumerator() { return MemoryMarshal.ToEnumerable(bytes).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public CodedInputStream CreateCodedInput() { if (MemoryMarshal.TryGetArray(bytes, out var segment) && segment.Count == bytes.Length) { return new CodedInputStream(segment.Array, segment.Offset, segment.Count); } return new CodedInputStream(bytes.ToArray()); } public static bool operator ==(ByteString lhs, ByteString rhs) { if ((object)lhs == rhs) { return true; } if ((object)lhs == null || (object)rhs == null) { return false; } return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span); } public static bool operator !=(ByteString lhs, ByteString rhs) { return !(lhs == rhs); } [SecuritySafeCritical] public override bool Equals(object obj) { return this == obj as ByteString; } [SecuritySafeCritical] public override int GetHashCode() { ReadOnlySpan span = bytes.Span; int num = 23; for (int i = 0; i < span.Length; i++) { num = num * 31 + span[i]; } return num; } public bool Equals(ByteString other) { return this == other; } public void CopyTo(byte[] array, int position) { bytes.CopyTo(array.AsMemory(position)); } public void WriteTo(Stream outputStream) { if (MemoryMarshal.TryGetArray(bytes, out var segment)) { outputStream.Write(segment.Array, segment.Offset, segment.Count); return; } byte[] array = bytes.ToArray(); outputStream.Write(array, 0, array.Length); } } internal static class ByteStringAsync { internal static async Task FromStreamAsyncCore(Stream stream, CancellationToken cancellationToken) { int capacity = (stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0); MemoryStream memoryStream = new MemoryStream(capacity); await stream.CopyToAsync(memoryStream, 81920, cancellationToken); return ByteString.AttachBytes((memoryStream.Length == memoryStream.Capacity) ? memoryStream.GetBuffer() : memoryStream.ToArray()); } } [SecuritySafeCritical] public sealed class CodedInputStream : IDisposable { private readonly bool leaveOpen; private readonly byte[] buffer; private readonly Stream input; private ParserInternalState state; internal const int DefaultRecursionLimit = 100; internal const int DefaultSizeLimit = int.MaxValue; internal const int BufferSize = 4096; public long Position { get { if (input != null) { return input.Position - (state.bufferSize + state.bufferSizeAfterLimit - state.bufferPos); } return state.bufferPos; } } internal uint LastTag => state.lastTag; public int SizeLimit => state.sizeLimit; public int RecursionLimit => state.recursionLimit; internal bool DiscardUnknownFields { get { return state.DiscardUnknownFields; } set { state.DiscardUnknownFields = value; } } internal ExtensionRegistry ExtensionRegistry { get { return state.ExtensionRegistry; } set { state.ExtensionRegistry = value; } } internal byte[] InternalBuffer => buffer; internal Stream InternalInputStream => input; internal ref ParserInternalState InternalState => ref state; internal bool ReachedLimit => SegmentedBufferHelper.IsReachedLimit(ref state); public bool IsAtEnd { get { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return SegmentedBufferHelper.IsAtEnd(ref readOnlySpan, ref state); } } public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length, leaveOpen: true) { } public CodedInputStream(byte[] buffer, int offset, int length) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length, leaveOpen: true) { if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset", "Offset must be within the buffer"); } if (length < 0 || offset + length > buffer.Length) { throw new ArgumentOutOfRangeException("length", "Length must be non-negative and within the buffer"); } } public CodedInputStream(Stream input) : this(input, leaveOpen: false) { } public CodedInputStream(Stream input, bool leaveOpen) : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[4096], 0, 0, leaveOpen) { } internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, bool leaveOpen) { this.input = input; this.buffer = buffer; state.bufferPos = bufferPos; state.bufferSize = bufferSize; state.sizeLimit = int.MaxValue; state.recursionLimit = 100; SegmentedBufferHelper.Initialize(this, out state.segmentedBufferHelper); this.leaveOpen = leaveOpen; state.currentLimit = int.MaxValue; } internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit, bool leaveOpen) : this(input, buffer, bufferPos, bufferSize, leaveOpen) { if (sizeLimit <= 0) { throw new ArgumentOutOfRangeException("sizeLimit", "Size limit must be positive"); } if (recursionLimit <= 0) { throw new ArgumentOutOfRangeException("recursionLimit!", "Recursion limit must be positive"); } state.sizeLimit = sizeLimit; state.recursionLimit = recursionLimit; } public static CodedInputStream CreateWithLimits(Stream input, int sizeLimit, int recursionLimit) { return new CodedInputStream(input, new byte[4096], 0, 0, sizeLimit, recursionLimit, leaveOpen: false); } public void Dispose() { if (!leaveOpen) { input.Dispose(); } } internal void CheckReadEndOfStreamTag() { ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref state); } public uint PeekTag() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.PeekTag(ref readOnlySpan, ref state); } public uint ReadTag() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseTag(ref readOnlySpan, ref state); } public void SkipLastField() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); ParsingPrimitivesMessages.SkipLastField(ref readOnlySpan, ref state); } internal void SkipGroup(uint startGroupTag) { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); ParsingPrimitivesMessages.SkipGroup(ref readOnlySpan, ref state, startGroupTag); } public double ReadDouble() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseDouble(ref readOnlySpan, ref state); } public float ReadFloat() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseFloat(ref readOnlySpan, ref state); } public ulong ReadUInt64() { return ReadRawVarint64(); } public long ReadInt64() { return (long)ReadRawVarint64(); } public int ReadInt32() { return (int)ReadRawVarint32(); } public ulong ReadFixed64() { return ReadRawLittleEndian64(); } public uint ReadFixed32() { return ReadRawLittleEndian32(); } public bool ReadBool() { return ReadRawVarint64() != 0; } public string ReadString() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ReadString(ref readOnlySpan, ref state); } public void ReadMessage(IMessage builder) { ParseContext.Initialize(buffer.AsSpan(), ref state, out var ctx); try { ParsingPrimitivesMessages.ReadMessage(ref ctx, builder); } finally { ctx.CopyStateTo(this); } } public void ReadGroup(IMessage builder) { ParseContext.Initialize(this, out var ctx); try { ParsingPrimitivesMessages.ReadGroup(ref ctx, builder); } finally { ctx.CopyStateTo(this); } } public ByteString ReadBytes() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ReadBytes(ref readOnlySpan, ref state); } public uint ReadUInt32() { return ReadRawVarint32(); } public int ReadEnum() { return (int)ReadRawVarint32(); } public int ReadSFixed32() { return (int)ReadRawLittleEndian32(); } public long ReadSFixed64() { return (long)ReadRawLittleEndian64(); } public int ReadSInt32() { return ParsingPrimitives.DecodeZigZag32(ReadRawVarint32()); } public long ReadSInt64() { return ParsingPrimitives.DecodeZigZag64(ReadRawVarint64()); } public int ReadLength() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseLength(ref readOnlySpan, ref state); } public bool MaybeConsumeTag(uint tag) { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.MaybeConsumeTag(ref readOnlySpan, ref state, tag); } internal uint ReadRawVarint32() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseRawVarint32(ref readOnlySpan, ref state); } internal static uint ReadRawVarint32(Stream input) { return ParsingPrimitives.ReadRawVarint32(input); } internal ulong ReadRawVarint64() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseRawVarint64(ref readOnlySpan, ref state); } internal uint ReadRawLittleEndian32() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseRawLittleEndian32(ref readOnlySpan, ref state); } internal ulong ReadRawLittleEndian64() { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ParseRawLittleEndian64(ref readOnlySpan, ref state); } internal int PushLimit(int byteLimit) { return SegmentedBufferHelper.PushLimit(ref state, byteLimit); } internal void PopLimit(int oldLimit) { SegmentedBufferHelper.PopLimit(ref state, oldLimit); } private bool RefillBuffer(bool mustSucceed) { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return state.segmentedBufferHelper.RefillBuffer(ref readOnlySpan, ref state, mustSucceed); } internal byte[] ReadRawBytes(int size) { ReadOnlySpan readOnlySpan = new ReadOnlySpan(buffer); return ParsingPrimitives.ReadRawBytes(ref readOnlySpan, ref state, size); } public void ReadRawMessage(IMessage message) { ParseContext.Initialize(this, out var ctx); try { ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message); } finally { ctx.CopyStateTo(this); } } } [SecuritySafeCritical] public sealed class CodedOutputStream : IDisposable { public sealed class OutOfSpaceException : IOException { internal OutOfSpaceException() : base("CodedOutputStream was writing to a flat byte array and ran out of space.") { } } private const int LittleEndian64Size = 8; private const int LittleEndian32Size = 4; internal const int DoubleSize = 8; internal const int FloatSize = 4; internal const int BoolSize = 1; public static readonly int DefaultBufferSize = 4096; private readonly bool leaveOpen; private readonly byte[] buffer; private WriterInternalState state; private readonly Stream output; public long Position { get { if (output != null) { return output.Position + state.position; } return state.position; } } public int SpaceLeft => WriteBufferHelper.GetSpaceLeft(ref state); internal byte[] InternalBuffer => buffer; internal Stream InternalOutputStream => output; internal ref WriterInternalState InternalState => ref state; public static int ComputeDoubleSize(double value) { return 8; } public static int ComputeFloatSize(float value) { return 4; } public static int ComputeUInt64Size(ulong value) { return ComputeRawVarint64Size(value); } public static int ComputeInt64Size(long value) { return ComputeRawVarint64Size((ulong)value); } public static int ComputeInt32Size(int value) { if (value >= 0) { return ComputeRawVarint32Size((uint)value); } return 10; } public static int ComputeFixed64Size(ulong value) { return 8; } public static int ComputeFixed32Size(uint value) { return 4; } public static int ComputeBoolSize(bool value) { return 1; } public static int ComputeStringSize(string value) { int byteCount = WritingPrimitives.Utf8Encoding.GetByteCount(value); return ComputeLengthSize(byteCount) + byteCount; } public static int ComputeGroupSize(IMessage value) { return value.CalculateSize(); } public static int ComputeMessageSize(IMessage value) { int num = value.CalculateSize(); return ComputeLengthSize(num) + num; } public static int ComputeBytesSize(ByteString value) { return ComputeLengthSize(value.Length) + value.Length; } public static int ComputeUInt32Size(uint value) { return ComputeRawVarint32Size(value); } public static int ComputeEnumSize(int value) { return ComputeInt32Size(value); } public static int ComputeSFixed32Size(int value) { return 4; } public static int ComputeSFixed64Size(long value) { return 8; } public static int ComputeSInt32Size(int value) { return ComputeRawVarint32Size(WritingPrimitives.EncodeZigZag32(value)); } public static int ComputeSInt64Size(long value) { return ComputeRawVarint64Size(WritingPrimitives.EncodeZigZag64(value)); } public static int ComputeLengthSize(int length) { return ComputeRawVarint32Size((uint)length); } public static int ComputeRawVarint32Size(uint value) { if ((value & 0xFFFFFF80u) == 0) { return 1; } if ((value & 0xFFFFC000u) == 0) { return 2; } if ((value & 0xFFE00000u) == 0) { return 3; } if ((value & 0xF0000000u) == 0) { return 4; } return 5; } public static int ComputeRawVarint64Size(ulong value) { if ((value & 0xFFFFFFFFFFFFFF80uL) == 0L) { return 1; } if ((value & 0xFFFFFFFFFFFFC000uL) == 0L) { return 2; } if ((value & 0xFFFFFFFFFFE00000uL) == 0L) { return 3; } if ((value & 0xFFFFFFFFF0000000uL) == 0L) { return 4; } if ((value & 0xFFFFFFF800000000uL) == 0L) { return 5; } if ((value & 0xFFFFFC0000000000uL) == 0L) { return 6; } if ((value & 0xFFFE000000000000uL) == 0L) { return 7; } if ((value & 0xFF00000000000000uL) == 0L) { return 8; } if ((value & 0x8000000000000000uL) == 0L) { return 9; } return 10; } public static int ComputeTagSize(int fieldNumber) { return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.Varint)); } public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length) { } private CodedOutputStream(byte[] buffer, int offset, int length) { output = null; this.buffer = ProtoPreconditions.CheckNotNull(buffer, "buffer"); state.position = offset; state.limit = offset + length; WriteBufferHelper.Initialize(this, out state.writeBufferHelper); leaveOpen = true; } private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen) { this.output = ProtoPreconditions.CheckNotNull(output, "output"); this.buffer = buffer; state.position = 0; state.limit = buffer.Length; WriteBufferHelper.Initialize(this, out state.writeBufferHelper); this.leaveOpen = leaveOpen; } public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, leaveOpen: false) { } public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], leaveOpen: false) { } public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen) { } public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen) { } public void WriteDouble(double value) { Span span = new Span(buffer); WritingPrimitives.WriteDouble(ref span, ref state, value); } public void WriteFloat(float value) { Span span = new Span(buffer); WritingPrimitives.WriteFloat(ref span, ref state, value); } public void WriteUInt64(ulong value) { Span span = new Span(buffer); WritingPrimitives.WriteUInt64(ref span, ref state, value); } public void WriteInt64(long value) { Span span = new Span(buffer); WritingPrimitives.WriteInt64(ref span, ref state, value); } public void WriteInt32(int value) { Span span = new Span(buffer); WritingPrimitives.WriteInt32(ref span, ref state, value); } public void WriteFixed64(ulong value) { Span span = new Span(buffer); WritingPrimitives.WriteFixed64(ref span, ref state, value); } public void WriteFixed32(uint value) { Span span = new Span(buffer); WritingPrimitives.WriteFixed32(ref span, ref state, value); } public void WriteBool(bool value) { Span span = new Span(buffer); WritingPrimitives.WriteBool(ref span, ref state, value); } public void WriteString(string value) { Span span = new Span(buffer); WritingPrimitives.WriteString(ref span, ref state, value); } public void WriteMessage(IMessage value) { Span span = new Span(buffer); WriteContext.Initialize(ref span, ref state, out var ctx); try { WritingPrimitivesMessages.WriteMessage(ref ctx, value); } finally { ctx.CopyStateTo(this); } } public void WriteRawMessage(IMessage value) { Span span = new Span(buffer); WriteContext.Initialize(ref span, ref state, out var ctx); try { WritingPrimitivesMessages.WriteRawMessage(ref ctx, value); } finally { ctx.CopyStateTo(this); } } public void WriteGroup(IMessage value) { Span span = new Span(buffer); WriteContext.Initialize(ref span, ref state, out var ctx); try { WritingPrimitivesMessages.WriteGroup(ref ctx, value); } finally { ctx.CopyStateTo(this); } } public void WriteBytes(ByteString value) { Span span = new Span(buffer); WritingPrimitives.WriteBytes(ref span, ref state, value); } public void WriteUInt32(uint value) { Span span = new Span(buffer); WritingPrimitives.WriteUInt32(ref span, ref state, value); } public void WriteEnum(int value) { Span span = new Span(buffer); WritingPrimitives.WriteEnum(ref span, ref state, value); } public void WriteSFixed32(int value) { Span span = new Span(buffer); WritingPrimitives.WriteSFixed32(ref span, ref state, value); } public void WriteSFixed64(long value) { Span span = new Span(buffer); WritingPrimitives.WriteSFixed64(ref span, ref state, value); } public void WriteSInt32(int value) { Span span = new Span(buffer); WritingPrimitives.WriteSInt32(ref span, ref state, value); } public void WriteSInt64(long value) { Span span = new Span(buffer); WritingPrimitives.WriteSInt64(ref span, ref state, value); } public void WriteLength(int length) { Span span = new Span(buffer); WritingPrimitives.WriteLength(ref span, ref state, length); } public void WriteTag(int fieldNumber, WireFormat.WireType type) { Span span = new Span(buffer); WritingPrimitives.WriteTag(ref span, ref state, fieldNumber, type); } public void WriteTag(uint tag) { Span span = new Span(buffer); WritingPrimitives.WriteTag(ref span, ref state, tag); } public void WriteRawTag(byte b1) { Span span = new Span(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1); } public void WriteRawTag(byte b1, byte b2) { Span span = new Span(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2); } public void WriteRawTag(byte b1, byte b2, byte b3) { Span span = new Span(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3); } public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) { Span span = new Span(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4); } public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) { Span span = new Span(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4, b5); } internal void WriteRawVarint32(uint value) { Span span = new Span(buffer); WritingPrimitives.WriteRawVarint32(ref span, ref state, value); } internal void WriteRawVarint64(ulong value) { Span span = new Span(buffer); WritingPrimitives.WriteRawVarint64(ref span, ref state, value); } internal void WriteRawLittleEndian32(uint value) { Span span = new Span(buffer); WritingPrimitives.WriteRawLittleEndian32(ref span, ref state, value); } internal void WriteRawLittleEndian64(ulong value) { Span span = new Span(buffer); WritingPrimitives.WriteRawLittleEndian64(ref span, ref state, value); } internal void WriteRawBytes(byte[] value) { WriteRawBytes(value, 0, value.Length); } internal void WriteRawBytes(byte[] value, int offset, int length) { Span span = new Span(buffer); WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length); } public void Dispose() { Flush(); if (!leaveOpen) { output.Dispose(); } } public void Flush() { Span span = new Span(buffer); WriteBufferHelper.Flush(ref span, ref state); } public void CheckNoSpaceLeft() { WriteBufferHelper.CheckNoSpaceLeft(ref state); } } public abstract class Extension { internal abstract System.Type TargetType { get; } public int FieldNumber { get; } internal abstract bool IsRepeated { get; } protected Extension(int fieldNumber) { FieldNumber = fieldNumber; } internal abstract IExtensionValue CreateValue(); } public sealed class Extension : Extension where TTarget : IExtendableMessage { private readonly FieldCodec codec; internal TValue DefaultValue { get { if (codec == null) { return default(TValue); } return codec.DefaultValue; } } internal override System.Type TargetType => typeof(TTarget); internal override bool IsRepeated => false; public Extension(int fieldNumber, FieldCodec codec) : base(fieldNumber) { this.codec = codec; } internal override IExtensionValue CreateValue() { return new ExtensionValue(codec); } } public sealed class RepeatedExtension : Extension where TTarget : IExtendableMessage { private readonly FieldCodec codec; internal override System.Type TargetType => typeof(TTarget); internal override bool IsRepeated => true; public RepeatedExtension(int fieldNumber, FieldCodec codec) : base(fieldNumber) { this.codec = codec; } internal override IExtensionValue CreateValue() { return new RepeatedExtensionValue(codec); } } public sealed class ExtensionRegistry : ICollection, IEnumerable, IEnumerable, IDeepCloneable { internal sealed class ExtensionComparer : IEqualityComparer { internal static ExtensionComparer Instance = new ExtensionComparer(); public bool Equals(Extension a, Extension b) { return new ObjectIntPair(a.TargetType, a.FieldNumber).Equals(new ObjectIntPair(b.TargetType, b.FieldNumber)); } public int GetHashCode(Extension a) { return new ObjectIntPair(a.TargetType, a.FieldNumber).GetHashCode(); } } private IDictionary, Extension> extensions; public int Count => extensions.Count; bool ICollection.IsReadOnly => false; public ExtensionRegistry() { extensions = new Dictionary, Extension>(); } private ExtensionRegistry(IDictionary, Extension> collection) { extensions = collection.ToDictionary((KeyValuePair, Extension> k) => k.Key, (KeyValuePair, Extension> v) => v.Value); } internal bool ContainsInputField(uint lastTag, System.Type target, out Extension extension) { return extensions.TryGetValue(new ObjectIntPair(target, WireFormat.GetTagFieldNumber(lastTag)), out extension); } public void Add(Extension extension) { ProtoPreconditions.CheckNotNull(extension, "extension"); extensions.Add(new ObjectIntPair(extension.TargetType, extension.FieldNumber), extension); } public void AddRange(IEnumerable extensions) { ProtoPreconditions.CheckNotNull(extensions, "extensions"); foreach (Extension extension in extensions) { Add(extension); } } public void Clear() { extensions.Clear(); } public bool Contains(Extension item) { ProtoPreconditions.CheckNotNull(item, "item"); return extensions.ContainsKey(new ObjectIntPair(item.TargetType, item.FieldNumber)); } void ICollection.CopyTo(Extension[] array, int arrayIndex) { ProtoPreconditions.CheckNotNull(array, "array"); if (arrayIndex < 0 || arrayIndex >= array.Length) { throw new ArgumentOutOfRangeException("arrayIndex"); } if (array.Length - arrayIndex < Count) { throw new ArgumentException("The provided array is shorter than the number of elements in the registry"); } foreach (Extension extension in array) { extensions.Add(new ObjectIntPair(extension.TargetType, extension.FieldNumber), extension); } } public IEnumerator GetEnumerator() { return extensions.Values.GetEnumerator(); } public bool Remove(Extension item) { ProtoPreconditions.CheckNotNull(item, "item"); return extensions.Remove(new ObjectIntPair(item.TargetType, item.FieldNumber)); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public ExtensionRegistry Clone() { return new ExtensionRegistry(extensions); } } public static class ExtensionSet { private static bool TryGetValue(ref ExtensionSet set, Extension extension, out IExtensionValue value) where TTarget : IExtendableMessage { if (set == null) { value = null; return false; } return set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value); } public static TValue Get(ref ExtensionSet set, Extension extension) where TTarget : IExtendableMessage { if (TryGetValue(ref set, extension, out var value)) { if (value is ExtensionValue extensionValue) { return extensionValue.GetValue(); } object value2 = value.GetValue(); if (value2 is TValue) { return (TValue)value2; } TypeInfo typeInfo = value.GetType().GetTypeInfo(); if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(ExtensionValue<>)) { System.Type type = typeInfo.GenericTypeArguments[0]; throw new InvalidOperationException("The stored extension value has a type of '" + type.AssemblyQualifiedName + "'. This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'."); } throw new InvalidOperationException("Unexpected extension value type: " + typeInfo.AssemblyQualifiedName); } return extension.DefaultValue; } public static RepeatedField Get(ref ExtensionSet set, RepeatedExtension extension) where TTarget : IExtendableMessage { if (TryGetValue(ref set, extension, out var value)) { if (value is RepeatedExtensionValue repeatedExtensionValue) { return repeatedExtensionValue.GetValue(); } TypeInfo typeInfo = value.GetType().GetTypeInfo(); if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(RepeatedExtensionValue<>)) { System.Type type = typeInfo.GenericTypeArguments[0]; throw new InvalidOperationException("The stored extension value has a type of '" + type.AssemblyQualifiedName + "'. This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'."); } throw new InvalidOperationException("Unexpected extension value type: " + typeInfo.AssemblyQualifiedName); } return null; } public static RepeatedField GetOrInitialize(ref ExtensionSet set, RepeatedExtension extension) where TTarget : IExtendableMessage { IExtensionValue value; if (set == null) { value = extension.CreateValue(); set = new ExtensionSet(); set.ValuesByNumber.Add(extension.FieldNumber, value); } else if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value)) { value = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, value); } return ((RepeatedExtensionValue)value).GetValue(); } public static void Set(ref ExtensionSet set, Extension extension, TValue value) where TTarget : IExtendableMessage { ProtoPreconditions.CheckNotNullUnconstrained(value, "value"); IExtensionValue value2; if (set == null) { value2 = extension.CreateValue(); set = new ExtensionSet(); set.ValuesByNumber.Add(extension.FieldNumber, value2); } else if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value2)) { value2 = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, value2); } ((ExtensionValue)value2).SetValue(value); } public static bool Has(ref ExtensionSet set, Extension extension) where TTarget : IExtendableMessage { IExtensionValue value; return TryGetValue(ref set, extension, out value); } public static void Clear(ref ExtensionSet set, Extension extension) where TTarget : IExtendableMessage { if (set != null) { set.ValuesByNumber.Remove(extension.FieldNumber); if (set.ValuesByNumber.Count == 0) { set = null; } } } public static void Clear(ref ExtensionSet set, RepeatedExtension extension) where TTarget : IExtendableMessage { if (set != null) { set.ValuesByNumber.Remove(extension.FieldNumber); if (set.ValuesByNumber.Count == 0) { set = null; } } } public static bool TryMergeFieldFrom(ref ExtensionSet set, CodedInputStream stream) where TTarget : IExtendableMessage { ParseContext.Initialize(stream, out var ctx); try { return TryMergeFieldFrom(ref set, ref ctx); } finally { ctx.CopyStateTo(stream); } } public static bool TryMergeFieldFrom(ref ExtensionSet set, ref ParseContext ctx) where TTarget : IExtendableMessage { int tagFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag); if (set != null && set.ValuesByNumber.TryGetValue(tagFieldNumber, out var value)) { value.MergeFrom(ref ctx); return true; } if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out var extension)) { IExtensionValue extensionValue = extension.CreateValue(); extensionValue.MergeFrom(ref ctx); set = set ?? new ExtensionSet(); set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); return true; } return false; } public static void MergeFrom(ref ExtensionSet first, ExtensionSet second) where TTarget : IExtendableMessage { if (second == null) { return; } if (first == null) { first = new ExtensionSet(); } foreach (KeyValuePair item in second.ValuesByNumber) { if (first.ValuesByNumber.TryGetValue(item.Key, out var value)) { value.MergeFrom(item.Value); continue; } IExtensionValue value2 = item.Value.Clone(); first.ValuesByNumber[item.Key] = value2; } } public static ExtensionSet Clone(ExtensionSet set) where TTarget : IExtendableMessage { if (set == null) { return null; } ExtensionSet extensionSet = new ExtensionSet(); foreach (KeyValuePair item in set.ValuesByNumber) { IExtensionValue value = item.Value.Clone(); extensionSet.ValuesByNumber[item.Key] = value; } return extensionSet; } } public sealed class ExtensionSet where TTarget : IExtendableMessage { internal Dictionary ValuesByNumber { get; } = new Dictionary(); public override int GetHashCode() { int num = typeof(TTarget).GetHashCode(); foreach (KeyValuePair item in ValuesByNumber) { int num2 = item.Key.GetHashCode() ^ item.Value.GetHashCode(); num ^= num2; } return num; } public override bool Equals(object other) { if (this == other) { return true; } ExtensionSet extensionSet = other as ExtensionSet; if (ValuesByNumber.Count != extensionSet.ValuesByNumber.Count) { return false; } foreach (KeyValuePair item in ValuesByNumber) { if (!extensionSet.ValuesByNumber.TryGetValue(item.Key, out var value)) { return false; } if (!item.Value.Equals(value)) { return false; } } return true; } public int CalculateSize() { int num = 0; foreach (IExtensionValue value in ValuesByNumber.Values) { num += value.CalculateSize(); } return num; } public void WriteTo(CodedOutputStream stream) { WriteContext.Initialize(stream, out var ctx); try { WriteTo(ref ctx); } finally { ctx.CopyStateTo(stream); } } [SecuritySafeCritical] public void WriteTo(ref WriteContext ctx) { foreach (IExtensionValue value in ValuesByNumber.Values) { value.WriteTo(ref ctx); } } internal bool IsInitialized() { return ValuesByNumber.Values.All((IExtensionValue v) => v.IsInitialized()); } } internal interface IExtensionValue : IEquatable, IDeepCloneable { void MergeFrom(ref ParseContext ctx); void MergeFrom(IExtensionValue value); void WriteTo(ref WriteContext ctx); int CalculateSize(); bool IsInitialized(); object GetValue(); } internal sealed class ExtensionValue : IExtensionValue, IEquatable, IDeepCloneable { private T field; private FieldCodec codec; internal ExtensionValue(FieldCodec codec) { this.codec = codec; field = codec.DefaultValue; } public int CalculateSize() { return codec.CalculateUnconditionalSizeWithTag(field); } public IExtensionValue Clone() { return new ExtensionValue(codec) { field = ((field is IDeepCloneable) ? (field as IDeepCloneable).Clone() : field) }; } public bool Equals(IExtensionValue other) { if (this == other) { return true; } if (other is ExtensionValue && codec.Equals((other as ExtensionValue).codec)) { return object.Equals(field, (other as ExtensionValue).field); } return false; } public override int GetHashCode() { return (17 * 31 + field.GetHashCode()) * 31 + codec.GetHashCode(); } public void MergeFrom(ref ParseContext ctx) { codec.ValueMerger(ref ctx, ref field); } public void MergeFrom(IExtensionValue value) { if (value is ExtensionValue) { ExtensionValue extensionValue = value as ExtensionValue; codec.FieldMerger(ref field, extensionValue.field); } } public void WriteTo(ref WriteContext ctx) { ctx.WriteTag(codec.Tag); codec.ValueWriter(ref ctx, field); if (codec.EndTag != 0) { ctx.WriteTag(codec.EndTag); } } public T GetValue() { return field; } object IExtensionValue.GetValue() { return field; } public void SetValue(T value) { field = value; } public bool IsInitialized() { if (field is IMessage) { return (field as IMessage).IsInitialized(); } return true; } } internal sealed class RepeatedExtensionValue : IExtensionValue, IEquatable, IDeepCloneable { private RepeatedField field; private readonly FieldCodec codec; internal RepeatedExtensionValue(FieldCodec codec) { this.codec = codec; field = new RepeatedField(); } public int CalculateSize() { return field.CalculateSize(codec); } public IExtensionValue Clone() { return new RepeatedExtensionValue(codec) { field = field.Clone() }; } public bool Equals(IExtensionValue other) { if (this == other) { return true; } if (other is RepeatedExtensionValue && field.Equals((other as RepeatedExtensionValue).field)) { return codec.Equals((other as RepeatedExtensionValue).codec); } return false; } public override int GetHashCode() { return (17 * 31 + field.GetHashCode()) * 31 + codec.GetHashCode(); } public void MergeFrom(ref ParseContext ctx) { field.AddEntriesFrom(ref ctx, codec); } public void MergeFrom(IExtensionValue value) { if (value is RepeatedExtensionValue) { field.Add((value as RepeatedExtensionValue).field); } } public void WriteTo(ref WriteContext ctx) { field.WriteTo(ref ctx, codec); } public RepeatedField GetValue() { return field; } object IExtensionValue.GetValue() { return field; } public bool IsInitialized() { for (int i = 0; i < field.Count; i++) { T val = field[i]; if (!(val is IMessage)) { break; } if (!(val as IMessage).IsInitialized()) { return false; } } return true; } } public static class FieldCodec { private static class WrapperCodecs { private static readonly Dictionary Codecs = new Dictionary { { typeof(bool), ForBool(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(int), ForInt32(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(long), ForInt64(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(uint), ForUInt32(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(ulong), ForUInt64(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(float), ForFloat(WireFormat.MakeTag(1, WireFormat.WireType.Fixed32)) }, { typeof(double), ForDouble(WireFormat.MakeTag(1, WireFormat.WireType.Fixed64)) }, { typeof(string), ForString(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited)) }, { typeof(ByteString), ForBytes(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited)) } }; private static readonly Dictionary Readers = new Dictionary { { typeof(bool), new ValueReader(ParsingPrimitivesWrappers.ReadBoolWrapper) }, { typeof(int), new ValueReader(ParsingPrimitivesWrappers.ReadInt32Wrapper) }, { typeof(long), new ValueReader(ParsingPrimitivesWrappers.ReadInt64Wrapper) }, { typeof(uint), new ValueReader(ParsingPrimitivesWrappers.ReadUInt32Wrapper) }, { typeof(ulong), new ValueReader(ParsingPrimitivesWrappers.ReadUInt64Wrapper) }, { typeof(float), BitConverter.IsLittleEndian ? new ValueReader(ParsingPrimitivesWrappers.ReadFloatWrapperLittleEndian) : new ValueReader(ParsingPrimitivesWrappers.ReadFloatWrapperSlow) }, { typeof(double), BitConverter.IsLittleEndian ? new ValueReader(ParsingPrimitivesWrappers.ReadDoubleWrapperLittleEndian) : new ValueReader(ParsingPrimitivesWrappers.ReadDoubleWrapperSlow) }, { typeof(string), null }, { typeof(ByteString), null } }; internal static FieldCodec GetCodec() { if (!Codecs.TryGetValue(typeof(T), out var value)) { throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T)); } return (FieldCodec)value; } internal static ValueReader GetReader() where T : struct { if (!Readers.TryGetValue(typeof(T), out var value)) { throw new InvalidOperationException("Invalid type argument requested for wrapper reader: " + typeof(T)); } if (value == null) { FieldCodec nestedCoded = GetCodec(); return delegate(ref ParseContext ctx) { return Read(ref ctx, nestedCoded); }; } return (ValueReader)value; } [SecuritySafeCritical] internal static T Read(ref ParseContext ctx, FieldCodec codec) { int byteLimit = ctx.ReadLength(); int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, byteLimit); T result = codec.DefaultValue; uint num; while ((num = ctx.ReadTag()) != 0) { if (num == codec.Tag) { result = codec.Read(ref ctx); } else { ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state); } } ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state); SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); return result; } internal static void Write(ref WriteContext ctx, T value, FieldCodec codec) { ctx.WriteLength(codec.CalculateSizeWithTag(value)); codec.WriteTagAndValue(ref ctx, value); } internal static int CalculateSize(T value, FieldCodec codec) { int num = codec.CalculateSizeWithTag(value); return CodedOutputStream.ComputeLengthSize(num) + num; } } public static FieldCodec ForString(uint tag) { return ForString(tag, ""); } public static FieldCodec ForBytes(uint tag) { return ForBytes(tag, ByteString.Empty); } public static FieldCodec ForBool(uint tag) { return ForBool(tag, defaultValue: false); } public static FieldCodec ForInt32(uint tag) { return ForInt32(tag, 0); } public static FieldCodec ForSInt32(uint tag) { return ForSInt32(tag, 0); } public static FieldCodec ForFixed32(uint tag) { return ForFixed32(tag, 0u); } public static FieldCodec ForSFixed32(uint tag) { return ForSFixed32(tag, 0); } public static FieldCodec ForUInt32(uint tag) { return ForUInt32(tag, 0u); } public static FieldCodec ForInt64(uint tag) { return ForInt64(tag, 0L); } public static FieldCodec ForSInt64(uint tag) { return ForSInt64(tag, 0L); } public static FieldCodec ForFixed64(uint tag) { return ForFixed64(tag, 0uL); } public static FieldCodec ForSFixed64(uint tag) { return ForSFixed64(tag, 0L); } public static FieldCodec ForUInt64(uint tag) { return ForUInt64(tag, 0uL); } public static FieldCodec ForFloat(uint tag) { return ForFloat(tag, 0f); } public static FieldCodec ForDouble(uint tag) { return ForDouble(tag, 0.0); } public static FieldCodec ForEnum(uint tag, Func toInt32, Func fromInt32) { return ForEnum(tag, toInt32, fromInt32, default(T)); } public static FieldCodec ForString(uint tag, string defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadString(); }, delegate(ref WriteContext ctx, string value) { ctx.WriteString(value); }, CodedOutputStream.ComputeStringSize, tag, defaultValue); } public static FieldCodec ForBytes(uint tag, ByteString defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadBytes(); }, delegate(ref WriteContext ctx, ByteString value) { ctx.WriteBytes(value); }, CodedOutputStream.ComputeBytesSize, tag, defaultValue); } public static FieldCodec ForBool(uint tag, bool defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadBool(); }, delegate(ref WriteContext ctx, bool value) { ctx.WriteBool(value); }, 1, tag, defaultValue); } public static FieldCodec ForInt32(uint tag, int defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadInt32(); }, delegate(ref WriteContext output, int value) { output.WriteInt32(value); }, CodedOutputStream.ComputeInt32Size, tag, defaultValue); } public static FieldCodec ForSInt32(uint tag, int defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadSInt32(); }, delegate(ref WriteContext output, int value) { output.WriteSInt32(value); }, CodedOutputStream.ComputeSInt32Size, tag, defaultValue); } public static FieldCodec ForFixed32(uint tag, uint defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadFixed32(); }, delegate(ref WriteContext output, uint value) { output.WriteFixed32(value); }, 4, tag, defaultValue); } public static FieldCodec ForSFixed32(uint tag, int defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadSFixed32(); }, delegate(ref WriteContext output, int value) { output.WriteSFixed32(value); }, 4, tag, defaultValue); } public static FieldCodec ForUInt32(uint tag, uint defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadUInt32(); }, delegate(ref WriteContext output, uint value) { output.WriteUInt32(value); }, CodedOutputStream.ComputeUInt32Size, tag, defaultValue); } public static FieldCodec ForInt64(uint tag, long defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadInt64(); }, delegate(ref WriteContext output, long value) { output.WriteInt64(value); }, CodedOutputStream.ComputeInt64Size, tag, defaultValue); } public static FieldCodec ForSInt64(uint tag, long defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadSInt64(); }, delegate(ref WriteContext output, long value) { output.WriteSInt64(value); }, CodedOutputStream.ComputeSInt64Size, tag, defaultValue); } public static FieldCodec ForFixed64(uint tag, ulong defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadFixed64(); }, delegate(ref WriteContext output, ulong value) { output.WriteFixed64(value); }, 8, tag, defaultValue); } public static FieldCodec ForSFixed64(uint tag, long defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadSFixed64(); }, delegate(ref WriteContext output, long value) { output.WriteSFixed64(value); }, 8, tag, defaultValue); } public static FieldCodec ForUInt64(uint tag, ulong defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadUInt64(); }, delegate(ref WriteContext output, ulong value) { output.WriteUInt64(value); }, CodedOutputStream.ComputeUInt64Size, tag, defaultValue); } public static FieldCodec ForFloat(uint tag, float defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadFloat(); }, delegate(ref WriteContext output, float value) { output.WriteFloat(value); }, 4, tag, defaultValue); } public static FieldCodec ForDouble(uint tag, double defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return ctx.ReadDouble(); }, delegate(ref WriteContext output, double value) { output.WriteDouble(value); }, 8, tag, defaultValue); } public static FieldCodec ForEnum(uint tag, Func toInt32, Func fromInt32, T defaultValue) { return new FieldCodec(delegate(ref ParseContext ctx) { return fromInt32(ctx.ReadEnum()); }, delegate(ref WriteContext output, T value) { output.WriteEnum(toInt32(value)); }, (T value) => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag, defaultValue); } public static FieldCodec ForMessage(uint tag, MessageParser parser) where T : class, IMessage { return new FieldCodec(delegate(ref ParseContext ctx) { T val = parser.CreateTemplate(); ctx.ReadMessage(val); return val; }, delegate(ref WriteContext output, T value) { output.WriteMessage(value); }, delegate(ref ParseContext ctx, ref T v) { if (v == null) { v = parser.CreateTemplate(); } ctx.ReadMessage(v); }, delegate(ref T v, T v2) { if (v2 == null) { return false; } if (v == null) { v = v2.Clone(); } else { v.MergeFrom(v2); } return true; }, (T message) => CodedOutputStream.ComputeMessageSize(message), tag); } public static FieldCodec ForGroup(uint startTag, uint endTag, MessageParser parser) where T : class, IMessage { return new FieldCodec(delegate(ref ParseContext ctx) { T val = parser.CreateTemplate(); ctx.ReadGroup(val); return val; }, delegate(ref WriteContext output, T value) { output.WriteGroup(value); }, delegate(ref ParseContext ctx, ref T v) { if (v == null) { v = parser.CreateTemplate(); } ctx.ReadGroup(v); }, delegate(ref T v, T v2) { if (v2 == null) { return v == null; } if (v == null) { v = v2.Clone(); } else { v.MergeFrom(v2); } return true; }, (T message) => CodedOutputStream.ComputeGroupSize(message), startTag, endTag); } public static FieldCodec ForClassWrapper(uint tag) where T : class { FieldCodec nestedCodec = WrapperCodecs.GetCodec(); return new FieldCodec(delegate(ref ParseContext ctx) { return WrapperCodecs.Read(ref ctx, nestedCodec); }, delegate(ref WriteContext output, T value) { WrapperCodecs.Write(ref output, value, nestedCodec); }, delegate(ref ParseContext ctx, ref T v) { v = WrapperCodecs.Read(ref ctx, nestedCodec); }, delegate(ref T v, T v2) { v = v2; return v == null; }, (T value) => WrapperCodecs.CalculateSize(value, nestedCodec), tag, 0u, null); } public static FieldCodec ForStructWrapper(uint tag) where T : struct { FieldCodec nestedCodec = WrapperCodecs.GetCodec(); return new FieldCodec(WrapperCodecs.GetReader(), delegate(ref WriteContext output, T? value) { WrapperCodecs.Write(ref output, value.Value, nestedCodec); }, delegate(ref ParseContext ctx, ref T? v) { v = WrapperCodecs.Read(ref ctx, nestedCodec); }, delegate(ref T? v, T? v2) { if (v2.HasValue) { v = v2; } return v.HasValue; }, (T? value) => value.HasValue ? WrapperCodecs.CalculateSize(value.Value, nestedCodec) : 0, tag, 0u, null); } } internal delegate TValue ValueReader(ref ParseContext ctx); internal delegate void ValueWriter(ref WriteContext ctx, T value); public sealed class FieldCodec { internal delegate void InputMerger(ref ParseContext ctx, ref T value); internal delegate bool ValuesMerger(ref T value, T other); private static readonly EqualityComparer EqualityComparer; private static readonly T DefaultDefault; private static readonly bool TypeSupportsPacking; private readonly int tagSize; internal bool PackedRepeatedField { get; } internal ValueWriter ValueWriter { get; } internal Func ValueSizeCalculator { get; } internal ValueReader ValueReader { get; } internal InputMerger ValueMerger { get; } internal ValuesMerger FieldMerger { get; } internal int FixedSize { get; } internal uint Tag { get; } internal uint EndTag { get; } internal T DefaultValue { get; } static FieldCodec() { EqualityComparer = ProtobufEqualityComparers.GetEqualityComparer(); TypeSupportsPacking = default(T) != null; if (typeof(T) == typeof(string)) { DefaultDefault = (T)(object)""; } else if (typeof(T) == typeof(ByteString)) { DefaultDefault = (T)(object)ByteString.Empty; } } internal static bool IsPackedRepeatedField(uint tag) { if (TypeSupportsPacking) { return WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited; } return false; } internal FieldCodec(ValueReader reader, ValueWriter writer, int fixedSize, uint tag, T defaultValue) : this(reader, writer, (Func)((T _) => fixedSize), tag, defaultValue) { FixedSize = fixedSize; } internal FieldCodec(ValueReader reader, ValueWriter writer, Func sizeCalculator, uint tag, T defaultValue) : this(reader, writer, (InputMerger)delegate(ref ParseContext ctx, ref T v) { v = reader(ref ctx); }, (ValuesMerger)delegate(ref T v, T v2) { v = v2; return true; }, sizeCalculator, tag, 0u, defaultValue) { } internal FieldCodec(ValueReader reader, ValueWriter writer, InputMerger inputMerger, ValuesMerger valuesMerger, Func sizeCalculator, uint tag, uint endTag = 0u) : this(reader, writer, inputMerger, valuesMerger, sizeCalculator, tag, endTag, DefaultDefault) { } internal FieldCodec(ValueReader reader, ValueWriter writer, InputMerger inputMerger, ValuesMerger valuesMerger, Func sizeCalculator, uint tag, uint endTag, T defaultValue) { ValueReader = reader; ValueWriter = writer; ValueMerger = inputMerger; FieldMerger = valuesMerger; ValueSizeCalculator = sizeCalculator; FixedSize = 0; Tag = tag; EndTag = endTag; DefaultValue = defaultValue; tagSize = CodedOutputStream.ComputeRawVarint32Size(tag); if (endTag != 0) { tagSize += CodedOutputStream.ComputeRawVarint32Size(endTag); } PackedRepeatedField = IsPackedRepeatedField(tag); } public void WriteTagAndValue(CodedOutputStream output, T value) { WriteContext.Initialize(output, out var ctx); try { WriteTagAndValue(ref ctx, value); } finally { ctx.CopyStateTo(output); } } public void WriteTagAndValue(ref WriteContext ctx, T value) { if (!IsDefault(value)) { ctx.WriteTag(Tag); ValueWriter(ref ctx, value); if (EndTag != 0) { ctx.WriteTag(EndTag); } } } public T Read(CodedInputStream input) { ParseContext.Initialize(input, out var ctx); try { return ValueReader(ref ctx); } finally { ctx.CopyStateTo(input); } } public T Read(ref ParseContext ctx) { return ValueReader(ref ctx); } public int CalculateSizeWithTag(T value) { if (!IsDefault(value)) { return ValueSizeCalculator(value) + tagSize; } return 0; } internal int CalculateUnconditionalSizeWithTag(T value) { return ValueSizeCalculator(value) + tagSize; } private bool IsDefault(T value) { return EqualityComparer.Equals(value, DefaultValue); } } internal sealed class FieldMaskTree { internal sealed class Node { public Dictionary Children { get; } = new Dictionary(); } private const char FIELD_PATH_SEPARATOR = '.'; private readonly Node root = new Node(); public FieldMaskTree() { } public FieldMaskTree(FieldMask mask) { MergeFromFieldMask(mask); } public override string ToString() { return ToFieldMask().ToString(); } public FieldMaskTree AddFieldPath(string path) { string[] array = path.Split(new char[1] { '.' }); if (array.Length == 0) { return this; } Node node = root; bool flag = false; string[] array2 = array; foreach (string key in array2) { if (!flag && node != root && node.Children.Count == 0) { return this; } if (!node.Children.TryGetValue(key, out var value)) { flag = true; value = new Node(); node.Children.Add(key, value); } node = value; } node.Children.Clear(); return this; } public FieldMaskTree MergeFromFieldMask(FieldMask mask) { foreach (string path in mask.Paths) { AddFieldPath(path); } return this; } public FieldMask ToFieldMask() { FieldMask fieldMask = new FieldMask(); if (root.Children.Count != 0) { List list = new List(); GetFieldPaths(root, "", list); fieldMask.Paths.AddRange(list); } return fieldMask; } private void GetFieldPaths(Node node, string path, List paths) { if (node.Children.Count == 0) { paths.Add(path); return; } foreach (KeyValuePair child in node.Children) { string path2 = ((path.Length == 0) ? child.Key : (path + "." + child.Key)); GetFieldPaths(child.Value, path2, paths); } } public void IntersectFieldPath(string path, FieldMaskTree output) { if (root.Children.Count == 0) { return; } string[] array = path.Split(new char[1] { '.' }); if (array.Length == 0) { return; } Node value = root; string[] array2 = array; foreach (string key in array2) { if (value != root && value.Children.Count == 0) { output.AddFieldPath(path); return; } if (!value.Children.TryGetValue(key, out value)) { return; } } List list = new List(); GetFieldPaths(value, path, list); foreach (string item in list) { output.AddFieldPath(item); } } public void Merge(IMessage source, IMessage destination, FieldMask.MergeOptions options) { if (source.Descriptor != destination.Descriptor) { throw new InvalidProtocolBufferException("Cannot merge messages of different types."); } if (root.Children.Count != 0) { Merge(root, "", source, destination, options); } } private void Merge(Node node, string path, IMessage source, IMessage destination, FieldMask.MergeOptions options) { if (source.Descriptor != destination.Descriptor) { throw new InvalidProtocolBufferException($"source ({source.Descriptor}) and destination ({destination.Descriptor}) descriptor must be equal"); } MessageDescriptor descriptor = source.Descriptor; foreach (KeyValuePair child in node.Children) { FieldDescriptor fieldDescriptor = descriptor.FindFieldByName(child.Key); if (fieldDescriptor == null) { continue; } if (child.Value.Children.Count != 0) { if (fieldDescriptor.IsRepeated || fieldDescriptor.FieldType != FieldType.Message) { continue; } object value = fieldDescriptor.Accessor.GetValue(source); object obj = fieldDescriptor.Accessor.GetValue(destination); if (value != null || obj != null) { if (obj == null) { obj = fieldDescriptor.MessageType.Parser.CreateTemplate(); fieldDescriptor.Accessor.SetValue(destination, obj); } string path2 = ((path.Length == 0) ? child.Key : (path + "." + child.Key)); Merge(child.Value, path2, (IMessage)value, (IMessage)obj, options); } continue; } if (fieldDescriptor.IsRepeated) { if (options.ReplaceRepeatedFields) { fieldDescriptor.Accessor.Clear(destination); } IList obj2 = (IList)fieldDescriptor.Accessor.GetValue(source); IList list = (IList)fieldDescriptor.Accessor.GetValue(destination); foreach (object item in obj2) { list.Add(item); } continue; } object value2 = fieldDescriptor.Accessor.GetValue(source); if (fieldDescriptor.FieldType == FieldType.Message) { if (options.ReplaceMessageFields) { if (value2 == null) { fieldDescriptor.Accessor.Clear(destination); } else { fieldDescriptor.Accessor.SetValue(destination, value2); } } else if (value2 != null) { ByteString data = ((IMessage)value2).ToByteString(); IMessage message = (IMessage)fieldDescriptor.Accessor.GetValue(destination); if (message != null) { message.MergeFrom(data); } else { fieldDescriptor.Accessor.SetValue(destination, fieldDescriptor.MessageType.Parser.ParseFrom(data)); } } } else if (value2 != null || !options.ReplacePrimitiveFields) { fieldDescriptor.Accessor.SetValue(destination, value2); } else { fieldDescriptor.Accessor.Clear(destination); } } } } internal static class FrameworkPortability { internal static readonly RegexOptions CompiledRegexWhereAvailable = (System.Enum.IsDefined(typeof(RegexOptions), 8) ? RegexOptions.Compiled : RegexOptions.None); } public interface IBufferMessage : IMessage { void InternalMergeFrom(ref ParseContext ctx); void InternalWriteTo(ref WriteContext ctx); } public interface ICustomDiagnosticMessage : IMessage { string ToDiagnosticString(); } public interface IDeepCloneable { T Clone(); } public interface IExtendableMessage : IMessage, IMessage, IEquatable, IDeepCloneable where T : IExtendableMessage { TValue GetExtension(Extension extension); RepeatedField GetExtension(RepeatedExtension extension); RepeatedField GetOrInitializeExtension(RepeatedExtension extension); void SetExtension(Extension extension, TValue value); bool HasExtension(Extension extension); void ClearExtension(Extension extension); void ClearExtension(RepeatedExtension extension); } public interface IMessage { MessageDescriptor Descriptor { get; } void MergeFrom(CodedInputStream input); void WriteTo(CodedOutputStream output); int CalculateSize(); } public interface IMessage : IMessage, IEquatable, IDeepCloneable where T : IMessage { void MergeFrom(T message); } public sealed class InvalidJsonException : IOException { internal InvalidJsonException(string message) : base(message) { } } public sealed class InvalidProtocolBufferException : IOException { internal InvalidProtocolBufferException(string message) : base(message) { } internal InvalidProtocolBufferException(string message, Exception innerException) : base(message, innerException) { } internal static InvalidProtocolBufferException MoreDataAvailable() { return new InvalidProtocolBufferException("Completed reading a message while more data was available in the stream."); } internal static InvalidProtocolBufferException TruncatedMessage() { return new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length."); } internal static InvalidProtocolBufferException NegativeSize() { return new InvalidProtocolBufferException("CodedInputStream encountered an embedded string or message which claimed to have negative size."); } internal static InvalidProtocolBufferException MalformedVarint() { return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint."); } internal static InvalidProtocolBufferException InvalidTag() { return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero)."); } internal static InvalidProtocolBufferException InvalidWireType() { return new InvalidProtocolBufferException("Protocol message contained a tag with an invalid wire type."); } internal static InvalidProtocolBufferException InvalidBase64(Exception innerException) { return new InvalidProtocolBufferException("Invalid base64 data", innerException); } internal static InvalidProtocolBufferException InvalidEndTag() { return new InvalidProtocolBufferException("Protocol message end-group tag did not match expected tag."); } internal static InvalidProtocolBufferException RecursionLimitExceeded() { return new InvalidProtocolBufferException("Protocol message had too many levels of nesting. May be malicious. Use CodedInputStream.SetRecursionLimit() to increase the depth limit."); } internal static InvalidProtocolBufferException JsonRecursionLimitExceeded() { return new InvalidProtocolBufferException("Protocol message had too many levels of nesting. May be malicious. Use JsonParser.Settings to increase the depth limit."); } internal static InvalidProtocolBufferException SizeLimitExceeded() { return new InvalidProtocolBufferException("Protocol message was too large. May be malicious. Use CodedInputStream.SetSizeLimit() to increase the size limit."); } internal static InvalidProtocolBufferException InvalidMessageStreamTag() { return new InvalidProtocolBufferException("Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1."); } internal static InvalidProtocolBufferException MissingFields() { return new InvalidProtocolBufferException("Message was missing required fields"); } } public sealed class JsonFormatter { public sealed class Settings { public static Settings Default { get; } public bool FormatDefaultValues { get; } public TypeRegistry TypeRegistry { get; } public bool FormatEnumsAsIntegers { get; } public bool PreserveProtoFieldNames { get; } static Settings() { Default = new Settings(formatDefaultValues: false); } public Settings(bool formatDefaultValues) : this(formatDefaultValues, TypeRegistry.Empty) { } public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) : this(formatDefaultValues, typeRegistry, formatEnumsAsIntegers: false, preserveProtoFieldNames: false) { } private Settings(bool formatDefaultValues, TypeRegistry typeRegistry, bool formatEnumsAsIntegers, bool preserveProtoFieldNames) { FormatDefaultValues = formatDefaultValues; TypeRegistry = typeRegistry ?? TypeRegistry.Empty; FormatEnumsAsIntegers = formatEnumsAsIntegers; PreserveProtoFieldNames = preserveProtoFieldNames; } public Settings WithFormatDefaultValues(bool formatDefaultValues) { return new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames); } public Settings WithTypeRegistry(TypeRegistry typeRegistry) { return new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames); } public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) { return new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers, PreserveProtoFieldNames); } public Settings WithPreserveProtoFieldNames(bool preserveProtoFieldNames) { return new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, preserveProtoFieldNames); } } private static class OriginalEnumValueHelper { private static readonly Dictionary> dictionaries = new Dictionary>(); [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = "The field for the value must still be present. It will be returned by reflection, will be in this collection, and its name can be resolved.")] internal static string GetOriginalName(object value) { System.Type type = value.GetType(); Dictionary value2; lock (dictionaries) { if (!dictionaries.TryGetValue(type, out value2)) { value2 = GetNameMapping(type); dictionaries[type] = value2; } } value2.TryGetValue(value, out var value3); return value3; } private static Dictionary GetNameMapping([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] System.Type enumType) { return (from f in enumType.GetTypeInfo().DeclaredFields where f.IsStatic where f.GetCustomAttributes().FirstOrDefault()?.PreferredAlias ?? true select f).ToDictionary((FieldInfo f) => f.GetValue(null), (FieldInfo f) => f.GetCustomAttributes().FirstOrDefault()?.Name ?? f.Name); } } internal const string AnyTypeUrlField = "@type"; internal const string AnyDiagnosticValueField = "@value"; internal const string AnyWellKnownTypeValueField = "value"; private const string TypeUrlPrefix = "type.googleapis.com"; private const string NameValueSeparator = ": "; private const string PropertySeparator = ", "; private static readonly JsonFormatter diagnosticFormatter; private static readonly string[] CommonRepresentations; private readonly Settings settings; private const string Hex = "0123456789abcdef"; public static JsonFormatter Default { get; } private bool DiagnosticOnly => this == diagnosticFormatter; static JsonFormatter() { Default = new JsonFormatter(Settings.Default); diagnosticFormatter = new JsonFormatter(Settings.Default); CommonRepresentations = new string[160] { "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", "", "", "\\\"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u003c", "", "\\u003e", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\\\", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u007f", "\\u0080", "\\u0081", "\\u0082", "\\u0083", "\\u0084", "\\u0085", "\\u0086", "\\u0087", "\\u0088", "\\u0089", "\\u008a", "\\u008b", "\\u008c", "\\u008d", "\\u008e", "\\u008f", "\\u0090", "\\u0091", "\\u0092", "\\u0093", "\\u0094", "\\u0095", "\\u0096", "\\u0097", "\\u0098", "\\u0099", "\\u009a", "\\u009b", "\\u009c", "\\u009d", "\\u009e", "\\u009f" }; for (int i = 0; i < CommonRepresentations.Length; i++) { if (CommonRepresentations[i] == "") { CommonRepresentations[i] = ((char)i).ToString(); } } } public JsonFormatter(Settings settings) { this.settings = ProtoPreconditions.CheckNotNull(settings, "settings"); } public string Format(IMessage message) { StringWriter stringWriter = new StringWriter(); Format(message, stringWriter); return stringWriter.ToString(); } public void Format(IMessage message, TextWriter writer) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(writer, "writer"); if (message.Descriptor.IsWellKnownType) { WriteWellKnownTypeValue(writer, message.Descriptor, message); } else { WriteMessage(writer, message); } } public static string ToDiagnosticString(IMessage message) { ProtoPreconditions.CheckNotNull(message, "message"); return diagnosticFormatter.Format(message); } private void WriteMessage(TextWriter writer, IMessage message) { if (message == null) { WriteNull(writer); return; } if (DiagnosticOnly && message is ICustomDiagnosticMessage customDiagnosticMessage) { writer.Write(customDiagnosticMessage.ToDiagnosticString()); return; } writer.Write("{ "); bool flag = WriteMessageFields(writer, message, assumeFirstFieldWritten: false); writer.Write(flag ? " }" : "}"); } private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten) { MessageDescriptor.FieldCollection fields = message.Descriptor.Fields; bool flag = !assumeFirstFieldWritten; foreach (FieldDescriptor item in fields.InFieldNumberOrder()) { IFieldAccessor accessor = item.Accessor; object value = accessor.GetValue(message); if (ShouldFormatFieldValue(message, item, value)) { if (!flag) { writer.Write(", "); } if (settings.PreserveProtoFieldNames) { WriteString(writer, accessor.Descriptor.Name); } else { WriteString(writer, accessor.Descriptor.JsonName); } writer.Write(": "); WriteValue(writer, value); flag = false; } } return !flag; } private bool ShouldFormatFieldValue(IMessage message, FieldDescriptor field, object value) { if (!field.HasPresence) { if (!settings.FormatDefaultValues) { return !IsDefaultValue(field, value); } return true; } return field.Accessor.HasValue(message); } internal static string ToJsonName(string name) { StringBuilder stringBuilder = new StringBuilder(name.Length); bool flag = false; foreach (char c in name) { if (c == '_') { flag = true; } else if (flag) { stringBuilder.Append(char.ToUpperInvariant(c)); flag = false; } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } internal static string FromJsonName(string name) { StringBuilder stringBuilder = new StringBuilder(name.Length); foreach (char c in name) { if (char.IsUpper(c)) { stringBuilder.Append('_'); stringBuilder.Append(char.ToLowerInvariant(c)); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } private static void WriteNull(TextWriter writer) { writer.Write("null"); } private static bool IsDefaultValue(FieldDescriptor descriptor, object value) { if (descriptor.IsMap) { return ((IDictionary)value).Count == 0; } if (descriptor.IsRepeated) { return ((IList)value).Count == 0; } switch (descriptor.FieldType) { case FieldType.Bool: return !(bool)value; case FieldType.Bytes: return (ByteString)value == ByteString.Empty; case FieldType.String: return (string)value == ""; case FieldType.Double: return (double)value == 0.0; case FieldType.Int32: case FieldType.SFixed32: case FieldType.SInt32: case FieldType.Enum: return (int)value == 0; case FieldType.Fixed32: case FieldType.UInt32: return (uint)value == 0; case FieldType.UInt64: case FieldType.Fixed64: return (ulong)value == 0; case FieldType.Int64: case FieldType.SFixed64: case FieldType.SInt64: return (long)value == 0; case FieldType.Float: return (float)value == 0f; case FieldType.Group: case FieldType.Message: return value == null; default: throw new ArgumentException("Invalid field type"); } } public void WriteValue(TextWriter writer, object value) { if (value == null || value is NullValue) { WriteNull(writer); } else if (value is bool) { writer.Write(((bool)value) ? "true" : "false"); } else if (value is ByteString) { writer.Write('"'); writer.Write(((ByteString)value).ToBase64()); writer.Write('"'); } else if (value is string) { WriteString(writer, (string)value); } else if (value is IDictionary) { WriteDictionary(writer, (IDictionary)value); } else if (value is IList) { WriteList(writer, (IList)value); } else if (value is int || value is uint) { IFormattable formattable = (IFormattable)value; writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture)); } else if (value is long || value is ulong) { writer.Write('"'); IFormattable formattable2 = (IFormattable)value; writer.Write(formattable2.ToString("d", CultureInfo.InvariantCulture)); writer.Write('"'); } else if (value is System.Enum) { if (settings.FormatEnumsAsIntegers) { WriteValue(writer, (int)value); return; } string originalName = OriginalEnumValueHelper.GetOriginalName(value); if (originalName != null) { WriteString(writer, originalName); } else { WriteValue(writer, (int)value); } } else if (value is float || value is double) { string text = ((IFormattable)value).ToString("r", CultureInfo.InvariantCulture); switch (text) { case "NaN": case "Infinity": case "-Infinity": writer.Write('"'); writer.Write(text); writer.Write('"'); break; default: writer.Write(text); break; } } else { if (!(value is IMessage)) { throw new ArgumentException("Unable to format value of type " + value.GetType()); } Format((IMessage)value, writer); } } private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value) { if (value == null) { WriteNull(writer); } else if (descriptor.IsWrapperType) { if (value is IMessage) { IMessage message = (IMessage)value; value = message.Descriptor.Fields[1].Accessor.GetValue(message); } WriteValue(writer, value); } else if (descriptor.FullName == Timestamp.Descriptor.FullName) { WriteTimestamp(writer, (IMessage)value); } else if (descriptor.FullName == Duration.Descriptor.FullName) { WriteDuration(writer, (IMessage)value); } else if (descriptor.FullName == FieldMask.Descriptor.FullName) { WriteFieldMask(writer, (IMessage)value); } else if (descriptor.FullName == Struct.Descriptor.FullName) { WriteStruct(writer, (IMessage)value); } else if (descriptor.FullName == ListValue.Descriptor.FullName) { IFieldAccessor accessor = descriptor.Fields[1].Accessor; WriteList(writer, (IList)accessor.GetValue((IMessage)value)); } else if (descriptor.FullName == Value.Descriptor.FullName) { WriteStructFieldValue(writer, (IMessage)value); } else if (descriptor.FullName == Any.Descriptor.FullName) { WriteAny(writer, (IMessage)value); } else { WriteMessage(writer, (IMessage)value); } } private void WriteTimestamp(TextWriter writer, IMessage value) { int nanoseconds = (int)value.Descriptor.Fields[2].Accessor.GetValue(value); long seconds = (long)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(Timestamp.ToJson(seconds, nanoseconds, DiagnosticOnly)); } private void WriteDuration(TextWriter writer, IMessage value) { int nanoseconds = (int)value.Descriptor.Fields[2].Accessor.GetValue(value); long seconds = (long)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(Duration.ToJson(seconds, nanoseconds, DiagnosticOnly)); } private void WriteFieldMask(TextWriter writer, IMessage value) { IList paths = (IList)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(FieldMask.ToJson(paths, DiagnosticOnly)); } private void WriteAny(TextWriter writer, IMessage value) { if (DiagnosticOnly) { WriteDiagnosticOnlyAny(writer, value); return; } string text = (string)value.Descriptor.Fields[1].Accessor.GetValue(value); ByteString data = (ByteString)value.Descriptor.Fields[2].Accessor.GetValue(value); string typeName = Any.GetTypeName(text); MessageDescriptor messageDescriptor = settings.TypeRegistry.Find(typeName); if (messageDescriptor == null) { throw new InvalidOperationException("Type registry has no descriptor for type name '" + typeName + "'"); } IMessage message = messageDescriptor.Parser.ParseFrom(data); writer.Write("{ "); WriteString(writer, "@type"); writer.Write(": "); WriteString(writer, text); if (messageDescriptor.IsWellKnownType) { writer.Write(", "); WriteString(writer, "value"); writer.Write(": "); WriteWellKnownTypeValue(writer, messageDescriptor, message); } else { WriteMessageFields(writer, message, assumeFirstFieldWritten: true); } writer.Write(" }"); } private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value) { string text = (string)value.Descriptor.Fields[1].Accessor.GetValue(value); ByteString byteString = (ByteString)value.Descriptor.Fields[2].Accessor.GetValue(value); writer.Write("{ "); WriteString(writer, "@type"); writer.Write(": "); WriteString(writer, text); writer.Write(", "); WriteString(writer, "@value"); writer.Write(": "); writer.Write('"'); writer.Write(byteString.ToBase64()); writer.Write('"'); writer.Write(" }"); } private void WriteStruct(TextWriter writer, IMessage message) { writer.Write("{ "); IDictionary obj = (IDictionary)message.Descriptor.Fields[1].Accessor.GetValue(message); bool flag = true; foreach (DictionaryEntry item in obj) { string text = (string)item.Key; IMessage message2 = (IMessage)item.Value; if (string.IsNullOrEmpty(text) || message2 == null) { throw new InvalidOperationException("Struct fields cannot have an empty key or a null value."); } if (!flag) { writer.Write(", "); } WriteString(writer, text); writer.Write(": "); WriteStructFieldValue(writer, message2); flag = false; } writer.Write(flag ? "}" : " }"); } private void WriteStructFieldValue(TextWriter writer, IMessage message) { FieldDescriptor caseFieldDescriptor = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message); if (caseFieldDescriptor == null) { throw new InvalidOperationException("Value message must contain a value for the oneof."); } object value = caseFieldDescriptor.Accessor.GetValue(message); switch (caseFieldDescriptor.FieldNumber) { case 2: case 3: case 4: WriteValue(writer, value); break; case 5: case 6: { IMessage message2 = (IMessage)caseFieldDescriptor.Accessor.GetValue(message); WriteWellKnownTypeValue(writer, message2.Descriptor, message2); break; } case 1: WriteNull(writer); break; default: throw new InvalidOperationException("Unexpected case in struct field: " + caseFieldDescriptor.FieldNumber); } } internal void WriteList(TextWriter writer, IList list) { writer.Write("[ "); bool flag = true; foreach (object item in list) { if (!flag) { writer.Write(", "); } WriteValue(writer, item); flag = false; } writer.Write(flag ? "]" : " ]"); } internal void WriteDictionary(TextWriter writer, IDictionary dictionary) { writer.Write("{ "); bool flag = true; foreach (DictionaryEntry item in dictionary) { if (!flag) { writer.Write(", "); } string text; if (item.Key is string) { text = (string)item.Key; } else if (item.Key is bool) { text = (((bool)item.Key) ? "true" : "false"); } else { if (!(item.Key is int) && !((item.Key is uint) | (item.Key is long)) && !(item.Key is ulong)) { if (item.Key == null) { throw new ArgumentException("Dictionary has entry with null key"); } throw new ArgumentException("Unhandled dictionary key type: " + item.Key.GetType()); } text = ((IFormattable)item.Key).ToString("d", CultureInfo.InvariantCulture); } WriteString(writer, text); writer.Write(": "); WriteValue(writer, item.Value); flag = false; } writer.Write(flag ? "}" : " }"); } internal static void WriteString(TextWriter writer, string text) { writer.Write('"'); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c < '\u00a0') { writer.Write(CommonRepresentations[(uint)c]); continue; } if (char.IsHighSurrogate(c)) { i++; if (i == text.Length || !char.IsLowSurrogate(text[i])) { throw new ArgumentException("String contains low surrogate not followed by high surrogate"); } HexEncodeUtf16CodeUnit(writer, c); HexEncodeUtf16CodeUnit(writer, text[i]); continue; } if (char.IsLowSurrogate(c)) { throw new ArgumentException("String contains high surrogate not preceded by low surrogate"); } switch (c) { case 173u: case 1757u: case 1807u: case 6068u: case 6069u: case 65279u: case 65529u: case 65530u: case 65531u: HexEncodeUtf16CodeUnit(writer, c); continue; } if ((c >= '\u0600' && c <= '\u0603') || (c >= '\u200b' && c <= '\u200f') || (c >= '\u2028' && c <= '\u202e') || (c >= '\u2060' && c <= '\u2064') || (c >= '\u206a' && c <= '\u206f')) { HexEncodeUtf16CodeUnit(writer, c); } else { writer.Write(c); } } writer.Write('"'); } private static void HexEncodeUtf16CodeUnit(TextWriter writer, char c) { writer.Write("\\u"); writer.Write("0123456789abcdef"[((int)c >> 12) & 0xF]); writer.Write("0123456789abcdef"[((int)c >> 8) & 0xF]); writer.Write("0123456789abcdef"[((int)c >> 4) & 0xF]); writer.Write("0123456789abcdef"[c & 0xF]); } } public sealed class JsonParser { public sealed class Settings { public static Settings Default { get; } public int RecursionLimit { get; } public TypeRegistry TypeRegistry { get; } public bool IgnoreUnknownFields { get; } static Settings() { Default = new Settings(100); } private Settings(int recursionLimit, TypeRegistry typeRegistry, bool ignoreUnknownFields) { RecursionLimit = recursionLimit; TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, "typeRegistry"); IgnoreUnknownFields = ignoreUnknownFields; } public Settings(int recursionLimit) : this(recursionLimit, TypeRegistry.Empty) { } public Settings(int recursionLimit, TypeRegistry typeRegistry) : this(recursionLimit, typeRegistry, ignoreUnknownFields: false) { } public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) { return new Settings(RecursionLimit, TypeRegistry, ignoreUnknownFields); } public Settings WithRecursionLimit(int recursionLimit) { return new Settings(recursionLimit, TypeRegistry, IgnoreUnknownFields); } public Settings WithTypeRegistry(TypeRegistry typeRegistry) { return new Settings(RecursionLimit, ProtoPreconditions.CheckNotNull(typeRegistry, "typeRegistry"), IgnoreUnknownFields); } } private static readonly Regex TimestampRegex = new Regex("^(?[0-9]{4}-[01][0-9]-[0-3][0-9]T[012][0-9]:[0-5][0-9]:[0-5][0-9])(?\\.[0-9]{1,9})?(?(Z|[+-][0-1][0-9]:[0-5][0-9]))$", FrameworkPortability.CompiledRegexWhereAvailable); private static readonly Regex DurationRegex = new Regex("^(?-)?(?[0-9]{1,12})(?\\.[0-9]{1,9})?s$", FrameworkPortability.CompiledRegexWhereAvailable); private static readonly int[] SubsecondScalingFactors = new int[11] { 0, 100000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; private static readonly char[] FieldMaskPathSeparators = new char[1] { ',' }; private static readonly EnumDescriptor NullValueDescriptor = StructReflection.Descriptor.EnumTypes.Single((EnumDescriptor ed) => ed.ClrType == typeof(NullValue)); private static readonly JsonParser defaultInstance = new JsonParser(Settings.Default); private static readonly Dictionary> WellKnownTypeHandlers = new Dictionary> { { Timestamp.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { MergeTimestamp(message, tokenizer.Next()); } }, { Duration.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { MergeDuration(message, tokenizer.Next()); } }, { Value.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeStructValue(message, tokenizer); } }, { ListValue.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeRepeatedField(message, message.Descriptor.Fields[1], tokenizer); } }, { Struct.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeStruct(message, tokenizer); } }, { Any.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeAny(message, tokenizer); } }, { FieldMask.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { MergeFieldMask(message, tokenizer.Next()); } }, { Int32Value.Descriptor.FullName, MergeWrapperField }, { Int64Value.Descriptor.FullName, MergeWrapperField }, { UInt32Value.Descriptor.FullName, MergeWrapperField }, { UInt64Value.Descriptor.FullName, MergeWrapperField }, { FloatValue.Descriptor.FullName, MergeWrapperField }, { DoubleValue.Descriptor.FullName, MergeWrapperField }, { BytesValue.Descriptor.FullName, MergeWrapperField }, { StringValue.Descriptor.FullName, MergeWrapperField }, { BoolValue.Descriptor.FullName, MergeWrapperField } }; private readonly Settings settings; public static JsonParser Default => defaultInstance; private static void MergeWrapperField(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeField(message, message.Descriptor.Fields[1], tokenizer); } public JsonParser(Settings settings) { this.settings = ProtoPreconditions.CheckNotNull(settings, "settings"); } internal void Merge(IMessage message, string json) { Merge(message, new StringReader(json)); } internal void Merge(IMessage message, TextReader jsonReader) { JsonTokenizer jsonTokenizer = JsonTokenizer.FromTextReader(jsonReader); Merge(message, jsonTokenizer); if (jsonTokenizer.Next() != JsonToken.EndDocument) { throw new InvalidProtocolBufferException("Expected end of JSON after object"); } } private void Merge(IMessage message, JsonTokenizer tokenizer) { if (tokenizer.ObjectDepth > settings.RecursionLimit) { throw InvalidProtocolBufferException.JsonRecursionLimitExceeded(); } if (message.Descriptor.IsWellKnownType && WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out var value)) { value(this, message, tokenizer); return; } JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.StartObject) { throw new InvalidProtocolBufferException("Expected an object"); } IDictionary dictionary = message.Descriptor.Fields.ByJsonName(); HashSet hashSet = null; string stringValue; while (true) { jsonToken = tokenizer.Next(); if (jsonToken.Type == JsonToken.TokenType.EndObject) { return; } if (jsonToken.Type != JsonToken.TokenType.Name) { throw new InvalidOperationException("Unexpected token type " + jsonToken.Type); } stringValue = jsonToken.StringValue; if (dictionary.TryGetValue(stringValue, out var value2)) { if (value2.ContainingOneof != null) { if (hashSet == null) { hashSet = new HashSet(); } if (!hashSet.Add(value2.ContainingOneof)) { throw new InvalidProtocolBufferException("Multiple values specified for oneof " + value2.ContainingOneof.Name); } } MergeField(message, value2, tokenizer); } else { if (!settings.IgnoreUnknownFields) { break; } tokenizer.SkipValue(); } } throw new InvalidProtocolBufferException("Unknown field: " + stringValue); } private void MergeField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type == JsonToken.TokenType.Null && (field.IsMap || field.IsRepeated || (!IsGoogleProtobufValueField(field) && !IsGoogleProtobufNullValueField(field)))) { field.Accessor.Clear(message); return; } tokenizer.PushBack(jsonToken); if (field.IsMap) { MergeMapField(message, field, tokenizer); return; } if (field.IsRepeated) { MergeRepeatedField(message, field, tokenizer); return; } object value = ParseSingleValue(field, tokenizer); field.Accessor.SetValue(message, value); } private void MergeRepeatedField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.StartArray) { throw new InvalidProtocolBufferException("Repeated field value was not an array. Token type: " + jsonToken.Type); } IList list = (IList)field.Accessor.GetValue(message); while (true) { jsonToken = tokenizer.Next(); if (jsonToken.Type == JsonToken.TokenType.EndArray) { return; } tokenizer.PushBack(jsonToken); object obj = ParseSingleValue(field, tokenizer); if (obj == null) { break; } list.Add(obj); } throw new InvalidProtocolBufferException("Repeated field elements cannot be null"); } private void MergeMapField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.StartObject) { throw new InvalidProtocolBufferException("Expected an object to populate a map"); } MessageDescriptor messageType = field.MessageType; FieldDescriptor fieldDescriptor = messageType.FindFieldByNumber(1); FieldDescriptor fieldDescriptor2 = messageType.FindFieldByNumber(2); if (fieldDescriptor == null || fieldDescriptor2 == null) { throw new InvalidProtocolBufferException("Invalid map field: " + field.FullName); } IDictionary dictionary = (IDictionary)field.Accessor.GetValue(message); while (true) { jsonToken = tokenizer.Next(); if (jsonToken.Type == JsonToken.TokenType.EndObject) { return; } object key = ParseMapKey(fieldDescriptor, jsonToken.StringValue); object obj = ParseSingleValue(fieldDescriptor2, tokenizer); if (obj == null) { break; } dictionary[key] = obj; } throw new InvalidProtocolBufferException("Map values must not be null"); } private static bool IsGoogleProtobufValueField(FieldDescriptor field) { if (field.FieldType == FieldType.Message) { return field.MessageType.FullName == Value.Descriptor.FullName; } return false; } private static bool IsGoogleProtobufNullValueField(FieldDescriptor field) { if (field.FieldType == FieldType.Enum) { return field.EnumType.FullName == NullValueDescriptor.FullName; } return false; } private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type == JsonToken.TokenType.Null) { if (IsGoogleProtobufValueField(field)) { return Value.ForNull(); } if (IsGoogleProtobufNullValueField(field)) { return NullValue.NullValue; } return null; } FieldType fieldType = field.FieldType; if (fieldType == FieldType.Message) { if (!field.MessageType.IsWrapperType) { tokenizer.PushBack(jsonToken); IMessage message = NewMessageForField(field); Merge(message, tokenizer); return message; } field = field.MessageType.Fields[1]; fieldType = field.FieldType; } switch (jsonToken.Type) { case JsonToken.TokenType.False: case JsonToken.TokenType.True: if (fieldType == FieldType.Bool) { return jsonToken.Type == JsonToken.TokenType.True; } break; case JsonToken.TokenType.StringValue: return ParseSingleStringValue(field, jsonToken.StringValue); case JsonToken.TokenType.Number: return ParseSingleNumberValue(field, jsonToken); case JsonToken.TokenType.Null: throw new NotImplementedException("Haven't worked out what to do for null yet"); } throw new InvalidProtocolBufferException("Unsupported JSON token type " + jsonToken.Type.ToString() + " for field type " + fieldType); } public T Parse(string json) where T : IMessage, new() { ProtoPreconditions.CheckNotNull(json, "json"); return Parse(new StringReader(json)); } public T Parse(TextReader jsonReader) where T : IMessage, new() { ProtoPreconditions.CheckNotNull(jsonReader, "jsonReader"); T val = new T(); Merge(val, jsonReader); return val; } public IMessage Parse(string json, MessageDescriptor descriptor) { ProtoPreconditions.CheckNotNull(json, "json"); ProtoPreconditions.CheckNotNull(descriptor, "descriptor"); return Parse(new StringReader(json), descriptor); } public IMessage Parse(TextReader jsonReader, MessageDescriptor descriptor) { ProtoPreconditions.CheckNotNull(jsonReader, "jsonReader"); ProtoPreconditions.CheckNotNull(descriptor, "descriptor"); IMessage message = descriptor.Parser.CreateTemplate(); Merge(message, jsonReader); return message; } private void MergeStructValue(IMessage message, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); MessageDescriptor.FieldCollection fields = message.Descriptor.Fields; switch (jsonToken.Type) { case JsonToken.TokenType.Null: fields[1].Accessor.SetValue(message, 0); break; case JsonToken.TokenType.StringValue: fields[3].Accessor.SetValue(message, jsonToken.StringValue); break; case JsonToken.TokenType.Number: fields[2].Accessor.SetValue(message, jsonToken.NumberValue); break; case JsonToken.TokenType.False: case JsonToken.TokenType.True: fields[4].Accessor.SetValue(message, jsonToken.Type == JsonToken.TokenType.True); break; case JsonToken.TokenType.StartObject: { FieldDescriptor fieldDescriptor2 = fields[5]; IMessage message3 = NewMessageForField(fieldDescriptor2); tokenizer.PushBack(jsonToken); Merge(message3, tokenizer); fieldDescriptor2.Accessor.SetValue(message, message3); break; } case JsonToken.TokenType.StartArray: { FieldDescriptor fieldDescriptor = fields[6]; IMessage message2 = NewMessageForField(fieldDescriptor); tokenizer.PushBack(jsonToken); Merge(message2, tokenizer); fieldDescriptor.Accessor.SetValue(message, message2); break; } default: throw new InvalidOperationException("Unexpected token type: " + jsonToken.Type); } } private void MergeStruct(IMessage message, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.StartObject) { throw new InvalidProtocolBufferException("Expected object value for Struct"); } tokenizer.PushBack(jsonToken); FieldDescriptor field = message.Descriptor.Fields[1]; MergeMapField(message, field, tokenizer); } private void MergeAny(IMessage message, JsonTokenizer tokenizer) { List list = new List(); JsonToken jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.StartObject) { throw new InvalidProtocolBufferException("Expected object value for Any"); } int objectDepth = tokenizer.ObjectDepth; while (jsonToken.Type != JsonToken.TokenType.Name || jsonToken.StringValue != "@type" || tokenizer.ObjectDepth != objectDepth) { list.Add(jsonToken); jsonToken = tokenizer.Next(); if (tokenizer.ObjectDepth < objectDepth) { throw new InvalidProtocolBufferException("Any message with no @type"); } } jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.StringValue) { throw new InvalidProtocolBufferException("Expected string value for Any.@type"); } string stringValue = jsonToken.StringValue; string typeName = Any.GetTypeName(stringValue); MessageDescriptor obj = settings.TypeRegistry.Find(typeName) ?? throw new InvalidOperationException("Type registry has no descriptor for type name '" + typeName + "'"); JsonTokenizer tokenizer2 = JsonTokenizer.FromReplayedTokens(list, tokenizer); IMessage message2 = obj.Parser.CreateTemplate(); if (obj.IsWellKnownType) { MergeWellKnownTypeAnyBody(message2, tokenizer2); } else { Merge(message2, tokenizer2); } ByteString value = message2.ToByteString(); message.Descriptor.Fields[1].Accessor.SetValue(message, stringValue); message.Descriptor.Fields[2].Accessor.SetValue(message, value); } private void MergeWellKnownTypeAnyBody(IMessage body, JsonTokenizer tokenizer) { JsonToken jsonToken = tokenizer.Next(); jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.Name || jsonToken.StringValue != "value") { throw new InvalidProtocolBufferException("Expected 'value' property for well-known type Any body"); } Merge(body, tokenizer); jsonToken = tokenizer.Next(); if (jsonToken.Type != JsonToken.TokenType.EndObject) { throw new InvalidProtocolBufferException("Expected end-object token after @type/value for well-known type"); } } private static object ParseMapKey(FieldDescriptor field, string keyText) { switch (field.FieldType) { case FieldType.Bool: if (keyText == "true") { return true; } if (keyText == "false") { return false; } throw new InvalidProtocolBufferException("Invalid string for bool map key: " + keyText); case FieldType.String: return keyText; case FieldType.Int32: case FieldType.SFixed32: case FieldType.SInt32: return ParseNumericString(keyText, int.Parse); case FieldType.Fixed32: case FieldType.UInt32: return ParseNumericString(keyText, uint.Parse); case FieldType.Int64: case FieldType.SFixed64: case FieldType.SInt64: return ParseNumericString(keyText, long.Parse); case FieldType.UInt64: case FieldType.Fixed64: return ParseNumericString(keyText, ulong.Parse); default: throw new InvalidProtocolBufferException("Invalid field type for map: " + field.FieldType); } } private static object ParseSingleNumberValue(FieldDescriptor field, JsonToken token) { double numberValue = token.NumberValue; checked { try { switch (field.FieldType) { case FieldType.Int32: case FieldType.SFixed32: case FieldType.SInt32: CheckInteger(numberValue); return (int)numberValue; case FieldType.Fixed32: case FieldType.UInt32: CheckInteger(numberValue); return (uint)numberValue; case FieldType.Int64: case FieldType.SFixed64: case FieldType.SInt64: CheckInteger(numberValue); return (long)numberValue; case FieldType.UInt64: case FieldType.Fixed64: CheckInteger(numberValue); return (ulong)numberValue; case FieldType.Double: return numberValue; case FieldType.Float: if (double.IsNaN(numberValue)) { return float.NaN; } if (numberValue > 3.4028234663852886E+38 || numberValue < -3.4028234663852886E+38) { if (double.IsPositiveInfinity(numberValue)) { return float.PositiveInfinity; } if (double.IsNegativeInfinity(numberValue)) { return float.NegativeInfinity; } throw new InvalidProtocolBufferException($"Value out of range: {numberValue}"); } return (float)numberValue; case FieldType.Enum: CheckInteger(numberValue); return (int)numberValue; default: throw new InvalidProtocolBufferException($"Unsupported conversion from JSON number for field type {field.FieldType}"); } } catch (OverflowException) { throw new InvalidProtocolBufferException($"Value out of range: {numberValue}"); } } } private static void CheckInteger(double value) { if (double.IsInfinity(value) || double.IsNaN(value)) { throw new InvalidProtocolBufferException($"Value not an integer: {value}"); } if (value != Math.Floor(value)) { throw new InvalidProtocolBufferException($"Value not an integer: {value}"); } } private static object ParseSingleStringValue(FieldDescriptor field, string text) { switch (field.FieldType) { case FieldType.String: return text; case FieldType.Bytes: try { return ByteString.FromBase64(text); } catch (FormatException innerException) { throw InvalidProtocolBufferException.InvalidBase64(innerException); } case FieldType.Int32: case FieldType.SFixed32: case FieldType.SInt32: return ParseNumericString(text, int.Parse); case FieldType.Fixed32: case FieldType.UInt32: return ParseNumericString(text, uint.Parse); case FieldType.Int64: case FieldType.SFixed64: case FieldType.SInt64: return ParseNumericString(text, long.Parse); case FieldType.UInt64: case FieldType.Fixed64: return ParseNumericString(text, ulong.Parse); case FieldType.Double: { double num2 = ParseNumericString(text, double.Parse); ValidateInfinityAndNan(text, double.IsPositiveInfinity(num2), double.IsNegativeInfinity(num2), double.IsNaN(num2)); return num2; } case FieldType.Float: { float num = ParseNumericString(text, float.Parse); ValidateInfinityAndNan(text, float.IsPositiveInfinity(num), float.IsNegativeInfinity(num), float.IsNaN(num)); return num; } case FieldType.Enum: return (field.EnumType.FindValueByName(text) ?? throw new InvalidProtocolBufferException("Invalid enum value: " + text + " for enum type: " + field.EnumType.FullName)).Number; default: throw new InvalidProtocolBufferException($"Unsupported conversion from JSON string for field type {field.FieldType}"); } } private static IMessage NewMessageForField(FieldDescriptor field) { return field.MessageType.Parser.CreateTemplate(); } private static T ParseNumericString(string text, Func parser) { if (text.StartsWith("+")) { throw new InvalidProtocolBufferException("Invalid numeric value: " + text); } if (text.StartsWith("0") && text.Length > 1) { if (text[1] >= '0' && text[1] <= '9') { throw new InvalidProtocolBufferException("Invalid numeric value: " + text); } } else if (text.StartsWith("-0") && text.Length > 2 && text[2] >= '0' && text[2] <= '9') { throw new InvalidProtocolBufferException("Invalid numeric value: " + text); } try { return parser(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); } catch (FormatException) { throw new InvalidProtocolBufferException("Invalid numeric value for type: " + text); } catch (OverflowException) { throw new InvalidProtocolBufferException("Value out of range: " + text); } } private static void ValidateInfinityAndNan(string text, bool isPositiveInfinity, bool isNegativeInfinity, bool isNaN) { if ((isPositiveInfinity && text != "Infinity") || (isNegativeInfinity && text != "-Infinity") || (isNaN && text != "NaN")) { throw new InvalidProtocolBufferException("Invalid numeric value: " + text); } } private static void MergeTimestamp(IMessage message, JsonToken token) { if (token.Type != JsonToken.TokenType.StringValue) { throw new InvalidProtocolBufferException("Expected string value for Timestamp"); } Match match = TimestampRegex.Match(token.StringValue); if (!match.Success) { throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue); } string value = match.Groups["datetime"].Value; string value2 = match.Groups["subseconds"].Value; string value3 = match.Groups["offset"].Value; try { Timestamp timestamp = Timestamp.FromDateTime(DateTime.ParseExact(value, "yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal)); int num = 0; if (value2 != "") { num = int.Parse(value2.Substring(1), CultureInfo.InvariantCulture) * SubsecondScalingFactors[value2.Length]; } int num2 = 0; if (value3 != "Z") { int num3 = ((value3[0] == '-') ? 1 : (-1)); int num4 = int.Parse(value3.Substring(1, 2), CultureInfo.InvariantCulture); int num5 = int.Parse(value3.Substring(4, 2)); int num6 = num4 * 60 + num5; if (num6 > 1080) { throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue); } if (num6 == 0 && num3 == 1) { throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue); } num2 = num3 * num6 * 60; } if (num2 < 0 && num > 0) { num2++; num -= 1000000000; } if (num2 != 0 || num != 0) { timestamp += new Duration { Nanos = num, Seconds = num2 }; if (timestamp.Seconds < -62135596800L || timestamp.Seconds > 253402300799L) { throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue); } } message.Descriptor.Fields[1].Accessor.SetValue(message, timestamp.Seconds); message.Descriptor.Fields[2].Accessor.SetValue(message, timestamp.Nanos); } catch (FormatException) { throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue); } } private static void MergeDuration(IMessage message, JsonToken token) { if (token.Type != JsonToken.TokenType.StringValue) { throw new InvalidProtocolBufferException("Expected string value for Duration"); } Match match = DurationRegex.Match(token.StringValue); if (!match.Success) { throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue); } string value = match.Groups["sign"].Value; string value2 = match.Groups["int"].Value; if (value2[0] == '0' && value2.Length > 1) { throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue); } string value3 = match.Groups["subseconds"].Value; int num = ((!(value == "-")) ? 1 : (-1)); try { long num2 = long.Parse(value2, CultureInfo.InvariantCulture) * num; int num3 = 0; if (value3 != "") { num3 = int.Parse(value3.Substring(1)) * SubsecondScalingFactors[value3.Length] * num; } if (!Duration.IsNormalized(num2, num3)) { throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue); } message.Descriptor.Fields[1].Accessor.SetValue(message, num2); message.Descriptor.Fields[2].Accessor.SetValue(message, num3); } catch (FormatException) { throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue); } } private static void MergeFieldMask(IMessage message, JsonToken token) { if (token.Type != JsonToken.TokenType.StringValue) { throw new InvalidProtocolBufferException("Expected string value for FieldMask"); } string[] array = token.StringValue.Split(FieldMaskPathSeparators, StringSplitOptions.RemoveEmptyEntries); IList list = (IList)message.Descriptor.Fields[1].Accessor.GetValue(message); string[] array2 = array; foreach (string text in array2) { list.Add(ToSnakeCase(text)); } } private static string ToSnakeCase(string text) { StringBuilder stringBuilder = new StringBuilder(text.Length * 2); bool flag = false; bool flag2 = false; for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c >= 'A' && c <= 'Z') { if (flag && (flag2 || (i + 1 < text.Length && text[i + 1] >= 'a' && text[i + 1] <= 'z'))) { stringBuilder.Append('_'); } stringBuilder.Append((char)(c + 97 - 65)); flag = true; flag2 = false; } else { stringBuilder.Append(c); if (c == '_') { throw new InvalidProtocolBufferException("Invalid field mask: " + text); } flag = true; flag2 = true; } } return stringBuilder.ToString(); } } internal sealed class JsonToken : IEquatable { internal enum TokenType { Null, False, True, StringValue, Number, Name, StartObject, EndObject, StartArray, EndArray, EndDocument } private static readonly JsonToken _true = new JsonToken(TokenType.True); private static readonly JsonToken _false = new JsonToken(TokenType.False); private static readonly JsonToken _null = new JsonToken(TokenType.Null); private static readonly JsonToken startObject = new JsonToken(TokenType.StartObject); private static readonly JsonToken endObject = new JsonToken(TokenType.EndObject); private static readonly JsonToken startArray = new JsonToken(TokenType.StartArray); private static readonly JsonToken endArray = new JsonToken(TokenType.EndArray); private static readonly JsonToken endDocument = new JsonToken(TokenType.EndDocument); private readonly TokenType type; private readonly string stringValue; private readonly double numberValue; internal static JsonToken Null => _null; internal static JsonToken False => _false; internal static JsonToken True => _true; internal static JsonToken StartObject => startObject; internal static JsonToken EndObject => endObject; internal static JsonToken StartArray => startArray; internal static JsonToken EndArray => endArray; internal static JsonToken EndDocument => endDocument; internal TokenType Type => type; internal string StringValue => stringValue; internal double NumberValue => numberValue; internal static JsonToken Name(string name) { return new JsonToken(TokenType.Name, name); } internal static JsonToken Value(string value) { return new JsonToken(TokenType.StringValue, value); } internal static JsonToken Value(double value) { return new JsonToken(TokenType.Number, null, value); } private JsonToken(TokenType type, string stringValue = null, double numberValue = 0.0) { this.type = type; this.stringValue = stringValue; this.numberValue = numberValue; } public override bool Equals(object obj) { return Equals(obj as JsonToken); } public override int GetHashCode() { int num = (((int)(17 * 31 + type) * 31 + stringValue != null) ? stringValue.GetHashCode() : 0) * 31; double num2 = numberValue; return num + num2.GetHashCode(); } public override string ToString() { switch (type) { case TokenType.Null: return "null"; case TokenType.True: return "true"; case TokenType.False: return "false"; case TokenType.Name: return "name (" + stringValue + ")"; case TokenType.StringValue: return "value (" + stringValue + ")"; case TokenType.Number: { double num = numberValue; return "number (" + num + ")"; } case TokenType.StartObject: return "start-object"; case TokenType.EndObject: return "end-object"; case TokenType.StartArray: return "start-array"; case TokenType.EndArray: return "end-array"; case TokenType.EndDocument: return "end-document"; default: throw new InvalidOperationException("Token is of unknown type " + type); } } public bool Equals(JsonToken other) { if (other == null) { return false; } if (other.type == type && other.stringValue == stringValue) { double num = other.numberValue; return num.Equals(numberValue); } return false; } } internal abstract class JsonTokenizer { private class JsonReplayTokenizer : JsonTokenizer { private readonly IList tokens; private readonly JsonTokenizer nextTokenizer; private int nextTokenIndex; internal JsonReplayTokenizer(IList tokens, JsonTokenizer nextTokenizer) { this.tokens = tokens; this.nextTokenizer = nextTokenizer; } protected override JsonToken NextImpl() { if (nextTokenIndex >= tokens.Count) { return nextTokenizer.Next(); } return tokens[nextTokenIndex++]; } } private sealed class JsonTextTokenizer : JsonTokenizer { private enum ContainerType { Document, Object, Array } [Flags] private enum State { StartOfDocument = 1, ExpectedEndOfDocument = 2, ReaderExhausted = 4, ObjectStart = 8, ObjectBeforeColon = 0x10, ObjectAfterColon = 0x20, ObjectAfterProperty = 0x40, ObjectAfterComma = 0x80, ArrayStart = 0x100, ArrayAfterValue = 0x200, ArrayAfterComma = 0x400 } private class PushBackReader { private readonly TextReader reader; private char? nextChar; internal PushBackReader(TextReader reader) { this.reader = reader; } internal char? Read() { if (nextChar.HasValue) { char? result = nextChar; nextChar = null; return result; } int num = reader.Read(); if (num != -1) { return (char)num; } return null; } internal char ReadOrFail(string messageOnFailure) { char? c = Read(); if (!c.HasValue) { throw CreateException(messageOnFailure); } return c.Value; } internal void PushBack(char c) { if (nextChar.HasValue) { throw new InvalidOperationException("Cannot push back when already buffering a character"); } nextChar = c; } internal InvalidJsonException CreateException(string message) { return new InvalidJsonException(message); } } private static readonly State ValueStates = State.StartOfDocument | State.ObjectAfterColon | State.ArrayStart | State.ArrayAfterComma; private readonly Stack containerStack = new Stack(); private readonly PushBackReader reader; private State state; internal JsonTextTokenizer(TextReader reader) { this.reader = new PushBackReader(reader); state = State.StartOfDocument; containerStack.Push(ContainerType.Document); } protected override JsonToken NextImpl() { if (state == State.ReaderExhausted) { throw new InvalidOperationException("Next() called after end of document"); } while (true) { char? c = reader.Read(); if (!c.HasValue) { break; } switch (c.Value) { case '\t': case '\n': case '\r': case ' ': break; case ':': ValidateState(State.ObjectBeforeColon, "Invalid state to read a colon: "); state = State.ObjectAfterColon; break; case ',': ValidateState(State.ObjectAfterProperty | State.ArrayAfterValue, "Invalid state to read a comma: "); state = ((state == State.ObjectAfterProperty) ? State.ObjectAfterComma : State.ArrayAfterComma); break; case '"': { string text = ReadString(); if ((state & (State.ObjectStart | State.ObjectAfterComma)) != 0) { state = State.ObjectBeforeColon; return JsonToken.Name(text); } ValidateAndModifyStateForValue("Invalid state to read a double quote: "); return JsonToken.Value(text); } case '{': ValidateState(ValueStates, "Invalid state to read an open brace: "); state = State.ObjectStart; containerStack.Push(ContainerType.Object); return JsonToken.StartObject; case '}': ValidateState(State.ObjectStart | State.ObjectAfterProperty, "Invalid state to read a close brace: "); PopContainer(); return JsonToken.EndObject; case '[': ValidateState(ValueStates, "Invalid state to read an open square bracket: "); state = State.ArrayStart; containerStack.Push(ContainerType.Array); return JsonToken.StartArray; case ']': ValidateState(State.ArrayStart | State.ArrayAfterValue, "Invalid state to read a close square bracket: "); PopContainer(); return JsonToken.EndArray; case 'n': ConsumeLiteral("null"); ValidateAndModifyStateForValue("Invalid state to read a null literal: "); return JsonToken.Null; case 't': ConsumeLiteral("true"); ValidateAndModifyStateForValue("Invalid state to read a true literal: "); return JsonToken.True; case 'f': ConsumeLiteral("false"); ValidateAndModifyStateForValue("Invalid state to read a false literal: "); return JsonToken.False; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { double value = ReadNumber(c.Value); ValidateAndModifyStateForValue("Invalid state to read a number token: "); return JsonToken.Value(value); } default: throw new InvalidJsonException("Invalid first character of token: " + c.Value); } } ValidateState(State.ExpectedEndOfDocument, "Unexpected end of document in state: "); state = State.ReaderExhausted; return JsonToken.EndDocument; } private void ValidateState(State validStates, string errorPrefix) { if ((validStates & state) == 0) { throw reader.CreateException(errorPrefix + state); } } private string ReadString() { StringBuilder stringBuilder = new StringBuilder(); bool flag = false; while (true) { char c = reader.ReadOrFail("Unexpected end of text while reading string"); if (c < ' ') { throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in string literal: U+{0:x4}", (int)c)); } switch (c) { case '"': if (flag) { throw reader.CreateException("Invalid use of surrogate pair code units"); } return stringBuilder.ToString(); case '\\': c = ReadEscapedCharacter(); break; } if (flag != char.IsLowSurrogate(c)) { break; } flag = char.IsHighSurrogate(c); stringBuilder.Append(c); } throw reader.CreateException("Invalid use of surrogate pair code units"); } private char ReadEscapedCharacter() { char c = reader.ReadOrFail("Unexpected end of text while reading character escape sequence"); return c switch { 'n' => '\n', '\\' => '\\', 'b' => '\b', 'f' => '\f', 'r' => '\r', 't' => '\t', '"' => '"', '/' => '/', 'u' => ReadUnicodeEscape(), _ => throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int)c)), }; } private char ReadUnicodeEscape() { int num = 0; for (int i = 0; i < 4; i++) { char c = reader.ReadOrFail("Unexpected end of text while reading Unicode escape sequence"); int num2; if (c >= '0' && c <= '9') { num2 = c - 48; } else if (c >= 'a' && c <= 'f') { num2 = c - 97 + 10; } else { if (c < 'A' || c > 'F') { throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int)c)); } num2 = c - 65 + 10; } num = (num << 4) + num2; } return (char)num; } private void ConsumeLiteral(string text) { for (int i = 1; i < text.Length; i++) { char? c = reader.Read(); if (!c.HasValue) { throw reader.CreateException("Unexpected end of text while reading literal token " + text); } if (c.Value != text[i]) { throw reader.CreateException("Unexpected character while reading literal token " + text); } } } private double ReadNumber(char initialCharacter) { StringBuilder stringBuilder = new StringBuilder(); if (initialCharacter == '-') { stringBuilder.Append("-"); } else { reader.PushBack(initialCharacter); } char? c = ReadInt(stringBuilder); if (c == '.') { c = ReadFrac(stringBuilder); } if (c == 'e' || c == 'E') { c = ReadExp(stringBuilder); } if (c.HasValue) { reader.PushBack(c.Value); } try { double num = double.Parse(stringBuilder.ToString(), NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); if (double.IsInfinity(num)) { throw reader.CreateException("Numeric value out of range: " + stringBuilder); } return num; } catch (OverflowException) { throw reader.CreateException("Numeric value out of range: " + stringBuilder); } } private char? ReadInt(StringBuilder builder) { char c = reader.ReadOrFail("Invalid numeric literal"); if (c < '0' || c > '9') { throw reader.CreateException("Invalid numeric literal"); } builder.Append(c); int count; char? result = ConsumeDigits(builder, out count); if (c == '0' && count != 0) { throw reader.CreateException("Invalid numeric literal: leading 0 for non-zero value."); } return result; } private char? ReadFrac(StringBuilder builder) { builder.Append('.'); int count; char? result = ConsumeDigits(builder, out count); if (count == 0) { throw reader.CreateException("Invalid numeric literal: fraction with no trailing digits"); } return result; } private char? ReadExp(StringBuilder builder) { builder.Append('E'); char? c = reader.Read(); if (!c.HasValue) { throw reader.CreateException("Invalid numeric literal: exponent with no trailing digits"); } if (c == '-' || c == '+') { builder.Append(c.Value); } else { reader.PushBack(c.Value); } c = ConsumeDigits(builder, out var count); if (count == 0) { throw reader.CreateException("Invalid numeric literal: exponent without value"); } return c; } private char? ConsumeDigits(StringBuilder builder, out int count) { count = 0; char? result; while (true) { result = reader.Read(); if (!result.HasValue || result.Value < '0' || result.Value > '9') { break; } count++; builder.Append(result.Value); } return result; } private void ValidateAndModifyStateForValue(string errorPrefix) { ValidateState(ValueStates, errorPrefix); switch (state) { case State.StartOfDocument: state = State.ExpectedEndOfDocument; break; case State.ObjectAfterColon: state = State.ObjectAfterProperty; break; case State.ArrayStart: case State.ArrayAfterComma: state = State.ArrayAfterValue; break; default: throw new InvalidOperationException("ValidateAndModifyStateForValue does not handle all value states (and should)"); } } private void PopContainer() { containerStack.Pop(); ContainerType containerType = containerStack.Peek(); switch (containerType) { case ContainerType.Object: state = State.ObjectAfterProperty; break; case ContainerType.Array: state = State.ArrayAfterValue; break; case ContainerType.Document: state = State.ExpectedEndOfDocument; break; default: throw new InvalidOperationException("Unexpected container type: " + containerType); } } } private JsonToken bufferedToken; internal int ObjectDepth { get; private set; } internal static JsonTokenizer FromTextReader(TextReader reader) { return new JsonTextTokenizer(reader); } internal static JsonTokenizer FromReplayedTokens(IList tokens, JsonTokenizer continuation) { return new JsonReplayTokenizer(tokens, continuation); } internal void PushBack(JsonToken token) { if (bufferedToken != null) { throw new InvalidOperationException("Can't push back twice"); } bufferedToken = token; if (token.Type == JsonToken.TokenType.StartObject) { ObjectDepth--; } else if (token.Type == JsonToken.TokenType.EndObject) { ObjectDepth++; } } internal JsonToken Next() { JsonToken jsonToken; if (bufferedToken != null) { jsonToken = bufferedToken; bufferedToken = null; } else { jsonToken = NextImpl(); } if (jsonToken.Type == JsonToken.TokenType.StartObject) { ObjectDepth++; } else if (jsonToken.Type == JsonToken.TokenType.EndObject) { ObjectDepth--; } return jsonToken; } protected abstract JsonToken NextImpl(); internal void SkipValue() { int num = 0; do { switch (Next().Type) { case JsonToken.TokenType.EndObject: case JsonToken.TokenType.EndArray: num--; break; case JsonToken.TokenType.StartObject: case JsonToken.TokenType.StartArray: num++; break; } } while (num != 0); } } internal sealed class LimitedInputStream : Stream { private readonly Stream proxied; private int bytesLeft; public override bool CanRead => true; public override bool CanSeek => false; public override bool CanWrite => false; public override long Length { get { throw new NotSupportedException(); } } public override long Position { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } internal LimitedInputStream(Stream proxied, int size) { this.proxied = proxied; bytesLeft = size; } public override void Flush() { } public override int Read(byte[] buffer, int offset, int count) { if (bytesLeft > 0) { int num = proxied.Read(buffer, offset, Math.Min(bytesLeft, count)); bytesLeft -= num; return num; } return 0; } public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } public override void SetLength(long value) { throw new NotSupportedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } } public static class MessageExtensions { public static void MergeFrom(this IMessage message, byte[] data) { message.MergeFrom(data, discardUnknownFields: false, null); } public static void MergeFrom(this IMessage message, byte[] data, int offset, int length) { message.MergeFrom(data, offset, length, discardUnknownFields: false, null); } public static void MergeFrom(this IMessage message, ByteString data) { message.MergeFrom(data, discardUnknownFields: false, null); } public static void MergeFrom(this IMessage message, Stream input) { message.MergeFrom(input, discardUnknownFields: false, null); } [SecuritySafeCritical] public static void MergeFrom(this IMessage message, ReadOnlySpan span) { message.MergeFrom(span, discardUnknownFields: false, null); } public static void MergeDelimitedFrom(this IMessage message, Stream input) { message.MergeDelimitedFrom(input, discardUnknownFields: false, null); } public static byte[] ToByteArray(this IMessage message) { ProtoPreconditions.CheckNotNull(message, "message"); byte[] array = new byte[message.CalculateSize()]; CodedOutputStream codedOutputStream = new CodedOutputStream(array); message.WriteTo(codedOutputStream); codedOutputStream.CheckNoSpaceLeft(); return array; } public static void WriteTo(this IMessage message, Stream output) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(output, "output"); CodedOutputStream codedOutputStream = new CodedOutputStream(output); message.WriteTo(codedOutputStream); codedOutputStream.Flush(); } public static void WriteDelimitedTo(this IMessage message, Stream output) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(output, "output"); CodedOutputStream codedOutputStream = new CodedOutputStream(output); codedOutputStream.WriteLength(message.CalculateSize()); message.WriteTo(codedOutputStream); codedOutputStream.Flush(); } public static ByteString ToByteString(this IMessage message) { ProtoPreconditions.CheckNotNull(message, "message"); return ByteString.AttachBytes(message.ToByteArray()); } [SecuritySafeCritical] public static void WriteTo(this IMessage message, IBufferWriter output) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(output, "output"); WriteContext.Initialize(output, out var ctx); WritingPrimitivesMessages.WriteRawMessage(ref ctx, message); ctx.Flush(); } [SecuritySafeCritical] public static void WriteTo(this IMessage message, Span output) { ProtoPreconditions.CheckNotNull(message, "message"); WriteContext.Initialize(ref output, out var ctx); WritingPrimitivesMessages.WriteRawMessage(ref ctx, message); ctx.CheckNoSpaceLeft(); } public static bool IsInitialized(this IMessage message) { if (message.Descriptor.File.Syntax == Google.Protobuf.Reflection.Syntax.Proto3) { return true; } if (!message.Descriptor.IsExtensionsInitialized(message)) { return false; } return message.Descriptor.Fields.InDeclarationOrder().All(delegate(FieldDescriptor f) { if (f.IsMap) { if (f.MessageType.Fields[2].FieldType == FieldType.Message) { return ((IDictionary)f.Accessor.GetValue(message)).Values.Cast().All(IsInitialized); } return true; } if ((f.IsRepeated && f.FieldType == FieldType.Message) || f.FieldType == FieldType.Group) { return ((IEnumerable)f.Accessor.GetValue(message)).Cast().All(IsInitialized); } if (f.FieldType == FieldType.Message || f.FieldType == FieldType.Group) { if (f.Accessor.HasValue(message)) { return ((IMessage)f.Accessor.GetValue(message)).IsInitialized(); } return !f.IsRequired; } return !f.IsRequired || f.Accessor.HasValue(message); }); } internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(data, "data"); CodedInputStream codedInputStream = new CodedInputStream(data); codedInputStream.DiscardUnknownFields = discardUnknownFields; codedInputStream.ExtensionRegistry = registry; message.MergeFrom(codedInputStream); codedInputStream.CheckReadEndOfStreamTag(); } internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(data, "data"); CodedInputStream codedInputStream = new CodedInputStream(data, offset, length); codedInputStream.DiscardUnknownFields = discardUnknownFields; codedInputStream.ExtensionRegistry = registry; message.MergeFrom(codedInputStream); codedInputStream.CheckReadEndOfStreamTag(); } internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(data, "data"); CodedInputStream codedInputStream = data.CreateCodedInput(); codedInputStream.DiscardUnknownFields = discardUnknownFields; codedInputStream.ExtensionRegistry = registry; message.MergeFrom(codedInputStream); codedInputStream.CheckReadEndOfStreamTag(); } internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(input, "input"); CodedInputStream codedInputStream = new CodedInputStream(input); codedInputStream.DiscardUnknownFields = discardUnknownFields; codedInputStream.ExtensionRegistry = registry; message.MergeFrom(codedInputStream); codedInputStream.CheckReadEndOfStreamTag(); } [SecuritySafeCritical] internal static void MergeFrom(this IMessage message, ReadOnlySequence data, bool discardUnknownFields, ExtensionRegistry registry) { ParseContext.Initialize(data, out var ctx); ctx.DiscardUnknownFields = discardUnknownFields; ctx.ExtensionRegistry = registry; ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message); ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state); } [SecuritySafeCritical] internal static void MergeFrom(this IMessage message, ReadOnlySpan data, bool discardUnknownFields, ExtensionRegistry registry) { ParseContext.Initialize(data, out var ctx); ctx.DiscardUnknownFields = discardUnknownFields; ctx.ExtensionRegistry = registry; ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message); ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state); } internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(input, "input"); int size = (int)CodedInputStream.ReadRawVarint32(input); Stream input2 = new LimitedInputStream(input, size); message.MergeFrom(input2, discardUnknownFields, registry); } } public class MessageParser { private Func factory; internal bool DiscardUnknownFields { get; } internal ExtensionRegistry Extensions { get; } internal MessageParser(Func factory, bool discardUnknownFields, ExtensionRegistry extensions) { this.factory = factory; DiscardUnknownFields = discardUnknownFields; Extensions = extensions; } internal IMessage CreateTemplate() { return factory(); } public IMessage ParseFrom(byte[] data) { IMessage message = factory(); message.MergeFrom(data, DiscardUnknownFields, Extensions); return message; } public IMessage ParseFrom(byte[] data, int offset, int length) { IMessage message = factory(); message.MergeFrom(data, offset, length, DiscardUnknownFields, Extensions); return message; } public IMessage ParseFrom(ByteString data) { IMessage message = factory(); message.MergeFrom(data, DiscardUnknownFields, Extensions); return message; } public IMessage ParseFrom(Stream input) { IMessage message = factory(); message.MergeFrom(input, DiscardUnknownFields, Extensions); return message; } [SecuritySafeCritical] public IMessage ParseFrom(ReadOnlySequence data) { IMessage message = factory(); message.MergeFrom(data, DiscardUnknownFields, Extensions); return message; } [SecuritySafeCritical] public IMessage ParseFrom(ReadOnlySpan data) { IMessage message = factory(); message.MergeFrom(data, DiscardUnknownFields, Extensions); return message; } public IMessage ParseDelimitedFrom(Stream input) { IMessage message = factory(); message.MergeDelimitedFrom(input, DiscardUnknownFields, Extensions); return message; } public IMessage ParseFrom(CodedInputStream input) { IMessage message = factory(); MergeFrom(message, input); return message; } public IMessage ParseJson(string json) { IMessage message = factory(); JsonParser.Default.Merge(message, json); return message; } internal void MergeFrom(IMessage message, CodedInputStream codedInput) { bool discardUnknownFields = codedInput.DiscardUnknownFields; ExtensionRegistry extensionRegistry = codedInput.ExtensionRegistry; try { codedInput.DiscardUnknownFields = DiscardUnknownFields; codedInput.ExtensionRegistry = Extensions; message.MergeFrom(codedInput); } finally { codedInput.DiscardUnknownFields = discardUnknownFields; codedInput.ExtensionRegistry = extensionRegistry; } } public MessageParser WithDiscardUnknownFields(bool discardUnknownFields) { return new MessageParser(factory, discardUnknownFields, Extensions); } public MessageParser WithExtensionRegistry(ExtensionRegistry registry) { return new MessageParser(factory, DiscardUnknownFields, registry); } } public sealed class MessageParser : MessageParser where T : IMessage { private readonly Func factory; public MessageParser(Func factory) : this(factory, discardUnknownFields: false, (ExtensionRegistry)null) { } internal MessageParser(Func factory, bool discardUnknownFields, ExtensionRegistry extensions) : base(() => factory(), discardUnknownFields, extensions) { this.factory = factory; } internal new T CreateTemplate() { return factory(); } public new T ParseFrom(byte[] data) { T val = factory(); val.MergeFrom(data, base.DiscardUnknownFields, base.Extensions); return val; } public new T ParseFrom(byte[] data, int offset, int length) { T val = factory(); val.MergeFrom(data, offset, length, base.DiscardUnknownFields, base.Extensions); return val; } public new T ParseFrom(ByteString data) { T val = factory(); val.MergeFrom(data, base.DiscardUnknownFields, base.Extensions); return val; } public new T ParseFrom(Stream input) { T val = factory(); val.MergeFrom(input, base.DiscardUnknownFields, base.Extensions); return val; } [SecuritySafeCritical] public new T ParseFrom(ReadOnlySequence data) { T val = factory(); val.MergeFrom(data, base.DiscardUnknownFields, base.Extensions); return val; } [SecuritySafeCritical] public new T ParseFrom(ReadOnlySpan data) { T val = factory(); val.MergeFrom(data, base.DiscardUnknownFields, base.Extensions); return val; } public new T ParseDelimitedFrom(Stream input) { T val = factory(); val.MergeDelimitedFrom(input, base.DiscardUnknownFields, base.Extensions); return val; } public new T ParseFrom(CodedInputStream input) { T val = factory(); MergeFrom(val, input); return val; } public new T ParseJson(string json) { T val = factory(); JsonParser.Default.Merge(val, json); return val; } public new MessageParser WithDiscardUnknownFields(bool discardUnknownFields) { return new MessageParser(factory, discardUnknownFields, base.Extensions); } public new MessageParser WithExtensionRegistry(ExtensionRegistry registry) { return new MessageParser(factory, base.DiscardUnknownFields, registry); } } internal struct ObjectIntPair : IEquatable> where T : class { private readonly int number; private readonly T obj; internal ObjectIntPair(T obj, int number) { this.number = number; this.obj = obj; } public bool Equals(ObjectIntPair other) { if (obj == other.obj) { return number == other.number; } return false; } public override bool Equals(object obj) { if (obj is ObjectIntPair) { return Equals((ObjectIntPair)obj); } return false; } public override int GetHashCode() { return obj.GetHashCode() * 65535 + number; } } [SecuritySafeCritical] public ref struct ParseContext { internal const int DefaultRecursionLimit = 100; internal const int DefaultSizeLimit = int.MaxValue; internal ReadOnlySpan buffer; internal ParserInternalState state; internal uint LastTag => state.lastTag; internal bool DiscardUnknownFields { get { return state.DiscardUnknownFields; } set { state.DiscardUnknownFields = value; } } internal ExtensionRegistry ExtensionRegistry { get { return state.ExtensionRegistry; } set { state.ExtensionRegistry = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(ReadOnlySpan buffer, out ParseContext ctx) { ParserInternalState parserInternalState = new ParserInternalState { sizeLimit = int.MaxValue, recursionLimit = 100, currentLimit = int.MaxValue, bufferSize = buffer.Length }; Initialize(buffer, ref parserInternalState, out ctx); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(ReadOnlySpan buffer, ref ParserInternalState state, out ParseContext ctx) { ctx.buffer = buffer; ctx.state = state; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(CodedInputStream input, out ParseContext ctx) { ctx.buffer = new ReadOnlySpan(input.InternalBuffer); ctx.state = input.InternalState; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(ReadOnlySequence input, out ParseContext ctx) { Initialize(input, 100, out ctx); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(ReadOnlySequence input, int recursionLimit, out ParseContext ctx) { ctx.buffer = default(ReadOnlySpan); ctx.state = default(ParserInternalState); ctx.state.lastTag = 0u; ctx.state.recursionDepth = 0; ctx.state.sizeLimit = int.MaxValue; ctx.state.recursionLimit = recursionLimit; ctx.state.currentLimit = int.MaxValue; SegmentedBufferHelper.Initialize(input, out ctx.state.segmentedBufferHelper, out ctx.buffer); ctx.state.bufferPos = 0; ctx.state.bufferSize = ctx.buffer.Length; ctx.state.DiscardUnknownFields = false; ctx.state.ExtensionRegistry = null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadTag() { return ParsingPrimitives.ParseTag(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public double ReadDouble() { return ParsingPrimitives.ParseDouble(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float ReadFloat() { return ParsingPrimitives.ParseFloat(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadUInt64() { return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadInt64() { return (long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadInt32() { return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadFixed64() { return ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadFixed32() { return ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ReadBool() { return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString() { return ParsingPrimitives.ReadString(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadMessage(IMessage message) { ParsingPrimitivesMessages.ReadMessage(ref this, message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadGroup(IMessage message) { ParsingPrimitivesMessages.ReadGroup(ref this, message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ByteString ReadBytes() { return ParsingPrimitives.ReadBytes(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadUInt32() { return ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadEnum() { return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadSFixed32() { return (int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadSFixed64() { return (long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadSInt32() { return ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadSInt64() { return ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadLength() { return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); } internal void CopyStateTo(CodedInputStream input) { input.InternalState = state; } internal void LoadStateFrom(CodedInputStream input) { state = input.InternalState; } } internal struct ParserInternalState { internal int bufferPos; internal int bufferSize; internal int bufferSizeAfterLimit; internal int currentLimit; internal int totalBytesRetired; internal int recursionDepth; internal SegmentedBufferHelper segmentedBufferHelper; internal uint lastTag; internal uint nextTag; internal bool hasNextTag; internal int sizeLimit; internal int recursionLimit; internal CodedInputStream CodedInputStream => segmentedBufferHelper.CodedInputStream; internal bool DiscardUnknownFields { get; set; } internal ExtensionRegistry ExtensionRegistry { get; set; } } [SecuritySafeCritical] internal static class ParsingPrimitives { private const int StackallocThreshold = 256; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ParseLength(ref ReadOnlySpan buffer, ref ParserInternalState state) { return (int)ParseRawVarint32(ref buffer, ref state); } public static uint ParseTag(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.hasNextTag) { state.lastTag = state.nextTag; state.hasNextTag = false; return state.lastTag; } if (state.bufferPos + 2 <= state.bufferSize) { int num = buffer[state.bufferPos++]; if (num < 128) { state.lastTag = (uint)num; } else { int num2 = num & 0x7F; if ((num = buffer[state.bufferPos++]) < 128) { num2 |= num << 7; state.lastTag = (uint)num2; } else { state.bufferPos -= 2; state.lastTag = ParseRawVarint32(ref buffer, ref state); } } } else { if (SegmentedBufferHelper.IsAtEnd(ref buffer, ref state)) { state.lastTag = 0u; return 0u; } state.lastTag = ParseRawVarint32(ref buffer, ref state); } if (WireFormat.GetTagFieldNumber(state.lastTag) == 0) { throw InvalidProtocolBufferException.InvalidTag(); } return state.lastTag; } public static bool MaybeConsumeTag(ref ReadOnlySpan buffer, ref ParserInternalState state, uint tag) { if (PeekTag(ref buffer, ref state) == tag) { state.hasNextTag = false; return true; } return false; } public static uint PeekTag(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.hasNextTag) { return state.nextTag; } uint lastTag = state.lastTag; state.nextTag = ParseTag(ref buffer, ref state); state.hasNextTag = true; state.lastTag = lastTag; return state.nextTag; } public static ulong ParseRawVarint64(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 10 > state.bufferSize) { return ParseRawVarint64SlowPath(ref buffer, ref state); } ulong num = buffer[state.bufferPos++]; if (num < 128) { return num; } num &= 0x7F; int num2 = 7; do { byte b = buffer[state.bufferPos++]; num |= (ulong)((long)(b & 0x7F) << num2); if (b < 128) { return num; } num2 += 7; } while (num2 < 64); throw InvalidProtocolBufferException.MalformedVarint(); } private static ulong ParseRawVarint64SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) { int num = 0; ulong num2 = 0uL; do { byte b = ReadRawByte(ref buffer, ref state); num2 |= (ulong)((long)(b & 0x7F) << num); if (b < 128) { return num2; } num += 7; } while (num < 64); throw InvalidProtocolBufferException.MalformedVarint(); } public static uint ParseRawVarint32(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 5 > state.bufferSize) { return ParseRawVarint32SlowPath(ref buffer, ref state); } int num = buffer[state.bufferPos++]; if (num < 128) { return (uint)num; } int num2 = num & 0x7F; if ((num = buffer[state.bufferPos++]) < 128) { num2 |= num << 7; } else { num2 |= (num & 0x7F) << 7; if ((num = buffer[state.bufferPos++]) < 128) { num2 |= num << 14; } else { num2 |= (num & 0x7F) << 14; if ((num = buffer[state.bufferPos++]) < 128) { num2 |= num << 21; } else { num2 |= (num & 0x7F) << 21; num2 |= (num = buffer[state.bufferPos++]) << 28; if (num >= 128) { for (int i = 0; i < 5; i++) { if (ReadRawByte(ref buffer, ref state) < 128) { return (uint)num2; } } throw InvalidProtocolBufferException.MalformedVarint(); } } } } return (uint)num2; } private static uint ParseRawVarint32SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) { int num = ReadRawByte(ref buffer, ref state); if (num < 128) { return (uint)num; } int num2 = num & 0x7F; if ((num = ReadRawByte(ref buffer, ref state)) < 128) { num2 |= num << 7; } else { num2 |= (num & 0x7F) << 7; if ((num = ReadRawByte(ref buffer, ref state)) < 128) { num2 |= num << 14; } else { num2 |= (num & 0x7F) << 14; if ((num = ReadRawByte(ref buffer, ref state)) < 128) { num2 |= num << 21; } else { num2 |= (num & 0x7F) << 21; num2 |= (num = ReadRawByte(ref buffer, ref state)) << 28; if (num >= 128) { for (int i = 0; i < 5; i++) { if (ReadRawByte(ref buffer, ref state) < 128) { return (uint)num2; } } throw InvalidProtocolBufferException.MalformedVarint(); } } } } return (uint)num2; } public static uint ParseRawLittleEndian32(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 8 > state.bufferSize) { return ParseRawLittleEndian32SlowPath(ref buffer, ref state); } int result = (int)BinaryPrimitives.ReadUInt64LittleEndian(buffer.Slice(state.bufferPos, 8)); state.bufferPos += 4; return (uint)result; } private static uint ParseRawLittleEndian32SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) { byte num = ReadRawByte(ref buffer, ref state); uint num2 = ReadRawByte(ref buffer, ref state); uint num3 = ReadRawByte(ref buffer, ref state); uint num4 = ReadRawByte(ref buffer, ref state); return num | (num2 << 8) | (num3 << 16) | (num4 << 24); } public static ulong ParseRawLittleEndian64(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 8 > state.bufferSize) { return ParseRawLittleEndian64SlowPath(ref buffer, ref state); } ulong result = BinaryPrimitives.ReadUInt64LittleEndian(buffer.Slice(state.bufferPos, 8)); state.bufferPos += 8; return result; } private static ulong ParseRawLittleEndian64SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) { long num = ReadRawByte(ref buffer, ref state); ulong num2 = ReadRawByte(ref buffer, ref state); ulong num3 = ReadRawByte(ref buffer, ref state); ulong num4 = ReadRawByte(ref buffer, ref state); ulong num5 = ReadRawByte(ref buffer, ref state); ulong num6 = ReadRawByte(ref buffer, ref state); ulong num7 = ReadRawByte(ref buffer, ref state); ulong num8 = ReadRawByte(ref buffer, ref state); return (ulong)num | (num2 << 8) | (num3 << 16) | (num4 << 24) | (num5 << 32) | (num6 << 40) | (num7 << 48) | (num8 << 56); } public static double ParseDouble(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (!BitConverter.IsLittleEndian || state.bufferPos + 8 > state.bufferSize) { return BitConverter.Int64BitsToDouble((long)ParseRawLittleEndian64(ref buffer, ref state)); } double result = Unsafe.ReadUnaligned(in MemoryMarshal.GetReference(buffer.Slice(state.bufferPos, 8))); state.bufferPos += 8; return result; } public static float ParseFloat(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (!BitConverter.IsLittleEndian || state.bufferPos + 4 > state.bufferSize) { return ParseFloatSlow(ref buffer, ref state); } float result = Unsafe.ReadUnaligned(in MemoryMarshal.GetReference(buffer.Slice(state.bufferPos, 4))); state.bufferPos += 4; return result; } private unsafe static float ParseFloatSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) { byte* pointer = stackalloc byte[4]; Span span = new Span(pointer, 4); for (int i = 0; i < 4; i++) { span[i] = ReadRawByte(ref buffer, ref state); } if (!BitConverter.IsLittleEndian) { span.Reverse(); } return Unsafe.ReadUnaligned(in MemoryMarshal.GetReference(span)); } public static byte[] ReadRawBytes(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) { if (size < 0) { throw InvalidProtocolBufferException.NegativeSize(); } if (size <= state.bufferSize - state.bufferPos) { byte[] array = new byte[size]; buffer.Slice(state.bufferPos, size).CopyTo(array); state.bufferPos += size; return array; } return ReadRawBytesSlow(ref buffer, ref state, size); } private static byte[] ReadRawBytesSlow(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) { ValidateCurrentLimit(ref buffer, ref state, size); if ((!state.segmentedBufferHelper.TotalLength.HasValue && size < buffer.Length) || IsDataAvailableInSource(ref state, size)) { byte[] array = new byte[size]; ReadRawBytesIntoSpan(ref buffer, ref state, size, array); return array; } List list = new List(); int num = state.bufferSize - state.bufferPos; byte[] array2 = new byte[num]; buffer.Slice(state.bufferPos, num).CopyTo(array2); list.Add(array2); state.bufferPos = state.bufferSize; int num2 = size - num; while (num2 > 0) { state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, mustSucceed: true); byte[] array3 = new byte[Math.Min(num2, state.bufferSize)]; buffer.Slice(0, array3.Length).CopyTo(array3); state.bufferPos += array3.Length; num2 -= array3.Length; list.Add(array3); } byte[] array4 = new byte[size]; int num3 = 0; foreach (byte[] item in list) { Buffer.BlockCopy(item, 0, array4, num3, item.Length); num3 += item.Length; } return array4; } public static void SkipRawBytes(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) { if (size < 0) { throw InvalidProtocolBufferException.NegativeSize(); } ValidateCurrentLimit(ref buffer, ref state, size); if (size <= state.bufferSize - state.bufferPos) { state.bufferPos += size; return; } int num = state.bufferSize - state.bufferPos; state.bufferPos = state.bufferSize; state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, mustSucceed: true); while (size - num > state.bufferSize) { num += state.bufferSize; state.bufferPos = state.bufferSize; state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, mustSucceed: true); } state.bufferPos = size - num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ReadString(ref ReadOnlySpan buffer, ref ParserInternalState state) { int length = ParseLength(ref buffer, ref state); return ReadRawString(ref buffer, ref state, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ByteString ReadBytes(ref ReadOnlySpan buffer, ref ParserInternalState state) { int size = ParseLength(ref buffer, ref state); return ByteString.AttachBytes(ReadRawBytes(ref buffer, ref state, size)); } [SecuritySafeCritical] public unsafe static string ReadRawString(ref ReadOnlySpan buffer, ref ParserInternalState state, int length) { if (length == 0) { return string.Empty; } if (length < 0) { throw InvalidProtocolBufferException.NegativeSize(); } if (length <= state.bufferSize - state.bufferPos) { string result; fixed (byte* reference = &MemoryMarshal.GetReference(buffer.Slice(state.bufferPos, length))) { result = WritingPrimitives.Utf8Encoding.GetString(reference, length); } state.bufferPos += length; return result; } return ReadStringSlow(ref buffer, ref state, length); } private unsafe static string ReadStringSlow(ref ReadOnlySpan buffer, ref ParserInternalState state, int length) { ValidateCurrentLimit(ref buffer, ref state, length); if (IsDataAvailable(ref state, length)) { byte[] array = null; Span span = ((length > 256) ? ((Span)(array = ArrayPool.Shared.Rent(length))) : stackalloc byte[length]); Span span2 = span; try { fixed (byte* reference = &MemoryMarshal.GetReference(span2)) { Span byteSpan = new Span(reference, span2.Length); ReadRawBytesIntoSpan(ref buffer, ref state, length, byteSpan); return WritingPrimitives.Utf8Encoding.GetString(reference, length); } } finally { if (array != null) { ArrayPool.Shared.Return(array); } } } return WritingPrimitives.Utf8Encoding.GetString(ReadRawBytes(ref buffer, ref state, length), 0, length); } private static void ValidateCurrentLimit(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) { if (state.totalBytesRetired + state.bufferPos + size > state.currentLimit) { SkipRawBytes(ref buffer, ref state, state.currentLimit - state.totalBytesRetired - state.bufferPos); throw InvalidProtocolBufferException.TruncatedMessage(); } } [SecuritySafeCritical] private static byte ReadRawByte(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos == state.bufferSize) { state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, mustSucceed: true); } return buffer[state.bufferPos++]; } public static uint ReadRawVarint32(Stream input) { int num = 0; int i; for (i = 0; i < 32; i += 7) { int num2 = input.ReadByte(); if (num2 == -1) { throw InvalidProtocolBufferException.TruncatedMessage(); } num |= (num2 & 0x7F) << i; if ((num2 & 0x80) == 0) { return (uint)num; } } for (; i < 64; i += 7) { int num3 = input.ReadByte(); if (num3 == -1) { throw InvalidProtocolBufferException.TruncatedMessage(); } if ((num3 & 0x80) == 0) { return (uint)num; } } throw InvalidProtocolBufferException.MalformedVarint(); } public static int DecodeZigZag32(uint n) { return (int)((n >> 1) ^ (0 - (n & 1))); } public static long DecodeZigZag64(ulong n) { return (long)((n >> 1) ^ (0L - (n & 1))); } public static bool IsDataAvailable(ref ParserInternalState state, int size) { if (size <= state.bufferSize - state.bufferPos) { return true; } return IsDataAvailableInSource(ref state, size); } private static bool IsDataAvailableInSource(ref ParserInternalState state, int size) { return size <= state.segmentedBufferHelper.TotalLength - state.totalBytesRetired - state.bufferPos; } private static void ReadRawBytesIntoSpan(ref ReadOnlySpan buffer, ref ParserInternalState state, int length, Span byteSpan) { int num = length; while (num > 0) { if (state.bufferSize - state.bufferPos == 0) { state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, mustSucceed: true); } ReadOnlySpan readOnlySpan = buffer.Slice(state.bufferPos, Math.Min(num, state.bufferSize - state.bufferPos)); readOnlySpan.CopyTo(byteSpan.Slice(length - num)); num -= readOnlySpan.Length; state.bufferPos += readOnlySpan.Length; } } } [SecuritySafeCritical] internal static class ParsingPrimitivesMessages { private static readonly byte[] ZeroLengthMessageStreamData = new byte[1]; public static void SkipLastField(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.lastTag == 0) { throw new InvalidOperationException("SkipLastField cannot be called at the end of a stream"); } switch (WireFormat.GetTagWireType(state.lastTag)) { case WireFormat.WireType.StartGroup: SkipGroup(ref buffer, ref state, state.lastTag); break; case WireFormat.WireType.EndGroup: throw new InvalidProtocolBufferException("SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing"); case WireFormat.WireType.Fixed32: ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state); break; case WireFormat.WireType.Fixed64: ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state); break; case WireFormat.WireType.LengthDelimited: { int size = ParsingPrimitives.ParseLength(ref buffer, ref state); ParsingPrimitives.SkipRawBytes(ref buffer, ref state, size); break; } case WireFormat.WireType.Varint: ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); break; } } public static void SkipGroup(ref ReadOnlySpan buffer, ref ParserInternalState state, uint startGroupTag) { state.recursionDepth++; if (state.recursionDepth >= state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } uint num; while (true) { num = ParsingPrimitives.ParseTag(ref buffer, ref state); if (num == 0) { throw InvalidProtocolBufferException.TruncatedMessage(); } if (WireFormat.GetTagWireType(num) == WireFormat.WireType.EndGroup) { break; } SkipLastField(ref buffer, ref state); } int tagFieldNumber = WireFormat.GetTagFieldNumber(startGroupTag); int tagFieldNumber2 = WireFormat.GetTagFieldNumber(num); if (tagFieldNumber != tagFieldNumber2) { throw new InvalidProtocolBufferException($"Mismatched end-group tag. Started with field {tagFieldNumber}; ended with field {tagFieldNumber2}"); } state.recursionDepth--; } public static void ReadMessage(ref ParseContext ctx, IMessage message) { int byteLimit = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state); if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, byteLimit); ctx.state.recursionDepth++; ReadRawMessage(ref ctx, message); CheckReadEndOfStreamTag(ref ctx.state); if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) { throw InvalidProtocolBufferException.TruncatedMessage(); } ctx.state.recursionDepth--; SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); } public static KeyValuePair ReadMapEntry(ref ParseContext ctx, MapField.Codec codec) { int byteLimit = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state); if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, byteLimit); ctx.state.recursionDepth++; TKey key = codec.KeyCodec.DefaultValue; TValue val = codec.ValueCodec.DefaultValue; uint num; while ((num = ctx.ReadTag()) != 0) { if (num == codec.KeyCodec.Tag) { key = codec.KeyCodec.Read(ref ctx); } else if (num == codec.ValueCodec.Tag) { val = codec.ValueCodec.Read(ref ctx); } else { SkipLastField(ref ctx.buffer, ref ctx.state); } } if (val == null) { if (ctx.state.CodedInputStream != null) { val = codec.ValueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData)); } else { ParseContext.Initialize(new ReadOnlySequence(ZeroLengthMessageStreamData), out var ctx2); val = codec.ValueCodec.Read(ref ctx2); } } CheckReadEndOfStreamTag(ref ctx.state); if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) { throw InvalidProtocolBufferException.TruncatedMessage(); } ctx.state.recursionDepth--; SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); return new KeyValuePair(key, val); } public static void ReadGroup(ref ParseContext ctx, IMessage message) { if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } ctx.state.recursionDepth++; int tagFieldNumber = WireFormat.GetTagFieldNumber(ctx.state.lastTag); ReadRawMessage(ref ctx, message); CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(tagFieldNumber, WireFormat.WireType.EndGroup)); ctx.state.recursionDepth--; } public static void ReadGroup(ref ParseContext ctx, int fieldNumber, UnknownFieldSet set) { if (ctx.state.recursionDepth >= ctx.state.recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } ctx.state.recursionDepth++; set.MergeGroupFrom(ref ctx); CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); ctx.state.recursionDepth--; } public static void ReadRawMessage(ref ParseContext ctx, IMessage message) { if (message is IBufferMessage bufferMessage) { bufferMessage.InternalMergeFrom(ref ctx); return; } if (ctx.state.CodedInputStream == null) { throw new InvalidProtocolBufferException("Message " + message.GetType().Name + " doesn't provide the generated method that enables ParseContext-based parsing. You might need to regenerate the generated protobuf code."); } ctx.CopyStateTo(ctx.state.CodedInputStream); try { message.MergeFrom(ctx.state.CodedInputStream); } finally { ctx.LoadStateFrom(ctx.state.CodedInputStream); } } public static void CheckReadEndOfStreamTag(ref ParserInternalState state) { if (state.lastTag != 0) { throw InvalidProtocolBufferException.MoreDataAvailable(); } } private static void CheckLastTagWas(ref ParserInternalState state, uint expectedTag) { if (state.lastTag != expectedTag) { throw InvalidProtocolBufferException.InvalidEndTag(); } } } [SecuritySafeCritical] internal static class ParsingPrimitivesWrappers { internal static float? ReadFloatWrapperLittleEndian(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 6 <= state.bufferSize) { switch (buffer[state.bufferPos]) { case 0: state.bufferPos++; return 0f; case 5: if (buffer[state.bufferPos + 1] == 13) { state.bufferPos += 2; return ParsingPrimitives.ParseFloat(ref buffer, ref state); } goto default; default: return ReadFloatWrapperSlow(ref buffer, ref state); } } return ReadFloatWrapperSlow(ref buffer, ref state); } internal static float? ReadFloatWrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) { int num = ParsingPrimitives.ParseLength(ref buffer, ref state); if (num == 0) { return 0f; } int num2 = state.totalBytesRetired + state.bufferPos + num; float value = 0f; do { if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 13) { value = ParsingPrimitives.ParseFloat(ref buffer, ref state); } else { ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); } } while (state.totalBytesRetired + state.bufferPos < num2); return value; } internal static double? ReadDoubleWrapperLittleEndian(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 10 <= state.bufferSize) { switch (buffer[state.bufferPos]) { case 0: state.bufferPos++; return 0.0; case 9: if (buffer[state.bufferPos + 1] == 9) { state.bufferPos += 2; return ParsingPrimitives.ParseDouble(ref buffer, ref state); } goto default; default: return ReadDoubleWrapperSlow(ref buffer, ref state); } } return ReadDoubleWrapperSlow(ref buffer, ref state); } internal static double? ReadDoubleWrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) { int num = ParsingPrimitives.ParseLength(ref buffer, ref state); if (num == 0) { return 0.0; } int num2 = state.totalBytesRetired + state.bufferPos + num; double value = 0.0; do { if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 9) { value = ParsingPrimitives.ParseDouble(ref buffer, ref state); } else { ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); } } while (state.totalBytesRetired + state.bufferPos < num2); return value; } internal static bool? ReadBoolWrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) { return ReadUInt64Wrapper(ref buffer, ref state) != 0; } internal static uint? ReadUInt32Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 12 <= state.bufferSize) { int bufferPos = state.bufferPos; int num = buffer[state.bufferPos++]; if (num == 0) { return 0u; } if (num >= 128) { state.bufferPos = bufferPos; return ReadUInt32WrapperSlow(ref buffer, ref state); } int num2 = state.bufferPos + num; if (buffer[state.bufferPos++] != 8) { state.bufferPos = bufferPos; return ReadUInt32WrapperSlow(ref buffer, ref state); } uint value = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); if (state.bufferPos != num2) { state.bufferPos = bufferPos; return ReadUInt32WrapperSlow(ref buffer, ref state); } return value; } return ReadUInt32WrapperSlow(ref buffer, ref state); } internal static uint? ReadUInt32WrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) { int num = ParsingPrimitives.ParseLength(ref buffer, ref state); if (num == 0) { return 0u; } int num2 = state.totalBytesRetired + state.bufferPos + num; uint value = 0u; do { if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 8) { value = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); } else { ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); } } while (state.totalBytesRetired + state.bufferPos < num2); return value; } internal static int? ReadInt32Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) { return (int?)ReadUInt32Wrapper(ref buffer, ref state); } internal static ulong? ReadUInt64Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos + 12 <= state.bufferSize) { int bufferPos = state.bufferPos; int num = buffer[state.bufferPos++]; if (num == 0) { return 0uL; } if (num >= 128) { state.bufferPos = bufferPos; return ReadUInt64WrapperSlow(ref buffer, ref state); } int num2 = state.bufferPos + num; if (buffer[state.bufferPos++] != 8) { state.bufferPos = bufferPos; return ReadUInt64WrapperSlow(ref buffer, ref state); } ulong value = ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); if (state.bufferPos != num2) { state.bufferPos = bufferPos; return ReadUInt64WrapperSlow(ref buffer, ref state); } return value; } return ReadUInt64WrapperSlow(ref buffer, ref state); } internal static ulong? ReadUInt64WrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) { int num = ParsingPrimitives.ParseLength(ref buffer, ref state); if (num == 0) { return 0uL; } int num2 = state.totalBytesRetired + state.bufferPos + num; ulong value = 0uL; do { if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 8) { value = ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); } else { ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); } } while (state.totalBytesRetired + state.bufferPos < num2); return value; } internal static long? ReadInt64Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) { return (long?)ReadUInt64Wrapper(ref buffer, ref state); } internal static float? ReadFloatWrapperLittleEndian(ref ParseContext ctx) { return ReadFloatWrapperLittleEndian(ref ctx.buffer, ref ctx.state); } internal static float? ReadFloatWrapperSlow(ref ParseContext ctx) { return ReadFloatWrapperSlow(ref ctx.buffer, ref ctx.state); } internal static double? ReadDoubleWrapperLittleEndian(ref ParseContext ctx) { return ReadDoubleWrapperLittleEndian(ref ctx.buffer, ref ctx.state); } internal static double? ReadDoubleWrapperSlow(ref ParseContext ctx) { return ReadDoubleWrapperSlow(ref ctx.buffer, ref ctx.state); } internal static bool? ReadBoolWrapper(ref ParseContext ctx) { return ReadBoolWrapper(ref ctx.buffer, ref ctx.state); } internal static uint? ReadUInt32Wrapper(ref ParseContext ctx) { return ReadUInt32Wrapper(ref ctx.buffer, ref ctx.state); } internal static int? ReadInt32Wrapper(ref ParseContext ctx) { return ReadInt32Wrapper(ref ctx.buffer, ref ctx.state); } internal static ulong? ReadUInt64Wrapper(ref ParseContext ctx) { return ReadUInt64Wrapper(ref ctx.buffer, ref ctx.state); } internal static ulong? ReadUInt64WrapperSlow(ref ParseContext ctx) { return ReadUInt64WrapperSlow(ref ctx.buffer, ref ctx.state); } internal static long? ReadInt64Wrapper(ref ParseContext ctx) { return ReadInt64Wrapper(ref ctx.buffer, ref ctx.state); } } public static class ProtoPreconditions { public static T CheckNotNull(T value, string name) where T : class { if (value == null) { throw new ArgumentNullException(name); } return value; } internal static T CheckNotNullUnconstrained(T value, string name) { if (value == null) { throw new ArgumentNullException(name); } return value; } } [SecuritySafeCritical] internal struct SegmentedBufferHelper { private int? totalLength; private ReadOnlySequence.Enumerator readOnlySequenceEnumerator; private CodedInputStream codedInputStream; public int? TotalLength => totalLength; public CodedInputStream CodedInputStream => codedInputStream; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Initialize(CodedInputStream codedInputStream, out SegmentedBufferHelper instance) { instance.totalLength = ((codedInputStream.InternalInputStream == null) ? new int?(codedInputStream.InternalBuffer.Length) : ((int?)null)); instance.readOnlySequenceEnumerator = default(ReadOnlySequence.Enumerator); instance.codedInputStream = codedInputStream; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Initialize(ReadOnlySequence sequence, out SegmentedBufferHelper instance, out ReadOnlySpan firstSpan) { instance.codedInputStream = null; ReadOnlyMemory readOnlyMemory; if (sequence.IsSingleSegment) { readOnlyMemory = sequence.First; firstSpan = readOnlyMemory.Span; instance.totalLength = firstSpan.Length; instance.readOnlySequenceEnumerator = default(ReadOnlySequence.Enumerator); } else { instance.readOnlySequenceEnumerator = sequence.GetEnumerator(); instance.totalLength = (int)sequence.Length; instance.readOnlySequenceEnumerator.MoveNext(); readOnlyMemory = instance.readOnlySequenceEnumerator.Current; firstSpan = readOnlyMemory.Span; } } public bool RefillBuffer(ref ReadOnlySpan buffer, ref ParserInternalState state, bool mustSucceed) { if (codedInputStream != null) { return RefillFromCodedInputStream(ref buffer, ref state, mustSucceed); } return RefillFromReadOnlySequence(ref buffer, ref state, mustSucceed); } public static int PushLimit(ref ParserInternalState state, int byteLimit) { if (byteLimit < 0) { throw InvalidProtocolBufferException.NegativeSize(); } byteLimit += state.totalBytesRetired + state.bufferPos; int currentLimit = state.currentLimit; if (byteLimit > currentLimit) { throw InvalidProtocolBufferException.TruncatedMessage(); } state.currentLimit = byteLimit; RecomputeBufferSizeAfterLimit(ref state); return currentLimit; } public static void PopLimit(ref ParserInternalState state, int oldLimit) { state.currentLimit = oldLimit; RecomputeBufferSizeAfterLimit(ref state); } public static bool IsReachedLimit(ref ParserInternalState state) { if (state.currentLimit == int.MaxValue) { return false; } return state.totalBytesRetired + state.bufferPos >= state.currentLimit; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsAtEnd(ref ReadOnlySpan buffer, ref ParserInternalState state) { if (state.bufferPos == state.bufferSize) { return !state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, mustSucceed: false); } return false; } private bool RefillFromReadOnlySequence(ref ReadOnlySpan buffer, ref ParserInternalState state, bool mustSucceed) { CheckCurrentBufferIsEmpty(ref state); if (state.totalBytesRetired + state.bufferSize == state.currentLimit) { if (mustSucceed) { throw InvalidProtocolBufferException.TruncatedMessage(); } return false; } state.totalBytesRetired += state.bufferSize; state.bufferPos = 0; state.bufferSize = 0; while (readOnlySequenceEnumerator.MoveNext()) { buffer = readOnlySequenceEnumerator.Current.Span; state.bufferSize = buffer.Length; if (buffer.Length != 0) { break; } } if (state.bufferSize == 0) { if (mustSucceed) { throw InvalidProtocolBufferException.TruncatedMessage(); } return false; } RecomputeBufferSizeAfterLimit(ref state); int num = state.totalBytesRetired + state.bufferSize + state.bufferSizeAfterLimit; if (num < 0 || num > state.sizeLimit) { throw InvalidProtocolBufferException.SizeLimitExceeded(); } return true; } private bool RefillFromCodedInputStream(ref ReadOnlySpan buffer, ref ParserInternalState state, bool mustSucceed) { CheckCurrentBufferIsEmpty(ref state); if (state.totalBytesRetired + state.bufferSize == state.currentLimit) { if (mustSucceed) { throw InvalidProtocolBufferException.TruncatedMessage(); } return false; } Stream internalInputStream = codedInputStream.InternalInputStream; state.totalBytesRetired += state.bufferSize; state.bufferPos = 0; state.bufferSize = internalInputStream?.Read(codedInputStream.InternalBuffer, 0, buffer.Length) ?? 0; if (state.bufferSize < 0) { throw new InvalidOperationException("Stream.Read returned a negative count"); } if (state.bufferSize == 0) { if (mustSucceed) { throw InvalidProtocolBufferException.TruncatedMessage(); } return false; } RecomputeBufferSizeAfterLimit(ref state); int num = state.totalBytesRetired + state.bufferSize + state.bufferSizeAfterLimit; if (num < 0 || num > state.sizeLimit) { throw InvalidProtocolBufferException.SizeLimitExceeded(); } return true; } private static void RecomputeBufferSizeAfterLimit(ref ParserInternalState state) { state.bufferSize += state.bufferSizeAfterLimit; int num = state.totalBytesRetired + state.bufferSize; if (num > state.currentLimit) { state.bufferSizeAfterLimit = num - state.currentLimit; state.bufferSize -= state.bufferSizeAfterLimit; } else { state.bufferSizeAfterLimit = 0; } } private static void CheckCurrentBufferIsEmpty(ref ParserInternalState state) { if (state.bufferPos < state.bufferSize) { throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty."); } } } internal sealed class UnknownField { private List varintList; private List fixed32List; private List fixed64List; private List lengthDelimitedList; private List groupList; public override bool Equals(object other) { if (this == other) { return true; } if (other is UnknownField unknownField && Lists.Equals(varintList, unknownField.varintList) && Lists.Equals(fixed32List, unknownField.fixed32List) && Lists.Equals(fixed64List, unknownField.fixed64List) && Lists.Equals(lengthDelimitedList, unknownField.lengthDelimitedList)) { return Lists.Equals(groupList, unknownField.groupList); } return false; } public override int GetHashCode() { return ((((43 * 47 + Lists.GetHashCode(varintList)) * 47 + Lists.GetHashCode(fixed32List)) * 47 + Lists.GetHashCode(fixed64List)) * 47 + Lists.GetHashCode(lengthDelimitedList)) * 47 + Lists.GetHashCode(groupList); } internal void WriteTo(int fieldNumber, ref WriteContext output) { if (varintList != null) { foreach (ulong varint in varintList) { output.WriteTag(fieldNumber, WireFormat.WireType.Varint); output.WriteUInt64(varint); } } if (fixed32List != null) { foreach (uint @fixed in fixed32List) { output.WriteTag(fieldNumber, WireFormat.WireType.Fixed32); output.WriteFixed32(@fixed); } } if (fixed64List != null) { foreach (ulong fixed2 in fixed64List) { output.WriteTag(fieldNumber, WireFormat.WireType.Fixed64); output.WriteFixed64(fixed2); } } if (lengthDelimitedList != null) { foreach (ByteString lengthDelimited in lengthDelimitedList) { output.WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited); output.WriteBytes(lengthDelimited); } } if (groupList == null) { return; } foreach (UnknownFieldSet group in groupList) { output.WriteTag(fieldNumber, WireFormat.WireType.StartGroup); group.WriteTo(ref output); output.WriteTag(fieldNumber, WireFormat.WireType.EndGroup); } } internal int GetSerializedSize(int fieldNumber) { int num = 0; if (varintList != null) { num += CodedOutputStream.ComputeTagSize(fieldNumber) * varintList.Count; foreach (ulong varint in varintList) { num += CodedOutputStream.ComputeUInt64Size(varint); } } if (fixed32List != null) { num += CodedOutputStream.ComputeTagSize(fieldNumber) * fixed32List.Count; num += CodedOutputStream.ComputeFixed32Size(1u) * fixed32List.Count; } if (fixed64List != null) { num += CodedOutputStream.ComputeTagSize(fieldNumber) * fixed64List.Count; num += CodedOutputStream.ComputeFixed64Size(1uL) * fixed64List.Count; } if (lengthDelimitedList != null) { num += CodedOutputStream.ComputeTagSize(fieldNumber) * lengthDelimitedList.Count; foreach (ByteString lengthDelimited in lengthDelimitedList) { num += CodedOutputStream.ComputeBytesSize(lengthDelimited); } } if (groupList != null) { num += CodedOutputStream.ComputeTagSize(fieldNumber) * 2 * groupList.Count; foreach (UnknownFieldSet group in groupList) { num += group.CalculateSize(); } } return num; } internal UnknownField MergeFrom(UnknownField other) { varintList = AddAll(varintList, other.varintList); fixed32List = AddAll(fixed32List, other.fixed32List); fixed64List = AddAll(fixed64List, other.fixed64List); lengthDelimitedList = AddAll(lengthDelimitedList, other.lengthDelimitedList); groupList = AddAll(groupList, other.groupList); return this; } private static List AddAll(List current, IList extras) { if (extras == null || extras.Count == 0) { return current; } if (current == null) { current = new List(extras); } else { current.AddRange(extras); } return current; } internal UnknownField AddVarint(ulong value) { varintList = Add(varintList, value); return this; } internal UnknownField AddFixed32(uint value) { fixed32List = Add(fixed32List, value); return this; } internal UnknownField AddFixed64(ulong value) { fixed64List = Add(fixed64List, value); return this; } internal UnknownField AddLengthDelimited(ByteString value) { lengthDelimitedList = Add(lengthDelimitedList, value); return this; } internal UnknownField AddGroup(UnknownFieldSet value) { groupList = Add(groupList, value); return this; } private static List Add(List list, T value) { if (list == null) { list = new List(); } list.Add(value); return list; } } public sealed class UnknownFieldSet { private readonly IDictionary fields; private int lastFieldNumber; private UnknownField lastField; internal UnknownFieldSet() { fields = new Dictionary(); } internal bool HasField(int field) { return fields.ContainsKey(field); } public void WriteTo(CodedOutputStream output) { WriteContext.Initialize(output, out var ctx); try { WriteTo(ref ctx); } finally { ctx.CopyStateTo(output); } } [SecuritySafeCritical] public void WriteTo(ref WriteContext ctx) { foreach (KeyValuePair field in fields) { field.Value.WriteTo(field.Key, ref ctx); } } public int CalculateSize() { int num = 0; foreach (KeyValuePair field in fields) { num += field.Value.GetSerializedSize(field.Key); } return num; } public override bool Equals(object other) { if (this == other) { return true; } IDictionary dictionary = (other as UnknownFieldSet).fields; if (fields.Count != dictionary.Count) { return false; } foreach (KeyValuePair field in fields) { if (!dictionary.TryGetValue(field.Key, out var value)) { return false; } if (!field.Value.Equals(value)) { return false; } } return true; } public override int GetHashCode() { int num = 1; foreach (KeyValuePair field in fields) { int num2 = field.Key.GetHashCode() ^ field.Value.GetHashCode(); num ^= num2; } return num; } private UnknownField GetOrAddField(int number) { if (lastField != null && number == lastFieldNumber) { return lastField; } if (number == 0) { return null; } if (fields.TryGetValue(number, out var value)) { return value; } lastField = new UnknownField(); AddOrReplaceField(number, lastField); lastFieldNumber = number; return lastField; } internal UnknownFieldSet AddOrReplaceField(int number, UnknownField field) { if (number == 0) { throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); } fields[number] = field; return this; } private bool MergeFieldFrom(ref ParseContext ctx) { uint lastTag = ctx.LastTag; int tagFieldNumber = WireFormat.GetTagFieldNumber(lastTag); switch (WireFormat.GetTagWireType(lastTag)) { case WireFormat.WireType.Varint: { ulong value4 = ctx.ReadUInt64(); GetOrAddField(tagFieldNumber).AddVarint(value4); return true; } case WireFormat.WireType.Fixed32: { uint value3 = ctx.ReadFixed32(); GetOrAddField(tagFieldNumber).AddFixed32(value3); return true; } case WireFormat.WireType.Fixed64: { ulong value2 = ctx.ReadFixed64(); GetOrAddField(tagFieldNumber).AddFixed64(value2); return true; } case WireFormat.WireType.LengthDelimited: { ByteString value = ctx.ReadBytes(); GetOrAddField(tagFieldNumber).AddLengthDelimited(value); return true; } case WireFormat.WireType.StartGroup: { UnknownFieldSet unknownFieldSet = new UnknownFieldSet(); ParsingPrimitivesMessages.ReadGroup(ref ctx, tagFieldNumber, unknownFieldSet); GetOrAddField(tagFieldNumber).AddGroup(unknownFieldSet); return true; } case WireFormat.WireType.EndGroup: return false; default: throw InvalidProtocolBufferException.InvalidWireType(); } } internal void MergeGroupFrom(ref ParseContext ctx) { while (ctx.ReadTag() != 0 && MergeFieldFrom(ref ctx)) { } } public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields, CodedInputStream input) { ParseContext.Initialize(input, out var ctx); try { return MergeFieldFrom(unknownFields, ref ctx); } finally { ctx.CopyStateTo(input); } } [SecuritySafeCritical] public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields, ref ParseContext ctx) { if (ctx.DiscardUnknownFields) { ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state); return unknownFields; } if (unknownFields == null) { unknownFields = new UnknownFieldSet(); } if (!unknownFields.MergeFieldFrom(ref ctx)) { throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); } return unknownFields; } private UnknownFieldSet MergeFrom(UnknownFieldSet other) { if (other != null) { foreach (KeyValuePair field in other.fields) { MergeField(field.Key, field.Value); } } return this; } public static UnknownFieldSet MergeFrom(UnknownFieldSet unknownFields, UnknownFieldSet other) { if (other == null) { return unknownFields; } if (unknownFields == null) { unknownFields = new UnknownFieldSet(); } unknownFields.MergeFrom(other); return unknownFields; } private UnknownFieldSet MergeField(int number, UnknownField field) { if (number == 0) { throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number."); } if (HasField(number)) { GetOrAddField(number).MergeFrom(field); } else { AddOrReplaceField(number, field); } return this; } public static UnknownFieldSet Clone(UnknownFieldSet other) { if (other == null) { return null; } UnknownFieldSet unknownFieldSet = new UnknownFieldSet(); unknownFieldSet.MergeFrom(other); return unknownFieldSet; } } [SecuritySafeCritical] public static class UnsafeByteOperations { public static ByteString UnsafeWrap(ReadOnlyMemory bytes) { return ByteString.AttachBytes(bytes); } } public static class WireFormat { public enum WireType : uint { Varint, Fixed64, LengthDelimited, StartGroup, EndGroup, Fixed32 } private const int TagTypeBits = 3; private const uint TagTypeMask = 7u; public static WireType GetTagWireType(uint tag) { return (WireType)(tag & 7); } public static int GetTagFieldNumber(uint tag) { return (int)(tag >> 3); } public static uint MakeTag(int fieldNumber, WireType wireType) { return (uint)(fieldNumber << 3) | (uint)wireType; } } [SecuritySafeCritical] internal struct WriteBufferHelper { private IBufferWriter bufferWriter; private CodedOutputStream codedOutputStream; public CodedOutputStream CodedOutputStream => codedOutputStream; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Initialize(CodedOutputStream codedOutputStream, out WriteBufferHelper instance) { instance.bufferWriter = null; instance.codedOutputStream = codedOutputStream; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Initialize(IBufferWriter bufferWriter, out WriteBufferHelper instance, out Span buffer) { instance.bufferWriter = bufferWriter; instance.codedOutputStream = null; buffer = default(Span); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InitializeNonRefreshable(out WriteBufferHelper instance) { instance.bufferWriter = null; instance.codedOutputStream = null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CheckNoSpaceLeft(ref WriterInternalState state) { if (GetSpaceLeft(ref state) != 0) { throw new InvalidOperationException("Did not write as much data as expected."); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetSpaceLeft(ref WriterInternalState state) { if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream == null && state.writeBufferHelper.bufferWriter == null) { return state.limit - state.position; } throw new InvalidOperationException("SpaceLeft can only be called on CodedOutputStreams that are writing to a flat array or when writing to a single span."); } [MethodImpl(MethodImplOptions.NoInlining)] public static void RefreshBuffer(ref Span buffer, ref WriterInternalState state) { if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream != null) { state.writeBufferHelper.codedOutputStream.InternalOutputStream.Write(state.writeBufferHelper.codedOutputStream.InternalBuffer, 0, state.position); state.position = 0; return; } if (state.writeBufferHelper.bufferWriter != null) { state.writeBufferHelper.bufferWriter.Advance(state.position); state.position = 0; buffer = state.writeBufferHelper.bufferWriter.GetSpan(); state.limit = buffer.Length; return; } throw new CodedOutputStream.OutOfSpaceException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Flush(ref Span buffer, ref WriterInternalState state) { if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream != null) { state.writeBufferHelper.codedOutputStream.InternalOutputStream.Write(state.writeBufferHelper.codedOutputStream.InternalBuffer, 0, state.position); state.position = 0; } else if (state.writeBufferHelper.bufferWriter != null) { state.writeBufferHelper.bufferWriter.Advance(state.position); state.position = 0; state.limit = 0; buffer = default(Span); } } } [SecuritySafeCritical] public ref struct WriteContext { internal Span buffer; internal WriterInternalState state; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(ref Span buffer, ref WriterInternalState state, out WriteContext ctx) { ctx.buffer = buffer; ctx.state = state; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(CodedOutputStream output, out WriteContext ctx) { ctx.buffer = new Span(output.InternalBuffer); ctx.state = output.InternalState; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(IBufferWriter output, out WriteContext ctx) { ctx.buffer = default(Span); ctx.state = default(WriterInternalState); WriteBufferHelper.Initialize(output, out ctx.state.writeBufferHelper, out ctx.buffer); ctx.state.limit = ctx.buffer.Length; ctx.state.position = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Initialize(ref Span buffer, out WriteContext ctx) { ctx.buffer = buffer; ctx.state = default(WriterInternalState); ctx.state.limit = ctx.buffer.Length; ctx.state.position = 0; WriteBufferHelper.InitializeNonRefreshable(out ctx.state.writeBufferHelper); } public void WriteDouble(double value) { WritingPrimitives.WriteDouble(ref buffer, ref state, value); } public void WriteFloat(float value) { WritingPrimitives.WriteFloat(ref buffer, ref state, value); } public void WriteUInt64(ulong value) { WritingPrimitives.WriteUInt64(ref buffer, ref state, value); } public void WriteInt64(long value) { WritingPrimitives.WriteInt64(ref buffer, ref state, value); } public void WriteInt32(int value) { WritingPrimitives.WriteInt32(ref buffer, ref state, value); } public void WriteFixed64(ulong value) { WritingPrimitives.WriteFixed64(ref buffer, ref state, value); } public void WriteFixed32(uint value) { WritingPrimitives.WriteFixed32(ref buffer, ref state, value); } public void WriteBool(bool value) { WritingPrimitives.WriteBool(ref buffer, ref state, value); } public void WriteString(string value) { WritingPrimitives.WriteString(ref buffer, ref state, value); } public void WriteMessage(IMessage value) { WritingPrimitivesMessages.WriteMessage(ref this, value); } public void WriteGroup(IMessage value) { WritingPrimitivesMessages.WriteGroup(ref this, value); } public void WriteBytes(ByteString value) { WritingPrimitives.WriteBytes(ref buffer, ref state, value); } public void WriteUInt32(uint value) { WritingPrimitives.WriteUInt32(ref buffer, ref state, value); } public void WriteEnum(int value) { WritingPrimitives.WriteEnum(ref buffer, ref state, value); } public void WriteSFixed32(int value) { WritingPrimitives.WriteSFixed32(ref buffer, ref state, value); } public void WriteSFixed64(long value) { WritingPrimitives.WriteSFixed64(ref buffer, ref state, value); } public void WriteSInt32(int value) { WritingPrimitives.WriteSInt32(ref buffer, ref state, value); } public void WriteSInt64(long value) { WritingPrimitives.WriteSInt64(ref buffer, ref state, value); } public void WriteLength(int length) { WritingPrimitives.WriteLength(ref buffer, ref state, length); } public void WriteTag(int fieldNumber, WireFormat.WireType type) { WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type); } public void WriteTag(uint tag) { WritingPrimitives.WriteTag(ref buffer, ref state, tag); } public void WriteRawTag(byte b1) { WritingPrimitives.WriteRawTag(ref buffer, ref state, b1); } public void WriteRawTag(byte b1, byte b2) { WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2); } public void WriteRawTag(byte b1, byte b2, byte b3) { WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3); } public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) { WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4); } public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) { WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4, b5); } internal void Flush() { WriteBufferHelper.Flush(ref buffer, ref state); } internal void CheckNoSpaceLeft() { WriteBufferHelper.CheckNoSpaceLeft(ref state); } internal void CopyStateTo(CodedOutputStream output) { output.InternalState = state; } internal void LoadStateFrom(CodedOutputStream output) { state = output.InternalState; } } internal struct WriterInternalState { internal int limit; internal int position; internal WriteBufferHelper writeBufferHelper; internal CodedOutputStream CodedOutputStream => writeBufferHelper.CodedOutputStream; } [SecuritySafeCritical] internal static class WritingPrimitives { internal static readonly Encoding Utf8Encoding = Encoding.UTF8; public static void WriteDouble(ref Span buffer, ref WriterInternalState state, double value) { WriteRawLittleEndian64(ref buffer, ref state, (ulong)BitConverter.DoubleToInt64Bits(value)); } public static void WriteFloat(ref Span buffer, ref WriterInternalState state, float value) { if (buffer.Length - state.position >= 4) { Span span = buffer.Slice(state.position, 4); Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(span), value); if (!BitConverter.IsLittleEndian) { span.Reverse(); } state.position += 4; } else { WriteFloatSlowPath(ref buffer, ref state, value); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void WriteFloatSlowPath(ref Span buffer, ref WriterInternalState state, float value) { Span span = stackalloc byte[4]; Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(span), value); if (!BitConverter.IsLittleEndian) { span.Reverse(); } WriteRawByte(ref buffer, ref state, span[0]); WriteRawByte(ref buffer, ref state, span[1]); WriteRawByte(ref buffer, ref state, span[2]); WriteRawByte(ref buffer, ref state, span[3]); } public static void WriteUInt64(ref Span buffer, ref WriterInternalState state, ulong value) { WriteRawVarint64(ref buffer, ref state, value); } public static void WriteInt64(ref Span buffer, ref WriterInternalState state, long value) { WriteRawVarint64(ref buffer, ref state, (ulong)value); } public static void WriteInt32(ref Span buffer, ref WriterInternalState state, int value) { if (value >= 0) { WriteRawVarint32(ref buffer, ref state, (uint)value); } else { WriteRawVarint64(ref buffer, ref state, (ulong)value); } } public static void WriteFixed64(ref Span buffer, ref WriterInternalState state, ulong value) { WriteRawLittleEndian64(ref buffer, ref state, value); } public static void WriteFixed32(ref Span buffer, ref WriterInternalState state, uint value) { WriteRawLittleEndian32(ref buffer, ref state, value); } public static void WriteBool(ref Span buffer, ref WriterInternalState state, bool value) { WriteRawByte(ref buffer, ref state, (byte)(value ? 1 : 0)); } public static void WriteString(ref Span buffer, ref WriterInternalState state, string value) { if (value.Length <= 42 && buffer.Length - state.position - 1 >= value.Length * 3) { buffer[state.position++] = (byte)WriteStringToBuffer(buffer, ref state, value); return; } int byteCount = Utf8Encoding.GetByteCount(value); WriteLength(ref buffer, ref state, byteCount); if (buffer.Length - state.position >= byteCount) { if (byteCount == value.Length) { WriteAsciiStringToBuffer(buffer, ref state, value, byteCount); } else { WriteStringToBuffer(buffer, ref state, value); } } else { byte[] bytes = Utf8Encoding.GetBytes(value); WriteRawBytes(ref buffer, ref state, bytes); } } private static void WriteAsciiStringToBuffer(Span buffer, ref WriterInternalState state, string value, int length) { ref char reference = ref MemoryMarshal.GetReference(value.AsSpan()); ref byte reference2 = ref MemoryMarshal.GetReference(buffer.Slice(state.position)); int i = 0; if (IntPtr.Size == 8 && length >= 4) { ref byte source = ref Unsafe.As(ref reference); int num = value.Length - 4; do { NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref Unsafe.AddByteOffset(ref reference2, (IntPtr)i), Unsafe.ReadUnaligned(in Unsafe.AddByteOffset(ref source, (IntPtr)(i * 2)))); } while ((i += 4) <= num); } for (; i < length; i++) { Unsafe.AddByteOffset(ref reference2, (IntPtr)i) = (byte)Unsafe.AddByteOffset(ref reference, (IntPtr)(i * 2)); } state.position += length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref byte outputBuffer, ulong value) { if (BitConverter.IsLittleEndian) { outputBuffer = (byte)value; value >>= 16; Unsafe.Add(ref outputBuffer, 1) = (byte)value; value >>= 16; Unsafe.Add(ref outputBuffer, 2) = (byte)value; value >>= 16; Unsafe.Add(ref outputBuffer, 3) = (byte)value; } else { Unsafe.Add(ref outputBuffer, 3) = (byte)value; value >>= 16; Unsafe.Add(ref outputBuffer, 2) = (byte)value; value >>= 16; Unsafe.Add(ref outputBuffer, 1) = (byte)value; value >>= 16; outputBuffer = (byte)value; } } private unsafe static int WriteStringToBuffer(Span buffer, ref WriterInternalState state, string value) { ReadOnlySpan span = value.AsSpan(); int bytes; fixed (char* reference = &MemoryMarshal.GetReference(span)) { fixed (byte* reference2 = &MemoryMarshal.GetReference(buffer)) { bytes = Utf8Encoding.GetBytes(reference, span.Length, reference2 + state.position, buffer.Length - state.position); } } state.position += bytes; return bytes; } public static void WriteBytes(ref Span buffer, ref WriterInternalState state, ByteString value) { WriteLength(ref buffer, ref state, value.Length); WriteRawBytes(ref buffer, ref state, value.Span); } public static void WriteUInt32(ref Span buffer, ref WriterInternalState state, uint value) { WriteRawVarint32(ref buffer, ref state, value); } public static void WriteEnum(ref Span buffer, ref WriterInternalState state, int value) { WriteInt32(ref buffer, ref state, value); } public static void WriteSFixed32(ref Span buffer, ref WriterInternalState state, int value) { WriteRawLittleEndian32(ref buffer, ref state, (uint)value); } public static void WriteSFixed64(ref Span buffer, ref WriterInternalState state, long value) { WriteRawLittleEndian64(ref buffer, ref state, (ulong)value); } public static void WriteSInt32(ref Span buffer, ref WriterInternalState state, int value) { WriteRawVarint32(ref buffer, ref state, EncodeZigZag32(value)); } public static void WriteSInt64(ref Span buffer, ref WriterInternalState state, long value) { WriteRawVarint64(ref buffer, ref state, EncodeZigZag64(value)); } public static void WriteLength(ref Span buffer, ref WriterInternalState state, int length) { WriteRawVarint32(ref buffer, ref state, (uint)length); } public static void WriteRawVarint32(ref Span buffer, ref WriterInternalState state, uint value) { if (value < 128 && state.position < buffer.Length) { buffer[state.position++] = (byte)value; return; } while (state.position < buffer.Length) { if (value > 127) { buffer[state.position++] = (byte)((value & 0x7F) | 0x80); value >>= 7; continue; } buffer[state.position++] = (byte)value; return; } while (value > 127) { WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80)); value >>= 7; } WriteRawByte(ref buffer, ref state, (byte)value); } public static void WriteRawVarint64(ref Span buffer, ref WriterInternalState state, ulong value) { if (value < 128 && state.position < buffer.Length) { buffer[state.position++] = (byte)value; return; } while (state.position < buffer.Length) { if (value > 127) { buffer[state.position++] = (byte)((value & 0x7F) | 0x80); value >>= 7; continue; } buffer[state.position++] = (byte)value; return; } while (value > 127) { WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80)); value >>= 7; } WriteRawByte(ref buffer, ref state, (byte)value); } public static void WriteRawLittleEndian32(ref Span buffer, ref WriterInternalState state, uint value) { if (state.position + 4 > buffer.Length) { WriteRawLittleEndian32SlowPath(ref buffer, ref state, value); return; } BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(state.position), value); state.position += 4; } [MethodImpl(MethodImplOptions.NoInlining)] private static void WriteRawLittleEndian32SlowPath(ref Span buffer, ref WriterInternalState state, uint value) { WriteRawByte(ref buffer, ref state, (byte)value); WriteRawByte(ref buffer, ref state, (byte)(value >> 8)); WriteRawByte(ref buffer, ref state, (byte)(value >> 16)); WriteRawByte(ref buffer, ref state, (byte)(value >> 24)); } public static void WriteRawLittleEndian64(ref Span buffer, ref WriterInternalState state, ulong value) { if (state.position + 8 > buffer.Length) { WriteRawLittleEndian64SlowPath(ref buffer, ref state, value); return; } BinaryPrimitives.WriteUInt64LittleEndian(buffer.Slice(state.position), value); state.position += 8; } [MethodImpl(MethodImplOptions.NoInlining)] public static void WriteRawLittleEndian64SlowPath(ref Span buffer, ref WriterInternalState state, ulong value) { WriteRawByte(ref buffer, ref state, (byte)value); WriteRawByte(ref buffer, ref state, (byte)(value >> 8)); WriteRawByte(ref buffer, ref state, (byte)(value >> 16)); WriteRawByte(ref buffer, ref state, (byte)(value >> 24)); WriteRawByte(ref buffer, ref state, (byte)(value >> 32)); WriteRawByte(ref buffer, ref state, (byte)(value >> 40)); WriteRawByte(ref buffer, ref state, (byte)(value >> 48)); WriteRawByte(ref buffer, ref state, (byte)(value >> 56)); } private static void WriteRawByte(ref Span buffer, ref WriterInternalState state, byte value) { if (state.position == buffer.Length) { WriteBufferHelper.RefreshBuffer(ref buffer, ref state); } buffer[state.position++] = value; } public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, byte[] value) { WriteRawBytes(ref buffer, ref state, new ReadOnlySpan(value)); } public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, byte[] value, int offset, int length) { WriteRawBytes(ref buffer, ref state, new ReadOnlySpan(value, offset, length)); } public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, ReadOnlySpan value) { if (buffer.Length - state.position >= value.Length) { value.CopyTo(buffer.Slice(state.position, value.Length)); state.position += value.Length; return; } int num = 0; while (buffer.Length - state.position < value.Length - num) { int num2 = buffer.Length - state.position; value.Slice(num, num2).CopyTo(buffer.Slice(state.position, num2)); num += num2; state.position += num2; WriteBufferHelper.RefreshBuffer(ref buffer, ref state); } int num3 = value.Length - num; value.Slice(num, num3).CopyTo(buffer.Slice(state.position, num3)); state.position += num3; } public static void WriteTag(ref Span buffer, ref WriterInternalState state, int fieldNumber, WireFormat.WireType type) { WriteRawVarint32(ref buffer, ref state, WireFormat.MakeTag(fieldNumber, type)); } public static void WriteTag(ref Span buffer, ref WriterInternalState state, uint tag) { WriteRawVarint32(ref buffer, ref state, tag); } public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1) { WriteRawByte(ref buffer, ref state, b1); } public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) { if (state.position + 2 > buffer.Length) { WriteRawTagSlowPath(ref buffer, ref state, b1, b2); return; } buffer[state.position++] = b1; buffer[state.position++] = b2; } [MethodImpl(MethodImplOptions.NoInlining)] private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); } public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) { if (state.position + 3 > buffer.Length) { WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3); return; } buffer[state.position++] = b1; buffer[state.position++] = b2; buffer[state.position++] = b3; } [MethodImpl(MethodImplOptions.NoInlining)] private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); WriteRawByte(ref buffer, ref state, b3); } public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) { if (state.position + 4 > buffer.Length) { WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4); return; } buffer[state.position++] = b1; buffer[state.position++] = b2; buffer[state.position++] = b3; buffer[state.position++] = b4; } [MethodImpl(MethodImplOptions.NoInlining)] private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); WriteRawByte(ref buffer, ref state, b3); WriteRawByte(ref buffer, ref state, b4); } public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) { if (state.position + 5 > buffer.Length) { WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4, b5); return; } buffer[state.position++] = b1; buffer[state.position++] = b2; buffer[state.position++] = b3; buffer[state.position++] = b4; buffer[state.position++] = b5; } [MethodImpl(MethodImplOptions.NoInlining)] private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); WriteRawByte(ref buffer, ref state, b3); WriteRawByte(ref buffer, ref state, b4); WriteRawByte(ref buffer, ref state, b5); } public static uint EncodeZigZag32(int n) { return (uint)((n << 1) ^ (n >> 31)); } public static ulong EncodeZigZag64(long n) { return (ulong)((n << 1) ^ (n >> 63)); } } [SecuritySafeCritical] internal static class WritingPrimitivesMessages { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteMessage(ref WriteContext ctx, IMessage value) { WritingPrimitives.WriteLength(ref ctx.buffer, ref ctx.state, value.CalculateSize()); WriteRawMessage(ref ctx, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGroup(ref WriteContext ctx, IMessage value) { WriteRawMessage(ref ctx, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteRawMessage(ref WriteContext ctx, IMessage message) { if (message is IBufferMessage bufferMessage) { bufferMessage.InternalWriteTo(ref ctx); return; } if (ctx.state.CodedOutputStream == null) { throw new InvalidProtocolBufferException("Message " + message.GetType().Name + " doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code."); } ctx.CopyStateTo(ctx.state.CodedOutputStream); try { message.WriteTo(ctx.state.CodedOutputStream); } finally { ctx.LoadStateFrom(ctx.state.CodedOutputStream); } } } } namespace Google.Protobuf.WellKnownTypes { public static class AnyReflection { private static FileDescriptor descriptor; public static FileDescriptor Descriptor => descriptor; static AnyReflection() { descriptor = FileDescriptor.FromGeneratedCode(Convert.FromBase64String("Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi" + "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnYKE2Nv" + "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaLGdvb2dsZS5nb2xhbmcu" + "b3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2FueXBiogIDR1BCqgIeR29vZ2xl" + "LlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="), new FileDescriptor[0], new GeneratedClrTypeInfo(null, null, new GeneratedClrTypeInfo[1] { new GeneratedClrTypeInfo(typeof(Any), Any.Parser, new string[2] { "TypeUrl", "Value" }, null, null, null, null) })); } } public sealed class Any : IMessage, IMessage, IEquatable, IDeepCloneable, IBufferMessage { private static readonly MessageParser _parser = new MessageParser(() => new Any()); private UnknownFieldSet _unknownFields; public const int TypeUrlFieldNumber = 1; private string typeUrl_ = ""; public const int ValueFieldNumber = 2; private ByteString value_ = ByteString.Empty; private const string DefaultPrefix = "type.googleapis.com"; [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public static MessageParser Parser => _parser; [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public static MessageDescriptor Descriptor => AnyReflection.Descriptor.MessageTypes[0]; [DebuggerNonUserCode] [GeneratedCode("protoc", null)] MessageDescriptor IMessage.Descriptor => Descriptor; [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public string TypeUrl { get { return typeUrl_; } set { typeUrl_ = ProtoPreconditions.CheckNotNull(value, "value"); } } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public ByteString Value { get { return value_; } set { value_ = ProtoPreconditions.CheckNotNull(value, "value"); } } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public Any() { } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public Any(Any other) : this() { typeUrl_ = other.typeUrl_; value_ = other.value_; _unknownFields = UnknownFieldSet.Clone(other._unknownFields); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public Any Clone() { return new Any(this); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public override bool Equals(object other) { return Equals(other as Any); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public bool Equals(Any other) { if (other == null) { return false; } if (other == this) { return true; } if (TypeUrl != other.TypeUrl) { return false; } if (Value != other.Value) { return false; } return object.Equals(_unknownFields, other._unknownFields); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public override int GetHashCode() { int num = 1; if (TypeUrl.Length != 0) { num ^= TypeUrl.GetHashCode(); } if (Value.Length != 0) { num ^= Value.GetHashCode(); } if (_unknownFields != null) { num ^= _unknownFields.GetHashCode(); } return num; } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public override string ToString() { return JsonFormatter.ToDiagnosticString(this); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public void WriteTo(CodedOutputStream output) { output.WriteRawMessage(this); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] void IBufferMessage.InternalWriteTo(ref WriteContext output) { if (TypeUrl.Length != 0) { output.WriteRawTag(10); output.WriteString(TypeUrl); } if (Value.Length != 0) { output.WriteRawTag(18); output.WriteBytes(Value); } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); } } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public int CalculateSize() { int num = 0; if (TypeUrl.Length != 0) { num += 1 + CodedOutputStream.ComputeStringSize(TypeUrl); } if (Value.Length != 0) { num += 1 + CodedOutputStream.ComputeBytesSize(Value); } if (_unknownFields != null) { num += _unknownFields.CalculateSize(); } return num; } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public void MergeFrom(Any other) { if (other != null) { if (other.TypeUrl.Length != 0) { TypeUrl = other.TypeUrl; } if (other.Value.Length != 0) { Value = other.Value; } _unknownFields = UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] public void MergeFrom(CodedInputStream input) { input.ReadRawMessage(this); } [DebuggerNonUserCode] [GeneratedCode("protoc", null)] void IBufferMessage.InternalMergeFrom(ref ParseContext input) { uint num; while ((num = input.ReadTag()) != 0) { switch (num) { default: _unknownFields = UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 10u: TypeUrl = input.ReadString(); break; case 18u: Value = input.ReadBytes(); break; } } } private static string GetTypeUrl(MessageDescriptor descriptor, string prefix) { if (!prefix.EndsWith("/")) { return prefix + "/" + descriptor.FullName; } return prefix + descriptor.FullName; } public static string GetTypeName(string typeUrl) { ProtoPreconditions.CheckNotNull(typeUrl, "typeUrl"); int num = typeUrl.LastIndexOf('/'); if (num != -1) { return typeUrl.Substring(num + 1); } return ""; } public bool Is(MessageDescriptor descriptor) { ProtoPreconditions.CheckNotNull(descriptor, "descriptor"); return GetTypeName(TypeUrl) == descriptor.FullName; } public T Unpack() where T : IMessage, new() { T val = new T(); if (GetTypeName(TypeUrl) != val.Descriptor.FullName) { throw new InvalidProtocolBufferException("Full type name for " + val.Descriptor.Name + " is " + val.Descriptor.FullName + "; Any message's type url is " + TypeUrl); } val.MergeFrom(Value); return val; } public bool TryUnpack(out T result) where T : IMessage, new() { T val = new T(); if (GetTypeName(TypeUrl) != val.Descriptor.FullName) { result = default(T); return false; } val.MergeFrom(Value); result = val; return true; } public static Any Pack(IMessage message) { return Pack(message, "type.googleapis.com"); } public static Any Pack(IMessage message, string typeUrlPrefix) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(typeUrlPrefix, "typeUrlPrefix"); return new Any { TypeUrl = GetTypeUrl(message.Descriptor, typeUrlPrefix), Value = message.ToByteString() }; } } public static class ApiReflection { private static FileDescriptor descriptor; public static FileDescriptor Descriptor => descriptor; static ApiReflection() { descriptor = FileDescriptor.FromGeneratedCode(Convert.FromBase64String("Chlnb29nbGUvcHJvdG9idWYvYXBpLnByb3RvEg9nb29nbGUucHJvdG9idWYa" + "JGdvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90bxoaZ29vZ2xl" + "L3Byb3RvYnVmL3R5cGUucHJvdG8igQIKA0FwaRIMCgRuYW1lGAEgASgJEigK" + "B21ldGhvZHMYAiADKAsyFy5nb29nbGUucHJvdG9idWYuTWV0aG9kEigKB29w" + "dGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9uEg8KB3ZlcnNp" + "b24YBCABKAkSNgoOc291cmNlX2NvbnRleHQYBSABKAsyHi5nb29nbGUucHJv" + "dG9idWYuU291cmNlQ29udGV4dBImCgZtaXhpbnMYBiADKAsyFi5nb29nbGUu" + "cHJvdG9idWYuTWl4aW4SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3Rv" + "YnVmLlN5bnRheCLVAQoGTWV0aG9kEgwKBG5hbWUYASABKAkSGAoQcmVxdWVz" + "dF90eXBlX3VybBgCIAEoCRIZChFyZXF1ZXN0X3N0cmVhbWluZxgDIAEoCBIZ" + "ChFyZXNwb25zZV90eXBlX3VybBgEIAEoCRIaChJyZXNwb25zZV9zdHJlYW1p" + "bmcYBSABKAgSKAoHb3B0aW9ucxgGIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5P" + "cHRpb24SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3RvYnVmLlN5bnRh" + "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCdgoTY29t" + "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAVosZ29vZ2xlLmdvbGFuZy5v" + "cmcvcHJvdG9idWYvdHlwZXMva25vd24vYXBpcGKiAgNHUEKqAh5Hb29nbGUu" + "UHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="), new FileDescriptor[2] { SourceContextReflection.Descriptor, TypeReflection.Descriptor }, new GeneratedClrTypeInfo(null, null, new GeneratedClrTypeInfo[3] { new GeneratedClrTypeInfo(typeof(Api), Api.Parser, new string[7] { "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null, null), new GeneratedClrTypeInfo(typeof(Method), Method.Parser, new string[7] { "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null, null), new GeneratedClrTypeInfo(typeof(Mixin), Mixin.Parser, new string[2] { "Name", "Root" }, null, null, null, null) })); } } public sealed class Api : IMessage, IMessage, IEquatable, IDeepCloneable, IBufferMessage { private static readonly MessageParser _parser = new MessageParser(() => new Api()); private UnknownFieldSet _unknownFields; public const int NameFieldNumber = 1; private string name_ = ""; public const int MethodsFieldNumber = 2; private static readonly FieldCodec _repeated_methods_codec = FieldCodec.ForMessage(18u, Method.Parser); private readonly RepeatedField methods_ = new RepeatedField(); public const int OptionsFieldNumber = 3; private static readonly FieldCodec