using System; using System.Buffers; using System.Buffers.Binary; using System.Buffers.Text; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Microsoft.CodeAnalysis; using ProtoBuf.Internal; using ProtoBuf.Meta; using ProtoBuf.Serializers; using ProtoBuf.WellKnownTypes; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("3.2.56.57311")] [assembly: AssemblyInformationalVersion("3.2.56+dfdfce61a7")] [assembly: InternalsVisibleTo("protobuf-net.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("protobuf-net, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("Benchmark, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("protobuf-net.MessagePipes, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("protobuf-net.ServiceModel, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Marc Gravell")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("See https://github.com/protobuf-net/protobuf-net")] [assembly: AssemblyDescription("Provides simple access to fast and efficient \"Protocol Buffers\" serialization from .NET applications")] [assembly: AssemblyProduct("protobuf-net (netstandard2.1)")] [assembly: AssemblyTitle("protobuf-net.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/protobuf-net/protobuf-net")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.7.115.8147")] [ExcludeFromCodeCoverage] internal static class ThisAssembly { internal const string AssemblyConfiguration = "Release"; internal const string AssemblyFileVersion = "3.2.56.57311"; internal const string AssemblyInformationalVersion = "3.2.56+dfdfce61a7"; internal const string AssemblyName = "protobuf-net.Core"; internal const string AssemblyTitle = "protobuf-net.Core"; internal const string AssemblyVersion = "3.0.0.0"; internal static readonly DateTime GitCommitAuthorDate = new DateTime(638895502940000000L, DateTimeKind.Utc); internal static readonly DateTime GitCommitDate = new DateTime(638895502940000000L, DateTimeKind.Utc); internal const string GitCommitId = "dfdfce61a739cfd76f05fcdacf8a4b3b9e94e684"; internal const bool IsPrerelease = false; internal const bool IsPublicRelease = true; internal const string PublicKey = "002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc"; internal const string PublicKeyToken = "257b51d87d2e4d67"; internal const string RootNamespace = "ProtoBuf"; } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | 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, All = -1 } } namespace ProtoBuf { internal enum TimeSpanScale { Days = 0, Hours = 1, Minutes = 2, Seconds = 3, Milliseconds = 4, Ticks = 5, MinMax = 15 } public static class BclHelpers { internal static readonly DateTime[] EpochOrigin = new DateTime[3] { new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local) }; private const int MAX_DECIMAL_BYTES = 32; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static object GetUninitializedObject(Type type) { return FormatterServices.GetUninitializedObject(type); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteTimeSpanImpl(ref state, timeSpan, DateTimeKind.Unspecified); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimeSpan(ref ProtoWriter.State state, TimeSpan value) { WriteTimeSpanImpl(ref state, value, DateTimeKind.Unspecified); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteTimeSpanImpl(ref ProtoWriter.State state, TimeSpan timeSpan, DateTimeKind kind) { switch (state.WireType) { case WireType.String: case WireType.StartGroup: { PrimaryTypeProvider.ScaledTicks value = new PrimaryTypeProvider.ScaledTicks(timeSpan, kind); state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, value, SerializerCache.InstanceField); break; } case WireType.Fixed64: state.WriteInt64(timeSpan.Ticks); break; default: ThrowHelper.ThrowProtoException("Unexpected wire-type: " + state.WireType); break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadTimeSpan(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadTimeSpan(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadTimeSpan(ref ProtoReader.State state) { switch (state.WireType) { case WireType.String: case WireType.StartGroup: return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(PrimaryTypeProvider.ScaledTicks), SerializerCache.InstanceField).ToTimeSpan(); case WireType.Fixed64: { long num = state.ReadInt64(); return num switch { long.MinValue => TimeSpan.MinValue, long.MaxValue => TimeSpan.MaxValue, _ => TimeSpan.FromTicks(num), }; } default: ThrowHelper.ThrowProtoException($"Unexpected wire-type: {state.WireType}"); return default(TimeSpan); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadDuration(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadDuration(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadDuration(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(Duration), SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDuration(TimeSpan value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteDuration(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDuration(ref ProtoWriter.State state, TimeSpan value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, (Duration)value, (ISerializer)SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadTimestamp(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadTimestamp(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadTimestamp(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(Timestamp), SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimestamp(DateTime value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteTimestamp(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimestamp(ref ProtoWriter.State state, DateTime value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, (Timestamp)value, (ISerializer)SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadDateTime(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadDateTime(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadDateTime(ref ProtoReader.State state) { switch (state.WireType) { case WireType.String: case WireType.StartGroup: return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(PrimaryTypeProvider.ScaledTicks), SerializerCache.InstanceField).ToDateTime(); case WireType.Fixed64: { long num = state.ReadInt64(); return num switch { long.MinValue => DateTime.MinValue, long.MaxValue => DateTime.MaxValue, _ => EpochOrigin[0].AddTicks(num), }; } default: ThrowHelper.ThrowProtoException($"Unexpected wire-type: {state.WireType}"); return default(DateTime); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTime(DateTime value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteDateTimeImpl(ref state, value, includeKind: false); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTime(ref ProtoWriter.State state, DateTime value) { WriteDateTimeImpl(ref state, value, includeKind: false); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTimeWithKind(DateTime value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteDateTimeImpl(ref state, value, includeKind: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTimeWithKind(ref ProtoWriter.State state, DateTime value) { WriteDateTimeImpl(ref state, value, includeKind: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteDateTimeImpl(ref ProtoWriter.State state, DateTime value, bool includeKind) { WireType wireType = state.WireType; TimeSpan timeSpan; if ((uint)(wireType - 2) <= 1u) { if (value == DateTime.MaxValue) { timeSpan = TimeSpan.MaxValue; includeKind = false; } else if (value == DateTime.MinValue) { timeSpan = TimeSpan.MinValue; includeKind = false; } else { timeSpan = value - EpochOrigin[0]; } } else { timeSpan = value - EpochOrigin[0]; } WriteTimeSpanImpl(ref state, timeSpan, includeKind ? value.Kind : DateTimeKind.Unspecified); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal ReadDecimal(ProtoReader reader) { ProtoReader.State state = reader.DefaultState(); return ReadDecimal(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal ReadDecimal(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, 0m, SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static decimal ReadDecimalString(ref ProtoReader.State state) { byte* ptr = stackalloc byte[32]; Span span = state.ReadBytes(new Span(ptr, 32)); if (!Utf8Parser.TryParse((ReadOnlySpan)span, out decimal value, out int bytesConsumed, '\0') || bytesConsumed != span.Length) { ThrowHelper.ThrowInvalidOperationException("Unable to parse decimal: '" + Encoding.UTF8.GetString(ptr, span.Length) + "'"); } return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDecimal(decimal value, ProtoWriter writer) { ProtoWriter.State state = writer.DefaultState(); WriteDecimal(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDecimal(ref ProtoWriter.State state, decimal value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, value, SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDecimalString(ref ProtoWriter.State state, decimal value) { byte[] array = ArrayPool.Shared.Rent(32); try { if (!Utf8Formatter.TryFormat(value, array, out var bytesWritten)) { ThrowHelper.ThrowInvalidOperationException($"Unable to format decimal: '{value}'"); } state.WriteBytes(new ReadOnlyMemory(array, 0, bytesWritten)); } finally { ArrayPool.Shared.Return(array); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuid(Guid value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteGuid(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuid(ref ProtoWriter.State state, Guid value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, value, SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuidBytes(ref ProtoWriter.State state, Guid value) { GuidHelper.Write(ref state, in value, asBytes: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuidString(ref ProtoWriter.State state, Guid value) { GuidHelper.Write(ref state, in value, asBytes: false); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuid(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadGuid(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuid(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(Guid), SerializerCache.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuidBytes(ref ProtoReader.State state) { return GuidHelper.Read(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuidString(ref ProtoReader.State state) { return GuidHelper.Read(ref state); } } public sealed class BufferExtension : IExtension, IExtensionResettable { private ArraySegment _buffer; internal Type Type { get; private set; } internal BufferExtension Tail { get; private set; } internal void SetTail(Type type, BufferExtension tail) { Type = type; Tail = tail; } void IExtensionResettable.Reset() { _buffer = default(ArraySegment); } int IExtension.GetLength() { return _buffer.Count; } Stream IExtension.BeginAppend() { return new MemoryStream(); } void IExtension.EndAppend(Stream stream, bool commit) { using (stream) { if (!commit || !(stream is MemoryStream memoryStream) || !memoryStream.TryGetBuffer(out var buffer) || buffer.Count == 0) { return; } if (_buffer.Count == 0) { _buffer = buffer; return; } int num = _buffer.Offset + _buffer.Count; int num2 = _buffer.Array.Length - num; if (num2 >= buffer.Count) { Buffer.BlockCopy(buffer.Array, buffer.Offset, _buffer.Array, num, buffer.Count); _buffer = new ArraySegment(_buffer.Array, _buffer.Offset, num + buffer.Count); return; } byte[] array = new byte[_buffer.Count + buffer.Count]; Buffer.BlockCopy(_buffer.Array, _buffer.Offset, array, 0, _buffer.Count); Buffer.BlockCopy(buffer.Array, buffer.Offset, array, _buffer.Count, buffer.Count); _buffer = new ArraySegment(array, 0, _buffer.Count + buffer.Count); } } Stream IExtension.BeginQuery() { if (_buffer.Count != 0) { return new MemoryStream(_buffer.Array, _buffer.Offset, _buffer.Count, writable: false, publiclyVisible: true); } return Stream.Null; } void IExtension.EndQuery(Stream stream) { using (stream) { } } } internal static class BufferPool { private static readonly ArrayPool _pool = ArrayPool.Shared; internal const int BUFFER_LENGTH = 1024; private const int MaxByteArraySize = 2147483591; internal static byte[] GetBuffer() { return GetBuffer(1024); } internal static byte[] GetBuffer(int minSize) { byte[] cachedBuffer = GetCachedBuffer(minSize); return cachedBuffer ?? new byte[minSize]; } internal static byte[] GetCachedBuffer(int minSize) { return _pool.Rent(minSize); } internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex, int copyBytes) { int num = buffer.Length * 2; if (num < 0) { num = 2147483591; } if (num < toFitAtLeastBytes) { num = toFitAtLeastBytes; } if (copyBytes == 0) { ReleaseBufferToPool(ref buffer); } byte[] array = GetCachedBuffer(num) ?? new byte[num]; if (copyBytes > 0) { Buffer.BlockCopy(buffer, copyFromIndex, array, 0, copyBytes); ReleaseBufferToPool(ref buffer); } buffer = array; } internal static void ReleaseBufferToPool(ref byte[] buffer) { byte[] array = buffer; buffer = null; if (array != null) { _pool.Return(array); } } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoBeforeSerializationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoAfterSerializationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoBeforeDeserializationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoAfterDeserializationAttribute : Attribute { } public enum CompatibilityLevel { NotSpecified = 0, Level200 = 200, Level240 = 240, Level300 = 300 } [ImmutableObject(true)] [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)] public sealed class CompatibilityLevelAttribute : Attribute { public CompatibilityLevel Level { get; } public CompatibilityLevelAttribute(CompatibilityLevel level) { Level = level; } internal static void AssertValid(CompatibilityLevel compatibilityLevel) { switch (compatibilityLevel) { case CompatibilityLevel.NotSpecified: case CompatibilityLevel.Level200: case CompatibilityLevel.Level240: case CompatibilityLevel.Level300: return; } Throw(compatibilityLevel); static void Throw(CompatibilityLevel compatibilityLevel2) { throw new ArgumentOutOfRangeException("compatibilityLevel", $"Compatiblity level '{compatibilityLevel2}' is not recognized."); } } } public enum DataFormat { Default, ZigZag, TwosComplement, FixedSize, Group, [Obsolete("This option is replaced with CompatibilityLevel, and is only used for Level200, where it changes this field to Level240", false)] WellKnown } [Serializable] [StructLayout(LayoutKind.Auto)] public readonly struct DiscriminatedUnionObject : ISerializable { public readonly object Object; public int Discriminator { get; } public bool Is(int discriminator) { return Discriminator == discriminator; } public DiscriminatedUnionObject(int discriminator, object value) { Discriminator = discriminator; Object = value; } public static void Reset(ref DiscriminatedUnionObject value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnionObject); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (Discriminator != 0) { info.AddValue("d", Discriminator); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnionObject(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnionObject); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; string name = current.Name; if (!(name == "d")) { if (name == "o") { Object = current.Value; } } else { Discriminator = (int)current.Value; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion64 : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; public int Discriminator => _discriminator; private DiscriminatedUnion64(int discriminator) { this = default(DiscriminatedUnion64); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion64(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion64(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion64(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion64(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion64(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion64(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion64(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion64(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion64(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion64 value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion64); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int64 != 0L) { info.AddValue("i", Int64); } } private DiscriminatedUnion64(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion64); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; string name = current.Name; if (!(name == "d")) { if (name == "i") { Int64 = (long)current.Value; } } else { _discriminator = (int)current.Value; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion128Object : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; [FieldOffset(8)] public readonly Guid Guid; [FieldOffset(24)] public readonly object Object; [FieldOffset(8)] private readonly long _lo; [FieldOffset(16)] private readonly long _hi; public int Discriminator => _discriminator; private DiscriminatedUnion128Object(int discriminator) { this = default(DiscriminatedUnion128Object); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion128Object(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion128Object(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion128Object(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion128Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion128Object(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion128Object(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion128Object(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion128Object(int discriminator, object value) : this((value != null) ? discriminator : 0) { Object = value; } public DiscriminatedUnion128Object(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion128Object(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public DiscriminatedUnion128Object(int discriminator, Guid? value) : this(value.HasValue ? discriminator : 0) { Guid = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion128Object value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion128Object); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (_lo != 0L) { info.AddValue("l", _lo); } if (_hi != 0L) { info.AddValue("h", _hi); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnion128Object(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion128Object); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "l": _lo = (long)current.Value; break; case "h": _hi = (long)current.Value; break; case "o": Object = current.Value; break; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion128 : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; [FieldOffset(8)] public readonly Guid Guid; [FieldOffset(8)] private readonly long _lo; [FieldOffset(16)] private readonly long _hi; public int Discriminator => _discriminator; private DiscriminatedUnion128(int discriminator) { this = default(DiscriminatedUnion128); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion128(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion128(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion128(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion128(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion128(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion128(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion128(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion128(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion128(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public DiscriminatedUnion128(int discriminator, Guid? value) : this(value.HasValue ? discriminator : 0) { Guid = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion128 value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion128); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (_lo != 0L) { info.AddValue("l", _lo); } if (_hi != 0L) { info.AddValue("h", _hi); } } private DiscriminatedUnion128(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion128); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "l": _lo = (long)current.Value; break; case "h": _hi = (long)current.Value; break; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion64Object : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; [FieldOffset(16)] public readonly object Object; public int Discriminator => _discriminator; private DiscriminatedUnion64Object(int discriminator) { this = default(DiscriminatedUnion64Object); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion64Object(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion64Object(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion64Object(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion64Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion64Object(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion64Object(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion64Object(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion64Object(int discriminator, object value) : this((value != null) ? discriminator : 0) { Object = value; } public DiscriminatedUnion64Object(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion64Object(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion64Object value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion64Object); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int64 != 0L) { info.AddValue("i", Int64); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnion64Object(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion64Object); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "i": Int64 = (long)current.Value; break; case "o": Object = current.Value; break; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion32 : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(4)] public readonly int Int32; [FieldOffset(4)] public readonly uint UInt32; [FieldOffset(4)] public readonly bool Boolean; [FieldOffset(4)] public readonly float Single; public int Discriminator => _discriminator; private DiscriminatedUnion32(int discriminator) { this = default(DiscriminatedUnion32); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion32(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion32(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion32(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion32(int discriminator, bool value) : this(discriminator) { Boolean = value; } public static void Reset(ref DiscriminatedUnion32 value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion32); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int32 != 0) { info.AddValue("i", Int32); } } private DiscriminatedUnion32(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion32); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; string name = current.Name; if (!(name == "d")) { if (name == "i") { Int32 = (int)current.Value; } } else { _discriminator = (int)current.Value; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion32Object : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(4)] public readonly int Int32; [FieldOffset(4)] public readonly uint UInt32; [FieldOffset(4)] public readonly bool Boolean; [FieldOffset(4)] public readonly float Single; [FieldOffset(8)] public readonly object Object; public int Discriminator => _discriminator; private DiscriminatedUnion32Object(int discriminator) { this = default(DiscriminatedUnion32Object); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion32Object(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion32Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion32Object(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion32Object(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion32Object(int discriminator, object value) : this((value != null) ? discriminator : 0) { Object = value; } public static void Reset(ref DiscriminatedUnion32Object value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion32Object); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int32 != 0) { info.AddValue("i", Int32); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnion32Object(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion32Object); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "i": Int32 = (int)current.Value; break; case "o": Object = current.Value; break; } } } } public abstract class Extensible : ITypedExtensible, IExtensible { private IExtension extensionObject; IExtension IExtensible.GetExtensionObject(bool createIfMissing) { return GetExtensionObject(createIfMissing); } IExtension ITypedExtensible.GetExtensionObject(Type type, bool createIfMissing) { if ((object)type != GetType()) { return GetExtensionObject(ref extensionObject, type, createIfMissing); } return GetExtensionObject(createIfMissing); } [Obsolete("This API is considered, and may no longer be used in all scenarios (in particular when inheritance is involved); it is not recommended to rely on this API")] protected virtual IExtension GetExtensionObject(bool createIfMissing) { return GetExtensionObject(ref extensionObject, GetType(), createIfMissing); } public static IExtension GetExtensionObject(ref IExtension extensionObject, Type type, bool createIfMissing) { if ((object)type == null) { ThrowHelper.ThrowArgumentNullException("type"); } BufferExtension bufferExtension = extensionObject as BufferExtension; BufferExtension bufferExtension2 = bufferExtension; if (bufferExtension == null) { if (extensionObject != null) { ThrowHelper.ThrowNotSupportedException("Custom extension implementations should not be passed to GetExtensionObject"); } } else { while (bufferExtension2 != null) { Type type2 = bufferExtension2.Type; if ((object)type2 == null) { ThrowHelper.ThrowInvalidOperationException("Typed and untyped extension data cannot be mixed"); } if ((object)type2 == type) { return bufferExtension2; } bufferExtension2 = bufferExtension2.Tail; } } if (createIfMissing) { BufferExtension bufferExtension3 = new BufferExtension(); bufferExtension3.SetTail(type, bufferExtension); bufferExtension2 = (BufferExtension)(extensionObject = bufferExtension3); } return bufferExtension2; } public static IExtension GetExtensionObject(ref IExtension extensionObject, bool createIfMissing) { if (extensionObject == null) { if (createIfMissing) { extensionObject = new BufferExtension(); } } else if (extensionObject is BufferExtension { Type: not null }) { ThrowHelper.ThrowInvalidOperationException("Typed and untyped extension data cannot be mixed"); } return extensionObject; } public static void AppendValue(IExtensible instance, int tag, TValue value) { ExtensibleUtil.AppendExtendValue(null, instance, tag, DataFormat.Default, value); } public static void AppendValue(IExtensible instance, int tag, DataFormat format, TValue value) { ExtensibleUtil.AppendExtendValue(null, instance, tag, format, value); } public static void AppendValue(TypeModel model, IExtensible instance, int tag, TValue value, DataFormat format = DataFormat.Default) { ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); } public static TValue GetValue(IExtensible instance, int tag) { return GetValue(null, instance, tag); } public static TValue GetValue(IExtensible instance, int tag, DataFormat format) { return GetValue(null, instance, tag, format); } public static TValue GetValue(TypeModel model, IExtensible instance, int tag, DataFormat format = DataFormat.Default) { if (!TryGetValue(model, instance, tag, out var value, format)) { return default(TValue); } return value; } public static bool TryGetValue(IExtensible instance, int tag, out TValue value) { return TryGetValue(null, instance, tag, out value); } public static bool TryGetValue(IExtensible instance, int tag, DataFormat format, out TValue value) { return TryGetValue(null, instance, tag, out value, format); } public static bool TryGetValue(IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out TValue value) { return TryGetValue(null, instance, tag, out value, format, allowDefinedTag); } public static bool TryGetValue(TypeModel model, IExtensible instance, int tag, out TValue value, DataFormat format = DataFormat.Default, bool allowDefinedTag = false) { value = default(TValue); bool result = false; foreach (TValue extendedValue in ExtensibleUtil.GetExtendedValues(model, instance, tag, format, singleton: true, allowDefinedTag)) { value = extendedValue; result = true; } return result; } public static IEnumerable GetValues(IExtensible instance, int tag) { return ExtensibleUtil.GetExtendedValues(null, instance, tag, DataFormat.Default, singleton: false, allowDefinedTag: false); } public static IEnumerable GetValues(IExtensible instance, int tag, DataFormat format) { return ExtensibleUtil.GetExtendedValues(null, instance, tag, format, singleton: false, allowDefinedTag: false); } public static IEnumerable GetValues(TypeModel model, IExtensible instance, int tag, DataFormat format = DataFormat.Default) { return ExtensibleUtil.GetExtendedValues(model, instance, tag, format, singleton: false, allowDefinedTag: false); } public static bool TryGetValue(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out object value) { value = null; bool result = false; foreach (object extendedValue in ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, singleton: true, allowDefinedTag)) { value = extendedValue; result = true; } return result; } public static IEnumerable GetValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format = DataFormat.Default) { return ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, singleton: false, allowDefinedTag: false); } public static void AppendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) { ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); } } internal static class ExtensibleUtil { internal static IEnumerable GetExtendedValues(TypeModel model, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { foreach (TValue extendedValue in GetExtendedValues(model, typeof(TValue), instance, tag, format, singleton, allowDefinedTag)) { yield return extendedValue; } } internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } if (tag <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException("tag"); } return GetExtendedValues(model, type, instance.GetExtensionObject(createIfMissing: false), tag, format, singleton); } internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtension extn, int tag, DataFormat format, bool singleton) { if (model == null) { model = TypeModel.DefaultModel; } if (extn == null) { yield break; } Stream stream = extn.BeginQuery(); try { object value = null; SerializationContext userState = new SerializationContext(); ProtoReader.SolidState state = ProtoReader.State.Create(stream, model, userState, -1L).Solidify(); try { while (model.TryDeserializeAuxiliaryType(ref state, format, tag, type, ref value, skipOtherFields: true, asListItem: true, autoCreate: false, insideList: false, null, isRoot: false) && value != null) { if (!singleton) { yield return value; value = null; } } if (singleton && value != null) { yield return value; } } finally { state.Dispose(); } } finally { extn.EndQuery(stream); } } internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } if (value == null) { ThrowHelper.ThrowArgumentNullException("value"); } AppendExtendValue(model, instance.GetExtensionObject(createIfMissing: true), tag, format, value); } internal static void AppendExtendValue(TypeModel model, IExtension extn, int tag, DataFormat format, object value) { if (model == null) { model = TypeModel.DefaultModel; } if (extn == null) { ThrowHelper.ThrowInvalidOperationException("No extension object available; appended data would be lost."); } bool commit = false; Stream stream = extn.BeginAppend(); try { ProtoWriter.State state = ProtoWriter.State.Create(stream, model); try { model.TrySerializeAuxiliaryType(ref state, null, format, tag, value, isInsideList: false, null, isRoot: false); state.Close(); } catch { state.Abandon(); throw; } finally { state.Dispose(); } commit = true; } finally { extn.EndAppend(stream, commit); } } } internal static class Helpers { internal static MethodInfo GetInstanceMethod(Type declaringType, string name) { return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } internal static MethodInfo GetStaticMethod(Type declaringType, string name) { return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) { if (types == null) { types = Type.EmptyTypes; } return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null); } internal static bool IsSubclassOf(Type type, Type baseClass) { return type.IsSubclassOf(baseClass); } public static ProtoTypeCode GetTypeCode(Type type) { TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Empty: case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: return (ProtoTypeCode)typeCode; default: if (type == typeof(TimeSpan)) { return ProtoTypeCode.TimeSpan; } if (type == typeof(Guid)) { return ProtoTypeCode.Guid; } if (type == typeof(Uri)) { return ProtoTypeCode.Uri; } if (type == typeof(byte[])) { return ProtoTypeCode.ByteArray; } if (type == typeof(ArraySegment)) { return ProtoTypeCode.ByteArraySegment; } if (type == typeof(Memory)) { return ProtoTypeCode.ByteMemory; } if (type == typeof(ReadOnlyMemory)) { return ProtoTypeCode.ByteReadOnlyMemory; } if (type == typeof(Type)) { return ProtoTypeCode.Type; } if (type == typeof(IntPtr)) { return ProtoTypeCode.IntPtr; } if (type == typeof(UIntPtr)) { return ProtoTypeCode.UIntPtr; } return ProtoTypeCode.Unknown; } } internal static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) { if ((object)property == null) { return null; } MethodInfo methodInfo = property.GetGetMethod(nonPublic); if ((object)methodInfo == null && !nonPublic && allowInternal) { methodInfo = property.GetGetMethod(nonPublic: true); if ((object)methodInfo != null && !methodInfo.IsAssembly && !methodInfo.IsFamilyOrAssembly) { methodInfo = null; } } return methodInfo; } internal static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) { if ((object)property == null) { return null; } MethodInfo methodInfo = property.GetSetMethod(nonPublic); if ((object)methodInfo == null && !nonPublic && allowInternal) { methodInfo = property.GetSetMethod(nonPublic: true); if ((object)methodInfo != null && !methodInfo.IsAssembly && !methodInfo.IsFamilyOrAssembly) { methodInfo = null; } } return methodInfo; } internal static ConstructorInfo GetConstructor(Type type, Type[] parameterTypes, bool nonPublic) { return type.GetConstructor(nonPublic ? (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : (BindingFlags.Instance | BindingFlags.Public), null, parameterTypes, null); } internal static ConstructorInfo[] GetConstructors(Type type, bool nonPublic) { return type.GetConstructors(nonPublic ? (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : (BindingFlags.Instance | BindingFlags.Public)); } internal static void GetBuffer(MemoryStream stream, out ArraySegment segment) { if (stream == null || !stream.TryGetBuffer(out segment)) { ThrowHelper.ThrowInvalidOperationException("Unable to obtain buffer from MemoryStream"); segment = default(ArraySegment); } } internal static PropertyInfo GetProperty(Type type, string name, bool nonPublic) { return type.GetProperty(name, nonPublic ? (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : (BindingFlags.Instance | BindingFlags.Public)); } internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly) { BindingFlags bindingAttr = (publicOnly ? (BindingFlags.Instance | BindingFlags.Public) : (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); PropertyInfo[] properties = type.GetProperties(bindingAttr); FieldInfo[] fields = type.GetFields(bindingAttr); MemberInfo[] array = new MemberInfo[fields.Length + properties.Length]; properties.CopyTo(array, 0); fields.CopyTo(array, properties.Length); return array; } internal static Type GetMemberType(MemberInfo member) { return member.MemberType switch { MemberTypes.Field => ((FieldInfo)member).FieldType, MemberTypes.Property => ((PropertyInfo)member).PropertyType, _ => null, }; } } internal enum ProtoTypeCode { Empty = 0, Unknown = 1, Boolean = 3, Char = 4, SByte = 5, Byte = 6, Int16 = 7, UInt16 = 8, Int32 = 9, UInt32 = 10, Int64 = 11, UInt64 = 12, Single = 13, Double = 14, Decimal = 15, DateTime = 16, String = 18, TimeSpan = 100, ByteArray = 101, Guid = 102, Uri = 103, Type = 104, ByteArraySegment = 105, ByteMemory = 106, ByteReadOnlyMemory = 107, IntPtr = 108, UIntPtr = 109 } public interface IExtensible { IExtension GetExtensionObject(bool createIfMissing); } public interface ITypedExtensible { IExtension GetExtensionObject(Type type, bool createIfMissing); } public interface IExtension { Stream BeginAppend(); void EndAppend(Stream stream, bool commit); Stream BeginQuery(); void EndQuery(Stream stream); int GetLength(); } public interface IExtensionResettable : IExtension { void Reset(); } public enum ImplicitFields { None, AllPublic, AllFields } public interface IProtoInput<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TInput> { T Deserialize(TInput source, T value = default(T), object userState = null); } public interface IProtoOutput<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TOutput> { void Serialize(TOutput destination, T value, object userState = null); } public interface IMeasuredProtoOutput<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TOutput> : IProtoOutput { MeasureState Measure(T value, object userState = null); void Serialize(MeasureState measured, TOutput destination); } public interface ISerializationContext { TypeModel Model { get; } object UserState { get; } } public struct MeasureState<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> : IDisposable { private readonly TypeModel _model; private readonly T _value; private readonly object _userState; private ProtoWriter _writer; public long Length { get; } internal MeasureState(TypeModel model, in T value, object userState, long abortAfter) { _model = model; _value = value; _userState = userState; ProtoWriter.State state = ProtoWriter.NullProtoWriter.CreateNullProtoWriter(_model, userState, abortAfter); try { Length = TypeModel.SerializeImpl(ref state, _value); ProtoWriter.NullProtoWriter.CheckOversized(abortAfter, Length); _writer = state.GetWriter(); } catch { state.Dispose(); throw; } } public void Dispose() { ProtoWriter writer = _writer; _writer = null; writer?.Dispose(); } public long LengthOnly() { long length = Length; Dispose(); return length; } private readonly void SerializeCore(ProtoWriter.State state) { try { ProtoWriter writer = _writer ?? throw new ObjectDisposedException("MeasureState"); ProtoWriter writer2 = state.GetWriter(); writer2.InitializeFrom(writer); long num = TypeModel.SerializeImpl(ref state, _value); writer2.CopyBack(writer); if (num != Length) { ThrowHelper.ThrowInvalidOperationException($"Invalid length; expected {Length}, actual: {num}"); } } catch (Exception ex) { ex.Data?.Add("ProtoBuf.MeasuredLength", Length); throw; } finally { state.Dispose(); } } internal readonly int GetLengthHits(out int misses) { return _writer.GetLengthHits(out misses); } public readonly void Serialize(Stream stream) { SerializeCore(ProtoWriter.State.Create(stream, _model, _userState)); } public readonly void Serialize(IBufferWriter writer) { SerializeCore(ProtoWriter.State.Create(writer, _model, _userState)); } } internal sealed class NetObjectCache { [StructLayout(LayoutKind.Auto)] private readonly struct ObjectKey : IEquatable { private readonly object _obj; private readonly Type _subTypeLevel; [MethodImpl(MethodImplOptions.AggressiveInlining)] public ObjectKey(object obj, Type subTypeLevel) { _obj = obj; _subTypeLevel = subTypeLevel; } public override string ToString() { return $"{_subTypeLevel}/{_obj}"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { return RuntimeHelpers.GetHashCode(_obj) ^ (_subTypeLevel?.GetHashCode() ?? 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object obj) { if (obj is ObjectKey other) { return Equals(other); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(ObjectKey other) { return (_obj == other._obj) & (_subTypeLevel == other._subTypeLevel); } } private readonly Dictionary _knownLengths = new Dictionary(); private int _hit; private int _miss; internal int LengthHits => _hit; internal int LengthMisses => _miss; [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetKnownLength(object obj, Type subTypeLevel, out long length) { if (_knownLengths.TryGetValue(new ObjectKey(obj, subTypeLevel), out length)) { _hit++; return true; } _miss++; length = 0L; return false; } public void SetKnownLength(object obj, Type subTypeLevel, long length) { ObjectKey key = new ObjectKey(obj, subTypeLevel); _knownLengths[key] = length; } internal void Clear() { _knownLengths.Clear(); _hit = (_miss = 0); } internal void InitializeFrom(NetObjectCache obj) { if (obj == null) { return; } _knownLengths.Clear(); foreach (KeyValuePair knownLength in obj._knownLengths) { _knownLengths.Add(knownLength.Key, knownLength.Value); } } internal void CopyBack(NetObjectCache obj) { if (obj != null) { obj._hit += _hit; obj._miss += _miss; } } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class NullWrappedValueAttribute : Attribute { public bool AsGroup { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class NullWrappedCollectionAttribute : Attribute { public bool AsGroup { get; set; } } public enum PrefixStyle { None, Base128, Fixed32, Fixed32BigEndian } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] public sealed class ProtoContractAttribute : Attribute { [Flags] private enum TypeOptions : ushort { InferTagFromName = 1, InferTagFromNameHasValue = 2, UseProtoMembersOnly = 4, SkipConstructor = 8, IgnoreListHandling = 0x10, IsGroup = 0x100, IgnoreUnknownSubTypes = 0x200 } internal const string ReferenceDynamicDisabled = "Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited"; private int implicitFirstTag; private TypeOptions flags; public string Name { get; set; } public string Origin { get; set; } public int ImplicitFirstTag { get { return implicitFirstTag; } set { if (value < 1) { ThrowHelper.ThrowArgumentOutOfRangeException("ImplicitFirstTag"); } implicitFirstTag = value; } } public bool UseProtoMembersOnly { get { return HasFlag(TypeOptions.UseProtoMembersOnly); } set { SetFlag(TypeOptions.UseProtoMembersOnly, value); } } public bool IgnoreListHandling { get { return HasFlag(TypeOptions.IgnoreListHandling); } set { SetFlag(TypeOptions.IgnoreListHandling, value); } } public ImplicitFields ImplicitFields { get; set; } public bool InferTagFromName { get { return HasFlag(TypeOptions.InferTagFromName); } set { SetFlag(TypeOptions.InferTagFromName, value); SetFlag(TypeOptions.InferTagFromNameHasValue, value: true); } } internal bool InferTagFromNameHasValue => HasFlag(TypeOptions.InferTagFromNameHasValue); public int DataMemberOffset { get; set; } public bool SkipConstructor { get { return HasFlag(TypeOptions.SkipConstructor); } set { SetFlag(TypeOptions.SkipConstructor, value); } } public bool AsReferenceDefault { get { return false; } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] set { if (value != AsReferenceDefault) { ThrowHelper.ThrowNotSupportedException(); } } } public bool IsGroup { get { return HasFlag(TypeOptions.IsGroup); } set { SetFlag(TypeOptions.IsGroup, value); } } public bool IgnoreUnknownSubTypes { get { return HasFlag(TypeOptions.IgnoreUnknownSubTypes); } set { SetFlag(TypeOptions.IgnoreUnknownSubTypes, value); } } [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", true)] public bool EnumPassthru { get { return true; } set { if (!value) { ThrowHelper.ThrowInvalidOperationException("EnumPassthru is not longer supported, and is always considered true"); } } } public Type Surrogate { get; set; } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)] public Type Serializer { get; set; } private bool HasFlag(TypeOptions flag) { return (flags & flag) == flag; } private void SetFlag(TypeOptions flag, bool value) { if (value) { flags |= flag; } else { flags &= (TypeOptions)(ushort)(~(int)flag); } } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class ProtoConverterAttribute : Attribute { } [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public sealed class ProtoEnumAttribute : Attribute { internal const string EnumValueDeprecated = "Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties"; public int Value { [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", false)] get { return 0; } [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", true)] set { ThrowHelper.ThrowNotSupportedException(); } } public string Name { get; set; } [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", false)] public bool HasValue() { return false; } } [Serializable] public class ProtoException : Exception { public ProtoException() { } public ProtoException(string message) : base(message) { } public ProtoException(string message, Exception innerException) : base(message, innerException) { } protected ProtoException(SerializationInfo info, StreamingContext context) : base(info, context) { } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class ProtoIgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public sealed class ProtoPartialIgnoreAttribute : ProtoIgnoreAttribute { public string MemberName { get; } public ProtoPartialIgnoreAttribute(string memberName) { if (string.IsNullOrEmpty(memberName)) { ThrowHelper.ThrowArgumentNullException("memberName"); } MemberName = memberName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] public sealed class ProtoIncludeAttribute : Attribute { public int Tag { get; } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public string KnownTypeName { get; } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public Type KnownType => TypeModel.ResolveKnownType(KnownTypeName, null); [DefaultValue(DataFormat.Default)] public DataFormat DataFormat { get; set; } public ProtoIncludeAttribute(int tag, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type knownType) : this(tag, ((object)knownType == null) ? "" : knownType.AssemblyQualifiedName) { } public ProtoIncludeAttribute(int tag, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] string knownTypeName) { if (tag <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException("tag", "Tags must be positive integers"); } if (string.IsNullOrEmpty(knownTypeName)) { ThrowHelper.ThrowArgumentNullException("knownTypeName", "Known type cannot be blank"); } Tag = tag; KnownTypeName = knownTypeName; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class ProtoMapAttribute : Attribute { public DataFormat KeyFormat { get; set; } public DataFormat ValueFormat { get; set; } public bool DisableMap { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class ProtoMemberAttribute : Attribute, IComparable, IComparable { internal MemberInfo Member; internal MemberInfo BackingMember; internal bool TagIsPinned; private string name; private DataFormat dataFormat; private int tag; private MemberSerializationOptions options; public string Name { get { return name; } set { name = value; } } public DataFormat DataFormat { get { return dataFormat; } set { dataFormat = value; } } public int Tag => tag; public bool IsRequired { get { return (options & MemberSerializationOptions.Required) == MemberSerializationOptions.Required; } set { if (value) { options |= MemberSerializationOptions.Required; } else { options &= ~MemberSerializationOptions.Required; } } } public bool IsPacked { get { return (options & MemberSerializationOptions.Packed) == MemberSerializationOptions.Packed; } set { if (value) { options |= MemberSerializationOptions.Packed; } else { options &= ~MemberSerializationOptions.Packed; } } } public bool OverwriteList { get { return (options & MemberSerializationOptions.OverwriteList) == MemberSerializationOptions.OverwriteList; } set { if (value) { options |= MemberSerializationOptions.OverwriteList; } else { options &= ~MemberSerializationOptions.OverwriteList; } } } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] public bool AsReference { get { return (options & MemberSerializationOptions.AsReference) == MemberSerializationOptions.AsReference; } set { if (value) { options |= MemberSerializationOptions.AsReference; } else { options &= ~MemberSerializationOptions.AsReference; } options |= MemberSerializationOptions.AsReferenceHasValue; } } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] internal bool AsReferenceHasValue { get { return (options & MemberSerializationOptions.AsReferenceHasValue) == MemberSerializationOptions.AsReferenceHasValue; } set { if (value) { options |= MemberSerializationOptions.AsReferenceHasValue; } else { options &= ~MemberSerializationOptions.AsReferenceHasValue; } } } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] public bool DynamicType { get { return (options & MemberSerializationOptions.DynamicType) == MemberSerializationOptions.DynamicType; } set { if (value) { options |= MemberSerializationOptions.DynamicType; } else { options &= ~MemberSerializationOptions.DynamicType; } } } public MemberSerializationOptions Options { get { return options; } set { options = value; } } public int CompareTo(object other) { return CompareTo(other as ProtoMemberAttribute); } public int CompareTo(ProtoMemberAttribute other) { if (other == null) { return -1; } if (this == other) { return 0; } int num = tag.CompareTo(other.tag); if (num == 0) { num = string.CompareOrdinal(name, other.name); } return num; } public ProtoMemberAttribute(int tag) : this(tag, forced: false) { } internal ProtoMemberAttribute(int tag, bool forced) { if (tag <= 0 && !forced) { ThrowHelper.ThrowArgumentOutOfRangeException("tag"); } this.tag = tag; } internal void Rebase(int tag) { this.tag = tag; } } [Flags] public enum MemberSerializationOptions { None = 0, Packed = 1, Required = 2, [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", false)] AsReference = 4, [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", false)] DynamicType = 8, OverwriteList = 0x10, [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", false)] AsReferenceHasValue = 0x20 } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public sealed class ProtoPartialMemberAttribute : ProtoMemberAttribute { public string MemberName { get; private set; } public ProtoPartialMemberAttribute(int tag, string memberName) : base(tag) { if (string.IsNullOrEmpty(memberName)) { ThrowHelper.ThrowArgumentNullException("memberName"); } MemberName = memberName; } } public abstract class ProtoReader : IDisposable, ISerializationContext { private protected enum Read32VarintMode { Signed, Unsigned, FieldHeader } [StructLayout(LayoutKind.Auto)] public ref struct State { private ProtoReader _reader; private ReadOnlyMemory _memory; internal ReadOnlySpan Span { get; private set; } internal int OffsetInCurrent { get; private set; } internal int RemainingInCurrent { get; private set; } public readonly WireType WireType { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader.WireType; } } public readonly bool InternStrings { get { return _reader.InternStrings; } set { _reader.InternStrings = value; } } public readonly int FieldNumber { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader._fieldNumber; } } internal readonly TypeModel Model { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader?.Model; } private set { _reader.Model = value; } } public readonly ISerializationContext Context { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader; } } public static State Create(ReadOnlySequence source, TypeModel model, object userState = null) { ReadOnlySequenceProtoReader readOnlySequenceProtoReader = Pool.TryGet() ?? new ReadOnlySequenceProtoReader(); readOnlySequenceProtoReader.Init(source, model, userState); return new State(readOnlySequenceProtoReader); } public static State Create(ReadOnlyMemory source, TypeModel model, object userState = null) { return Create(new ReadOnlySequence(source), model, userState); } public void Dispose() { ProtoReader reader = _reader; this = default(State); reader?.Dispose(); } internal readonly SolidState Solidify() { return new SolidState(_reader, _memory.Slice(OffsetInCurrent, RemainingInCurrent)); } internal State(ProtoReader reader, ReadOnlyMemory memory) : this(reader) { Init(memory); } internal State(ProtoReader reader) { this = default(State); _reader = reader; } internal void Init(ReadOnlyMemory memory) { _memory = memory; Span = memory.Span; OffsetInCurrent = 0; RemainingInCurrent = Span.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Skip(int bytes) { OffsetInCurrent += bytes; RemainingInCurrent -= bytes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlySpan Consume(int bytes) { ReadOnlySpan result = Span.Slice(OffsetInCurrent, bytes); OffsetInCurrent += bytes; RemainingInCurrent -= bytes; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlySpan Consume(int bytes, out int offset) { offset = OffsetInCurrent; OffsetInCurrent += bytes; RemainingInCurrent -= bytes; return Span; } internal int ReadVarintUInt32(out uint value) { value = Span[OffsetInCurrent]; int num = (((value & 0x80) == 0) ? 1 : ParseVarintUInt32Tail(Span.Slice(OffsetInCurrent), ref value)); OffsetInCurrent += num; RemainingInCurrent -= num; return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal int ParseVarintUInt32(ReadOnlySpan span, out uint value) { value = span[0]; if ((value & 0x80) != 0) { return ParseVarintUInt32Tail(span, ref value); } return 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal int ParseVarintUInt32(ReadOnlySpan span, int offset, out uint value) { value = span[offset]; if ((value & 0x80) != 0) { return ParseVarintUInt32Tail(span.Slice(offset), ref value); } return 1; } private int ParseVarintUInt32Tail(ReadOnlySpan span, ref uint value) { uint num = span[1]; value = (value & 0x7F) | ((num & 0x7F) << 7); if ((num & 0x80) == 0) { return 2; } num = span[2]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0) { return 3; } num = span[3]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0) { return 4; } num = span[4]; value |= num << 28; if ((num & 0xF0) == 0) { return 5; } ThrowOverflow(); return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal readonly void Advance(long count) { _reader.Advance(count); } internal static int TryParseUInt64Varint(ReadOnlySpan span, int offset, out ulong value) { if ((uint)offset >= (uint)span.Length) { value = 0uL; return 0; } value = span[offset++]; if ((value & 0x80) == 0L) { return 1; } value &= 127uL; if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } ulong num = span[offset++]; value |= (num & 0x7F) << 7; if ((num & 0x80) == 0L) { return 2; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0L) { return 3; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0L) { return 4; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 28; if ((num & 0x80) == 0L) { return 5; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 35; if ((num & 0x80) == 0L) { return 6; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 42; if ((num & 0x80) == 0L) { return 7; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 49; if ((num & 0x80) == 0L) { return 8; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 56; if ((num & 0x80) == 0L) { return 9; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset]; value |= num << 63; if ((num & 0xFFFFFFFFFFFFFFFEuL) != 0L) { NoContextThrowOverflow(); } return 10; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal readonly ProtoReader GetReader() { return _reader; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ushort ReadUInt16() { return checked((ushort)ReadUInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public short ReadInt16() { return checked((short)ReadInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly long GetPosition() { return _reader._longPosition; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte ReadByte() { return checked((byte)ReadUInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public sbyte ReadSByte() { return checked((sbyte)ReadInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public IntPtr ReadIntPtr() { return new IntPtr(ReadInt64()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public UIntPtr ReadUIntPtr() { return new UIntPtr(ReadUInt64()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadUInt32() { switch (_reader.WireType) { case WireType.Variant: return ReadUInt32Varint(Read32VarintMode.Signed); case WireType.Fixed32: return _reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: { ulong num = _reader.ImplReadUInt64Fixed(ref this); return checked((uint)num); } default: ThrowWireTypeException(); return 0u; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadInt32() { switch (_reader.WireType) { case WireType.Variant: return (int)ReadUInt32Varint(Read32VarintMode.Signed); case WireType.Fixed32: return (int)_reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: { long num = ReadInt64(); return checked((int)num); } case WireType.SignedVariant: return Zag(ReadUInt32Varint(Read32VarintMode.Signed)); default: ThrowWireTypeException(); return 0; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadInt64() { switch (_reader.WireType) { case WireType.Variant: return (long)ReadUInt64Varint(); case WireType.Fixed32: return (int)_reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: return (long)_reader.ImplReadUInt64Fixed(ref this); case WireType.SignedVariant: return Zag(ReadUInt64Varint()); default: ThrowWireTypeException(); return 0L; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe double ReadDouble() { switch (_reader.WireType) { case WireType.Fixed32: return ReadSingle(); case WireType.Fixed64: { long num = ReadInt64(); return *(double*)(&num); } default: ThrowWireTypeException(); return 0.0; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe float ReadSingle() { switch (_reader.WireType) { case WireType.Fixed32: { int num3 = ReadInt32(); return *(float*)(&num3); } case WireType.Fixed64: { double num = ReadDouble(); float num2 = (float)num; if (float.IsInfinity(num2) && !double.IsInfinity(num)) { ThrowOverflow(); } return num2; } default: ThrowWireTypeException(); return 0f; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void PrepareToReadRepeated(ref SerializerFeatures features, SerializerFeatures serializerFeatures, out SerializerFeatures category, out bool packed) { if (serializerFeatures.IsRepeated()) { TypeModel.ThrowNestedListsNotSupported(typeof(T)); } features.InheritFrom(serializerFeatures); category = serializerFeatures.GetCategory(); packed = false; if (TypeHelper.CanBePacked && WireType == WireType.String && !features.HasAny(SerializerFeatures.OptionWrappedValue)) { if (category != SerializerFeatures.CategoryScalar) { ThrowInvalidOperationException("Packed data expected a scalar serializer"); } packed = true; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ReadRepeatedCore(ref TList values, SerializerFeatures category, WireType wireType, in TSerializer serializer, SerializerFeatures features) where TSerializer : ISerializer where TList : ICollection { int fieldNumber = FieldNumber; bool flag = features.HasAny(SerializerFeatures.OptionWrappedValue); T value = features.DefaultFor(); do { T item; if (flag) { item = ReadWrapped(features, value, serializer); } else { switch (category) { case SerializerFeatures.CategoryScalar: Hint(wireType); item = serializer.Read(ref this, value); break; case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: item = ReadMessage(SerializerFeatures.CategoryRepeated, value, in serializer); break; default: category.ThrowInvalidCategory(); item = default(T); break; } } values.Add(item); } while (TryReadFieldHeader(fieldNumber)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ReadPackedScalar(ref TList list, WireType wireType, in TSerializer serializer) where TSerializer : ISerializer where TList : ICollection { int num = (int)ReadUInt32Varint(Read32VarintMode.Unsigned); if (num == 0) { return; } if (num < 0) { ThrowInvalidLength(num); } int num2; if (wireType <= WireType.Fixed64) { if (wireType == WireType.Variant) { goto IL_00ff; } if (wireType == WireType.Fixed64) { if (num % 8 != 0) { ThrowHelper.ThrowInvalidOperationException("packed length should be multiple of 8"); } num2 = num / 8; goto IL_0065; } } else { if (wireType == WireType.Fixed32) { if (num % 4 != 0) { ThrowHelper.ThrowInvalidOperationException("packed length should be multiple of 4"); } num2 = num / 4; goto IL_0065; } if (wireType == WireType.SignedVariant) { goto IL_00ff; } } ThrowHelper.ThrowInvalidPackedOperationException(WireType, typeof(T)); return; IL_0065: if (list is List list2) { list2.Capacity = Math.Max(list2.Capacity, list2.Count + Math.Min(num2, 8192)); } TList val; TSerializer val2; for (int i = 0; i < num2; i++) { _reader.WireType = wireType; ref TList reference = ref list; val = default(TList); if (val == null) { val = reference; reference = ref val; } val2 = serializer; T item = val2.Read(ref this, default(T)); reference.Add(item); } return; IL_00ff: long num3 = GetPosition() + num; do { _reader.WireType = wireType; ref TList reference2 = ref list; val = default(TList); if (val == null) { val = reference2; reference2 = ref val; } val2 = serializer; T item2 = val2.Read(ref this, default(T)); reference2.Add(item2); } while (GetPosition() < num3); if (GetPosition() != num3) { ThrowHelper.ThrowInvalidOperationException("over-read packed data"); } } internal ReadBuffer FillBuffer(SerializerFeatures features, in TSerializer serializer, T initialValue) where TSerializer : ISerializer { PrepareToReadRepeated(ref features, serializer.Features, out var category, out var packed); ReadBuffer values = ReadBuffer.Create(); try { WireType wireType = features.GetWireType(); if (packed) { ReadPackedScalar, T>(ref values, wireType, in serializer); } else { ReadRepeatedCore, T>(ref values, category, wireType, in serializer, features); } return values; } catch { try { values.Dispose(); } catch { } throw; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ReadBoolean() { return ReadUInt32() != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadUInt64() { switch (_reader.WireType) { case WireType.Variant: return ReadUInt64Varint(); case WireType.Fixed32: return _reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: return _reader.ImplReadUInt64Fixed(ref this); default: ThrowWireTypeException(); return 0uL; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] AppendBytes(byte[] value) { return AppendBytesImpl(value, DefaultMemoryConverter.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory AppendBytes(ReadOnlyMemory value) { return AppendBytesImpl(value, DefaultMemoryConverter.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory AppendBytes(Memory value) { return AppendBytesImpl(value, DefaultMemoryConverter.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ArraySegment AppendBytes(ArraySegment value) { return AppendBytesImpl(value, DefaultMemoryConverter.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public TStorage AppendBytes(TStorage value, IMemoryConverter converter = null) { return AppendBytesImpl(value, converter ?? DefaultMemoryConverter.GetFor(Model)); } private TStorage AppendBytesImpl(TStorage value, IMemoryConverter converter) { WireType wireType = _reader.WireType; if (wireType == WireType.String) { int num = (int)ReadUInt32Varint(Read32VarintMode.Signed); _reader.WireType = WireType.None; if (num == 0) { return converter.NonNull(in value); } if (num < 0) { ThrowInvalidLength(num); } Memory memory = converter.Expand(Context, ref value, num); _reader.ImplReadBytes(ref this, memory.Span); return value; } ThrowWireTypeException(); return default(TStorage); } [Browsable(false)] public Span ReadBytes(Span destination) { ReadBytes(destination, out var length); return destination.Slice(0, length); } public void ReadBytes(Span destination, out int length) { WireType wireType = _reader.WireType; if (wireType == WireType.String) { length = (int)ReadUInt32Varint(Read32VarintMode.Signed); if (length < 0) { ThrowInvalidLength(length); } if (length > destination.Length) { ThrowHelper.ThrowInvalidOperationException($"Insufficient space in the target span to read a string/bytes value; {destination.Length} vs {length} bytes"); } _reader.WireType = WireType.None; destination = destination.Slice(0, length); _reader.ImplReadBytes(ref this, destination); } else { length = 0; ThrowWireTypeException(); } } [MethodImpl(MethodImplOptions.NoInlining)] public SubItemToken StartSubItem() { ProtoReader reader = _reader; switch (_reader.WireType) { case WireType.StartGroup: reader.WireType = WireType.None; if (reader.IncrDepth()) { ThrowTooDeep(); } return new SubItemToken(-reader._fieldNumber); case WireType.String: { long num = (long)ReadUInt64Varint(); if (num < 0) { ThrowInvalidOperationException(); } long blockEnd = reader.blockEnd64; reader.blockEnd64 = reader._longPosition + num; if (reader.IncrDepth()) { ThrowTooDeep(); } return new SubItemToken(blockEnd); } default: ThrowWireTypeException(); return default(SubItemToken); } } [MethodImpl(MethodImplOptions.NoInlining)] public void EndSubItem(SubItemToken token) { long value = token.value64; ProtoReader reader = _reader; WireType wireType = reader.WireType; if (wireType == WireType.EndGroup) { if (value >= 0) { ThrowProtoException("A length-based message was terminated via end-group; this indicates data corruption"); } if (-(int)value != reader._fieldNumber) { ThrowProtoException("Wrong group was ended"); } reader.WireType = WireType.None; reader.DecrDepth(); return; } long longPosition = reader._longPosition; if (value < longPosition) { ThrowProtoException($"Sub-message not read entirely; expected {value}, was {longPosition}"); } if (reader.blockEnd64 != longPosition && reader.blockEnd64 != long.MaxValue) { ThrowProtoException($"Sub-message not read correctly (end {reader.blockEnd64} vs {longPosition})"); } reader.blockEnd64 = value; reader.DecrDepth(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal object ReadObject(object value, Type type) { return ReadTypedObject(value, type); } [MethodImpl(MethodImplOptions.NoInlining)] internal object ReadTypedObject(object value, Type type) { TypeModel model = Model; if (model == null) { ThrowInvalidOperationException("Cannot deserialize sub-objects unless a model is provided"); } if (DynamicStub.TryDeserialize(ObjectScope.WrappedMessage, type, model, ref this, ref value)) { return value; } SubItemToken token = StartSubItem(); if ((object)type == null || !model.TryDeserializeAuxiliaryType(ref this, DataFormat.Default, 1, type, ref value, skipOtherFields: true, asListItem: false, autoCreate: true, insideList: false, null, isRoot: false)) { TypeModel.ThrowUnexpectedType(type, Model); } EndSubItem(token); return value; } internal void SkipAllFields() { while (ReadFieldHeader() > 0) { SkipField(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString(StringMap map = null) { if (_reader.WireType == WireType.String) { int num = (int)ReadUInt32Varint(Read32VarintMode.Unsigned); if (num == 0) { return ""; } if (num < 0) { ThrowInvalidLength(num); } string text = _reader.ImplReadString(ref this, num); if (_reader.InternStrings) { text = _reader.Intern(text); } return text; } ThrowWireTypeException(); return null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private uint ReadUInt32Varint(Read32VarintMode mode) { uint value; int num = _reader.ImplTryReadUInt32VarintWithoutMoving(ref this, mode, out value); if (num <= 0) { if (mode == Read32VarintMode.FieldHeader) { return 0u; } ThrowEoF(); } _reader.ImplSkipBytes(ref this, num); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ulong ReadUInt64Varint() { ulong value; int num = _reader.ImplTryReadUInt64VarintWithoutMoving(ref this, out value); if (num <= 0) { ThrowEoF(); } _reader.ImplSkipBytes(ref this, num); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Assert(WireType wireType) { WireType wireType2 = _reader.WireType; if (wireType2 != wireType) { if ((wireType & (WireType)7) == wireType2) { _reader.WireType = wireType; } else { ThrowWireTypeException(); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SkipField() { switch (_reader.WireType) { case WireType.Fixed32: _reader.ImplSkipBytes(ref this, 4L); break; case WireType.Fixed64: _reader.ImplSkipBytes(ref this, 8L); break; case WireType.String: { long num = (long)ReadUInt64Varint(); if (num < 0) { ThrowInvalidLength(num); } _reader.ImplSkipBytes(ref this, num); break; } case WireType.Variant: case WireType.SignedVariant: ReadUInt64Varint(); break; case WireType.StartGroup: SkipGroup(); break; default: ThrowWireTypeException(); break; } } internal readonly Type DeserializeType(string typeName) { return _reader.DeserializeType(typeName); } [MethodImpl(MethodImplOptions.NoInlining)] private void SkipGroup() { int fieldNumber = _reader._fieldNumber; if (_reader.IncrDepth()) { ThrowTooDeep(); } while (ReadFieldHeader() > 0) { SkipField(); } _reader.DecrDepth(); if (_reader.WireType == WireType.EndGroup && _reader._fieldNumber == fieldNumber) { _reader.WireType = WireType.None; } else { ThrowWireTypeException(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadFieldHeader() { if (_reader.blockEnd64 <= _reader._longPosition || _reader.WireType == WireType.EndGroup) { return 0; } if (RemainingInCurrent >= 5) { uint value; int num = ReadVarintUInt32(out value); _reader.Advance(num); return _reader.SetTag(value); } return ReadFieldHeaderFallback(); } [MethodImpl(MethodImplOptions.NoInlining)] private int ReadFieldHeaderFallback() { uint value; int num = _reader.ImplTryReadUInt32VarintWithoutMoving(ref this, Read32VarintMode.FieldHeader, out value); if (num == 0) { _reader.WireType = WireType.Variant; return _reader._fieldNumber = 0; } _reader.ImplSkipBytes(ref this, num); return _reader.SetTag(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryReadFieldHeader(int field) { ProtoReader reader = _reader; if (reader.blockEnd64 <= reader._longPosition || reader.WireType == WireType.EndGroup) { return false; } uint value; int num = reader.ImplTryReadUInt32VarintWithoutMoving(ref this, Read32VarintMode.FieldHeader, out value); WireType wireType; if (num > 0 && (int)value >> 3 == field && (wireType = (WireType)(value & 7)) != WireType.EndGroup) { reader.WireType = wireType; reader._fieldNumber = field; reader.ImplSkipBytes(ref this, num); return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void CheckFullyConsumed() { if (!_reader.IsFullyConsumed(ref this)) { ThrowProtoException("Incorrect number of bytes consumed"); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly void Hint(WireType wireType) { _reader.Hint(wireType); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowWireTypeException() { string message = ((_reader == null) ? "(no reader)" : $"Invalid wire-type ({_reader.WireType}); this usually means you have over-written a file without truncating or setting the length; see https://stackoverflow.com/q/2152978/23354"); ThrowProtoException(message); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowProtoException(string message) { throw AddErrorData(new ProtoException(message), _reader, ref this); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowEoF() { throw AddErrorData(new EndOfStreamException(), _reader, ref this); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowTooDeep() { ThrowInvalidOperationException("Maximum model depth exceeded (see TypeModel.MaxDepth): " + _reader._depth); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowInvalidOperationException(string message = null) { InvalidOperationException exception = (string.IsNullOrWhiteSpace(message) ? new InvalidOperationException() : new InvalidOperationException(message)); throw AddErrorData(exception, _reader, ref this); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowInvalidLength(long length) { ThrowInvalidOperationException("Invalid length: " + length); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowArgumentException(string message) { throw AddErrorData(new ArgumentException(message), _reader, ref this); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowOverflow() { throw AddErrorData(new OverflowException(), _reader, ref this); } internal static Exception AddErrorData(Exception exception, ProtoReader source, ref State state) { if (exception != null && source != null && !exception.Data.Contains("protoSource")) { exception.Data.Add("protoSource", $"tag={source.FieldNumber}; wire-type={source.WireType}; offset={state.GetPosition()}; depth={source._depth}"); } return exception; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Zag(uint ziggedValue) { return (int)(0 - (ziggedValue & 1)) ^ (((int)ziggedValue >> 1) & 0x7FFFFFFF); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static long Zag(ulong ziggedValue) { return (long)(0L - (ziggedValue & 1)) ^ (((long)ziggedValue >> 1) & 0x7FFFFFFFFFFFFFFFL); } [MethodImpl(MethodImplOptions.NoInlining)] public void ThrowEnumException(Type type, int value) { string text = (((object)type == null) ? "" : type.FullName); throw AddErrorData(new ProtoException("No " + text + " enum is mapped to the wire-value " + value), _reader, ref this); } [MethodImpl(MethodImplOptions.NoInlining)] public void AppendExtensionData(IExtensible instance) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } AppendExtensionDataImpl(instance.GetExtensionObject(createIfMissing: true)); } [MethodImpl(MethodImplOptions.NoInlining)] public void AppendExtensionData(ITypedExtensible instance, Type type) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } AppendExtensionDataImpl(instance.GetExtensionObject(type, createIfMissing: true)); } private void AppendExtensionDataImpl(IExtension extn) { bool commit = false; Stream stream = extn.BeginAppend(); try { ProtoWriter.State writeState = ProtoWriter.State.Create(stream, _reader._model); try { AppendExtensionField(ref writeState); writeState.Close(); } catch { writeState.Abandon(); throw; } finally { writeState.Dispose(); } commit = true; } finally { extn.EndAppend(stream, commit); } } [MethodImpl(MethodImplOptions.NoInlining)] private void AppendExtensionField(ref ProtoWriter.State writeState) { ProtoReader reader = _reader; writeState.WriteFieldHeader(reader._fieldNumber, reader.WireType); switch (reader.WireType) { case WireType.Fixed32: writeState.WriteInt32(ReadInt32()); break; case WireType.Variant: case WireType.Fixed64: case WireType.SignedVariant: writeState.WriteInt64(ReadInt64()); break; case WireType.String: writeState.WriteBytes(AppendBytes(null)); break; case WireType.StartGroup: { SubItemToken token = StartSubItem(); SubItemToken token2 = writeState.StartSubItem(null); while (ReadFieldHeader() > 0) { AppendExtensionField(ref writeState); } EndSubItem(token); writeState.EndSubItem(token2); break; } default: ThrowWireTypeException(); break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Type ReadType() { return TypeModel.DeserializeType(_reader._model, ReadString()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T ReadMessage<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value = default(T)) { return ReadMessage(SerializerFeatures.CategoryRepeated, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T ReadMessage<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(SerializerFeatures features, T value = default(T), ISerializer serializer = null) { ISerializer serializer2 = serializer ?? TypeModel.GetSerializer(Model); return ReadMessage(features, value, in serializer2); } [MethodImpl(MethodImplOptions.NoInlining)] internal T ReadMessage(SerializerFeatures features, T value, in TSerializer serializer) where TSerializer : ISerializer { SubItemToken token = StartSubItem(); T result = serializer.Read(ref this, value); EndSubItem(token); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T ReadAny<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value = default(T)) { return ReadAny(SerializerFeatures.CategoryRepeated, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T ReadAny<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(SerializerFeatures features, T value = default(T), ISerializer serializer = null) { if (serializer == null) { serializer = TypeModel.GetSerializer(Model); } SerializerFeatures features2 = serializer.Features; features.InheritFrom(features2); if (features.HasAny(SerializerFeatures.OptionWrappedValue | SerializerFeatures.OptionWrappedCollection)) { return ReadWrapped(features, value, serializer); } switch (features2.GetCategory()) { case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: return ReadMessage(features, value, serializer); case SerializerFeatures.CategoryRepeated: return ((IRepeatedSerializer)serializer).ReadRepeated(ref this, features, value); case SerializerFeatures.CategoryScalar: features.HintIfNeeded(ref this); return serializer.Read(ref this, value); default: features.ThrowInvalidCategory(); return default(T); } } public T ReadWrapped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(SerializerFeatures features, T value, ISerializer serializer = null) { if (serializer == null) { serializer = TypeModel.GetSerializer(Model); } features.InheritFrom(serializer.Features); ProtoWriter.State.AssertWrappedAndGetWireType(ref features, out var fieldPresence); SubItemToken token = StartSubItem(); int num; while ((num = ReadFieldHeader()) > 0) { if (num == 1) { value = ReadAny(features, value, serializer); } else { SkipField(); } } EndSubItem(token); if (!fieldPresence && TypeHelper.CanBeNull && TypeHelper.ValueChecker.IsNull(value)) { value = TypeHelper.NonTrivialDefault; } return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ISerializer GetSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return TypeModel.GetSerializer(Model); } [MethodImpl(MethodImplOptions.NoInlining)] public T ReadBaseType<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TBaseType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value = null, ISubTypeSerializer serializer = null) where TBaseType : class where T : class, TBaseType { return (T)(serializer ?? TypeModel.GetSubTypeSerializer(_reader._model)).ReadSubType(ref this, SubTypeState.Create(_reader, value)); } [MethodImpl(MethodImplOptions.NoInlining)] public T DeserializeRoot<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value = default(T), ISerializer serializer = null) { value = ReadAsRoot(value, serializer ?? TypeModel.GetSerializer(Model)); CheckFullyConsumed(); return value; } internal T ReadAsRoot<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value, ISerializer serializer) { SerializerFeatures features = serializer.Features; switch (features.GetCategory()) { case SerializerFeatures.CategoryMessageWrappedAtRoot: return ReadFieldOne(ref this, features, value, serializer); case SerializerFeatures.CategoryMessage: return serializer.Read(ref this, value); case SerializerFeatures.CategoryRepeated: case SerializerFeatures.CategoryScalar: return ReadFieldOne(ref this, features, value, serializer); default: features.ThrowInvalidCategory(); return default(T); } static T ReadFieldOne(ref State state, SerializerFeatures features2, T val, ISerializer serializer2) { bool flag = false; int num; while ((num = state.ReadFieldHeader()) > 0) { if (num == 1) { flag = true; val = state.ReadAny(features2, val, serializer2); } else { state.SkipField(); } } if (TypeHelper.IsReferenceType && !flag && val == null) { val = state.CreateInstance(serializer2); } return val; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool HasSubValue(WireType wireType) { return ProtoReader.HasSubValue(wireType, _reader); } [MethodImpl(MethodImplOptions.NoInlining)] public T CreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(ISerializer serializer = null) { return TypeModel.CreateInstance(Context, serializer); } [MethodImpl(MethodImplOptions.NoInlining)] internal object DeserializeRootFallbackWithModel(object value, Type type, TypeModel overrideModel) { TypeModel model = Model; try { Model = overrideModel; return DeserializeRootFallback(value, type); } finally { Model = model; } } [MethodImpl(MethodImplOptions.NoInlining)] internal object DeserializeRootFallback(object value, Type type) { bool autoCreate = TypeModel.PrepareDeserialize(value, ref type); object result = Model.DeserializeRootAny(ref this, type, value, autoCreate); CheckFullyConsumed(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal T DeserializeRootImpl(T value = default(T)) { ISerializer serializer = TypeModel.TryGetSerializer(Model); if (serializer == null) { return (T)DeserializeRootFallback(value, typeof(T)); } return DeserializeRoot(value, serializer); } public static State Create(Stream source, TypeModel model, object userState = null, long length = -1L) { ProtoReader reader = ProtoReader.Create(source, model, userState, length); return new State(reader); } } private sealed class ReadOnlySequenceProtoReader : ProtoReader { private ReadOnlySequence.Enumerator _source; protected internal override State DefaultState() { ThrowHelper.ThrowInvalidOperationException("You must retain and pass the state from ProtoReader.Create"); return default(State); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string ToString(ReadOnlySpan span, int offset, int bytes) { return UTF8.GetString(span.Slice(offset, bytes)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string ToString(ReadOnlySpan span) { return UTF8.GetString(span); } internal static int TryParseUInt32Varint(ref State state, int offset, bool trimNegative, out uint value, ReadOnlySpan span) { if ((uint)offset >= (uint)span.Length) { value = 0u; return 0; } value = span[offset++]; if ((value & 0x80) == 0) { return 1; } value &= 127u; if ((uint)offset >= (uint)span.Length) { state.ThrowEoF(); } uint num = span[offset++]; value |= (num & 0x7F) << 7; if ((num & 0x80) == 0) { return 2; } if ((uint)offset >= (uint)span.Length) { state.ThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0) { return 3; } if ((uint)offset >= (uint)span.Length) { state.ThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0) { return 4; } if ((uint)offset >= (uint)span.Length) { state.ThrowEoF(); } num = span[offset++]; value |= num << 28; if ((num & 0xF0) == 0) { return 5; } if (trimNegative && (num & 0xF0) == 240 && offset + 4 < (uint)span.Length && span[offset] == byte.MaxValue && span[offset + 1] == byte.MaxValue && span[offset + 2] == byte.MaxValue && span[offset + 3] == byte.MaxValue && span[offset + 4] == 1) { return 10; } state.ThrowOverflow(); return 0; } public override void Dispose() { base.Dispose(); _source = default(ReadOnlySequence.Enumerator); Pool.Put(this); } internal void Init(ReadOnlySequence source, TypeModel model, object userState) { Init(model, userState); _source = source.GetEnumerator(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private int GetSomeData(ref State state, bool throwIfEOF = true) { int remainingInCurrent = state.RemainingInCurrent; if (remainingInCurrent != 0) { return remainingInCurrent; } return ReadNextBuffer(ref state, throwIfEOF); } [MethodImpl(MethodImplOptions.NoInlining)] private int ReadNextBuffer(ref State state, bool throwIfEOF) { do { if (!_source.MoveNext()) { if (throwIfEOF) { state.ThrowEoF(); } return 0; } state.Init(_source.Current); } while (state.Span.IsEmpty); return state.Span.Length; } private protected override int ImplTryReadUInt64VarintWithoutMoving(ref State state, out ulong value) { if (state.RemainingInCurrent < 10) { return ViaStackAlloc(this, ref state, out value); } return State.TryParseUInt64Varint(state.Span, state.OffsetInCurrent, out value); static int ViaStackAlloc(ReadOnlySequenceProtoReader reader, ref State s, out ulong val) { Span span = stackalloc byte[10]; Span destination = span; int num = 0; if (s.RemainingInCurrent != 0) { int num2 = Math.Min(s.RemainingInCurrent, destination.Length); Peek(ref s, num2).CopyTo(destination); destination = destination.Slice(num2); num += num2; } ReadOnlySequence.Enumerator source = reader._source; while (!destination.IsEmpty && source.MoveNext()) { ReadOnlySpan span2 = source.Current.Span; int num3 = Math.Min(span2.Length, destination.Length); span2.Slice(0, num3).CopyTo(destination); destination = destination.Slice(num3); num += num3; } if (num != 10) { span = span.Slice(0, num); } return State.TryParseUInt64Varint(span, 0, out val); } } private protected override uint ImplReadUInt32Fixed(ref State state) { if (state.RemainingInCurrent < 4) { return ViaStackAlloc(ref state); } return BinaryPrimitives.ReadUInt32LittleEndian(Consume(ref state, 4)); uint ViaStackAlloc(ref State st) { Span span = stackalloc byte[4]; Span destination = span; while (!destination.IsEmpty) { int num = Math.Min(GetSomeData(ref st), destination.Length); Consume(ref st, num).CopyTo(destination); destination = destination.Slice(num); } return BinaryPrimitives.ReadUInt32LittleEndian(span); } } private protected override ulong ImplReadUInt64Fixed(ref State state) { if (state.RemainingInCurrent < 8) { return ViaStackAlloc(ref state); } return BinaryPrimitives.ReadUInt64LittleEndian(Consume(ref state, 8)); ulong ViaStackAlloc(ref State st) { Span span = stackalloc byte[8]; Span destination = span; while (!destination.IsEmpty) { int num = Math.Min(GetSomeData(ref st), destination.Length); Consume(ref st, num).CopyTo(destination); destination = destination.Slice(num); } return BinaryPrimitives.ReadUInt64LittleEndian(span); } } private protected override string ImplReadString(ref State state, int bytes) { if (state.RemainingInCurrent < bytes) { return ImplReadStringMultiSegment(ref state, bytes); } int offset; return ToString(Consume(ref state, bytes, out offset), offset, bytes); } private string ImplReadStringMultiSegment(ref State state, int bytes) { byte[] buffer = BufferPool.GetBuffer(bytes); try { Span span = new Span(buffer, 0, bytes); ImplReadBytes(ref state, span, bytes); return ToString(span); } finally { BufferPool.ReleaseBufferToPool(ref buffer); } } private void ImplReadBytes(ref State state, Span target, int bytesToRead) { if (state.RemainingInCurrent >= bytesToRead) { Consume(ref state, bytesToRead).CopyTo(target); } else { Looped(ref state, target); } void Looped(ref State st, Span ttarget) { int num; for (int i = 0; i < bytesToRead; i += num) { num = Math.Min(GetSomeData(ref st), bytesToRead - i); Consume(ref st, num).CopyTo(ttarget); ttarget = ttarget.Slice(num); } } } private protected override void ImplReadBytes(ref State state, Span target) { ImplReadBytes(ref state, target, target.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ReadOnlySpan Consume(ref State state, int bytes) { Advance(bytes); return state.Consume(bytes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ReadOnlySpan Consume(ref State state, int bytes, out int offset) { Advance(bytes); return state.Consume(bytes, out offset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReadOnlySpan Peek(ref State state, int bytes) { return state.Span.Slice(state.OffsetInCurrent, bytes); } private protected override int ImplTryReadUInt32VarintWithoutMoving(ref State state, Read32VarintMode mode, out uint value) { if (state.RemainingInCurrent < 10) { return ViaStackAlloc(ref state, mode, out value); } return TryParseUInt32Varint(ref state, state.OffsetInCurrent, mode == Read32VarintMode.Signed, out value, state.Span); unsafe int ViaStackAlloc(ref State s, Read32VarintMode m, out uint val) { byte* pointer = stackalloc byte[10]; Span span = new Span(pointer, 10); Span destination = span; ReadOnlySpan readOnlySpan = Peek(ref s, Math.Min(destination.Length, s.RemainingInCurrent)); readOnlySpan.CopyTo(destination); int num = readOnlySpan.Length; destination = destination.Slice(num); ReadOnlySequence.Enumerator source = _source; while (!destination.IsEmpty && source.MoveNext()) { ReadOnlySpan span2 = source.Current.Span; int num2 = Math.Min(span2.Length, destination.Length); span2.Slice(0, num2).CopyTo(destination); destination = destination.Slice(num2); num += num2; } if (num != 10) { span = span.Slice(0, num); } return TryParseUInt32Varint(ref s, 0, m == Read32VarintMode.Signed, out val, span); } } private protected override void ImplSkipBytes(ref State state, long count) { if (state.RemainingInCurrent >= count) { Skip(ref state, (int)count); } else { Looped(ref state, count); } void Looped(ref State st, long ccount) { while (ccount != 0L) { int num = (int)Math.Min(GetSomeData(ref st), ccount); Skip(ref st, num); ccount -= num; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Skip(ref State state, int bytes) { state.Skip(bytes); Advance(bytes); } private protected override bool IsFullyConsumed(ref State state) { return GetSomeData(ref state, throwIfEOF: false) == 0; } } [StructLayout(LayoutKind.Auto)] internal readonly struct SolidState : IDisposable { private readonly ReadOnlyMemory _memory; private readonly ProtoReader _reader; public void Dispose() { _reader?.Dispose(); } internal SolidState(ProtoReader reader, ReadOnlyMemory memory) { _memory = memory; _reader = reader; } internal State Liquify() { return new State(_reader, _memory); } } private sealed class StreamProtoReader : ProtoReader { private Stream _source; private byte[] _ioBuffer; private bool _isFixedLength; private int _ioIndex; private int _available; private long _dataRemaining64; protected internal override State DefaultState() { return new State(this); } [Obsolete("Please use ProtoReader.Create; this API may be removed in a future version", false)] public StreamProtoReader(Stream source, TypeModel model, SerializationContext context, int length) { Init(source, model, context, length); } [Obsolete("Please use ProtoReader.Create; this API may be removed in a future version", false)] public StreamProtoReader(Stream source, TypeModel model, SerializationContext context, long length) { Init(source, model, context, length); } internal StreamProtoReader() { } [Obsolete("Please use ProtoReader.Create; this API may be removed in a future version", false)] public StreamProtoReader(Stream source, TypeModel model, SerializationContext context) { Init(source, model, context, -1L); } internal void Init(Stream source, TypeModel model, object userState, long length) { Init(model, userState); if (source == null) { ThrowHelper.ThrowArgumentNullException("source"); } if (!source.CanRead) { ThrowHelper.ThrowArgumentException("Cannot read from stream", "source"); } if (TryConsumeSegmentRespectingPosition(source, out var data, length)) { _ioBuffer = data.Array; length = (_available = data.Count); _ioIndex = data.Offset; } else { _source = source; _ioBuffer = BufferPool.GetBuffer(); _available = (_ioIndex = 0); _dataRemaining64 = ((_isFixedLength = length >= 0) ? length : 0); } } public override void Dispose() { base.Dispose(); if (_source != null) { _source = null; BufferPool.ReleaseBufferToPool(ref _ioBuffer); } else { _ioBuffer = null; } Pool.Put(this); } private protected override int ImplTryReadUInt32VarintWithoutMoving(ref State state, Read32VarintMode mode, out uint value) { if (_available < 10) { Ensure(ref state, 10, strict: false); } if (_available == 0) { value = 0u; return 0; } int ioIndex = _ioIndex; value = _ioBuffer[ioIndex++]; if ((value & 0x80) == 0) { return 1; } value &= 127u; if (_available == 1) { state.ThrowEoF(); } uint num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 7; if ((num & 0x80) == 0) { return 2; } if (_available == 2) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0) { return 3; } if (_available == 3) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0) { return 4; } if (_available == 4) { state.ThrowEoF(); } num = _ioBuffer[ioIndex]; value |= num << 28; if ((num & 0xF0) == 0) { return 5; } if (mode == Read32VarintMode.Signed && (num & 0xF0) == 240 && _available >= 10 && _ioBuffer[++ioIndex] == byte.MaxValue && _ioBuffer[++ioIndex] == byte.MaxValue && _ioBuffer[++ioIndex] == byte.MaxValue && _ioBuffer[++ioIndex] == byte.MaxValue && _ioBuffer[++ioIndex] == 1) { return 10; } state.ThrowOverflow(); return 0; } private protected override ulong ImplReadUInt64Fixed(ref State state) { if (_available < 8) { Ensure(ref state, 8, strict: true); } Advance(8L); _available -= 8; ulong result = BinaryPrimitives.ReadUInt64LittleEndian(_ioBuffer.AsSpan(_ioIndex, 8)); _ioIndex += 8; return result; } private protected override void ImplReadBytes(ref State state, Span target) { int num = target.Length; Advance(num); while (num > _available) { if (_available > 0) { new Span(_ioBuffer, _ioIndex, _available).CopyTo(target); num -= _available; target = target.Slice(_available); _ioIndex = (_available = 0); } int num2 = ((num > _ioBuffer.Length) ? _ioBuffer.Length : num); if (num2 > 0) { Ensure(ref state, num2, strict: true); } } if (num > 0) { new Span(_ioBuffer, _ioIndex, num).CopyTo(target); _available -= num; _ioIndex += num; } } private protected override int ImplTryReadUInt64VarintWithoutMoving(ref State state, out ulong value) { if (_available < 10) { Ensure(ref state, 10, strict: false); } if (_available == 0) { value = 0uL; return 0; } int ioIndex = _ioIndex; value = _ioBuffer[ioIndex++]; if ((value & 0x80) == 0L) { return 1; } value &= 127uL; if (_available == 1) { state.ThrowEoF(); } ulong num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 7; if ((num & 0x80) == 0L) { return 2; } if (_available == 2) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0L) { return 3; } if (_available == 3) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0L) { return 4; } if (_available == 4) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 28; if ((num & 0x80) == 0L) { return 5; } if (_available == 5) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 35; if ((num & 0x80) == 0L) { return 6; } if (_available == 6) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 42; if ((num & 0x80) == 0L) { return 7; } if (_available == 7) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 49; if ((num & 0x80) == 0L) { return 8; } if (_available == 8) { state.ThrowEoF(); } num = _ioBuffer[ioIndex++]; value |= (num & 0x7F) << 56; if ((num & 0x80) == 0L) { return 9; } if (_available == 9) { state.ThrowEoF(); } num = _ioBuffer[ioIndex]; value |= num << 63; if ((num & 0xFFFFFFFFFFFFFFFEuL) != 0L) { state.ThrowOverflow(); } return 10; } private protected override string ImplReadString(ref State state, int bytes) { if (_available < bytes) { Ensure(ref state, bytes, strict: true); } string result = UTF8.GetString(_ioBuffer, _ioIndex, bytes); _available -= bytes; Advance(bytes); _ioIndex += bytes; return result; } private protected override bool IsFullyConsumed(ref State state) { return (_isFixedLength ? _dataRemaining64 : _available) == 0; } private protected override uint ImplReadUInt32Fixed(ref State state) { if (_available < 4) { Ensure(ref state, 4, strict: true); } Advance(4L); _available -= 4; uint result = BinaryPrimitives.ReadUInt32LittleEndian(_ioBuffer.AsSpan(_ioIndex, 4)); _ioIndex += 4; return result; } private void Ensure(ref State state, int count, bool strict) { if (_source != null) { if (count > _ioBuffer.Length) { BufferPool.ResizeAndFlushLeft(ref _ioBuffer, count, _ioIndex, _available); _ioIndex = 0; } else if (_ioIndex + count >= _ioBuffer.Length) { Buffer.BlockCopy(_ioBuffer, _ioIndex, _ioBuffer, 0, _available); _ioIndex = 0; } count -= _available; int num = _ioIndex + _available; int num2 = _ioBuffer.Length - num; if (_isFixedLength && _dataRemaining64 < num2) { num2 = (int)_dataRemaining64; } int num3; while (count > 0 && num2 > 0 && (num3 = _source.Read(_ioBuffer, num, num2)) > 0) { _available += num3; count -= num3; num2 -= num3; num += num3; if (_isFixedLength) { _dataRemaining64 -= num3; } } } if (strict && count > 0) { state.ThrowEoF(); } } private protected override void ImplSkipBytes(ref State state, long count) { if (_available < count && count < 128) { Ensure(ref state, (int)count, strict: true); } if (count <= _available) { _available -= (int)count; _ioIndex += (int)count; Advance(count); return; } Advance(count); count -= _available; _ioIndex = (_available = 0); if (_isFixedLength) { if (count > _dataRemaining64) { state.ThrowEoF(); } _dataRemaining64 -= count; } if (_source == null) { state.ThrowEoF(); } Seek(_source, count, _ioBuffer); } } internal const string PreferStateAPI = "If possible, please use the State API; a transitionary implementation is provided, but this API may be removed in a future version"; internal const string PreferReadMessage = "If possible, please use the ReadMessage API; this API may not work correctly with all readers"; private TypeModel _model; private int _fieldNumber; private int _depth; private long blockEnd64; private readonly NetObjectCache netCache = new NetObjectCache(); internal const long TO_EOF = -1L; private long _longPosition; private Dictionary stringInterner; private protected static readonly UTF8Encoding UTF8 = new UTF8Encoding(); internal static readonly byte[] EmptyBlob = Array.Empty(); internal const MethodImplOptions HotPath = MethodImplOptions.AggressiveInlining; private static readonly FieldInfo s_origin = typeof(MemoryStream).GetField("_origin", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo s_buffer = typeof(MemoryStream).GetField("_buffer", BindingFlags.Instance | BindingFlags.NonPublic); public int FieldNumber { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _fieldNumber; } } public WireType WireType { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; private protected set; } public bool InternStrings { get; set; } public object UserState { get; private set; } [Obsolete("Prefer UserState")] public SerializationContext Context => SerializationContext.AsSerializationContext(this); public int Position { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return checked((int)_longPosition); } } public long LongPosition { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _longPosition; } } public TypeModel Model { get { return _model; } internal set { _model = value; } } private protected abstract int ImplTryReadUInt64VarintWithoutMoving(ref State state, out ulong value); private protected abstract uint ImplReadUInt32Fixed(ref State state); private protected abstract ulong ImplReadUInt64Fixed(ref State state); private protected abstract string ImplReadString(ref State state, int bytes); private protected abstract void ImplSkipBytes(ref State state, long count); private protected abstract int ImplTryReadUInt32VarintWithoutMoving(ref State state, Read32VarintMode mode, out uint value); private protected abstract void ImplReadBytes(ref State state, Span target); private protected virtual void ImplReadBytes(ref State state, ReadOnlySequence target) { Memory memory; if (target.IsSingleSegment) { memory = MemoryMarshal.AsMemory(target.First); ImplReadBytes(ref state, memory.Span); return; } ReadOnlySequence.Enumerator enumerator = target.GetEnumerator(); while (enumerator.MoveNext()) { ReadOnlyMemory current = enumerator.Current; memory = MemoryMarshal.AsMemory(current); ImplReadBytes(ref state, memory.Span); } } private protected abstract bool IsFullyConsumed(ref State state); [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool IncrDepth() { return ++_depth >= ((_model == null) ? 512 : _model.MaxDepth); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void DecrDepth() { _depth--; } private protected ProtoReader() { } internal void Init(TypeModel model, object userState) { _model = model; if (userState is SerializationContext serializationContext) { serializationContext.Freeze(); } UserState = userState; _longPosition = 0L; _depth = (_fieldNumber = 0); blockEnd64 = long.MaxValue; InternStrings = model.HasOption(TypeModel.TypeModelOptions.InternStrings); WireType = WireType.None; } public virtual void Dispose() { _model = null; if (stringInterner != null) { stringInterner.Clear(); stringInterner = null; } netCache.Clear(); UserState = null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Advance(long count) { _longPosition += count; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public short ReadInt16() { return DefaultState().ReadInt16(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ushort ReadUInt16() { return DefaultState().ReadUInt16(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte ReadByte() { return DefaultState().ReadByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public sbyte ReadSByte() { return DefaultState().ReadSByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadUInt32() { return DefaultState().ReadUInt32(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadInt32() { return DefaultState().ReadInt32(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadInt64() { return DefaultState().ReadInt64(); } private protected string Intern(string value) { if (value == null) { return null; } if (value.Length == 0) { return ""; } string value2; if (stringInterner == null) { stringInterner = new Dictionary(StringComparer.Ordinal) { { value, value } }; } else if (stringInterner.TryGetValue(value, out value2)) { value = value2; } else { stringInterner.Add(value, value); } return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString() { return DefaultState().ReadString(); } [MethodImpl(MethodImplOptions.NoInlining)] public void ThrowEnumException(Type type, int value) { DefaultState().ThrowEnumException(type, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public double ReadDouble() { return DefaultState().ReadDouble(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static object ReadObject(object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, ProtoReader reader) { return reader.DefaultState().ReadObject(value, type); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void EndSubItem(SubItemToken token, ProtoReader reader) { reader.DefaultState().EndSubItem(token); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SubItemToken StartSubItem(ProtoReader reader) { return reader.DefaultState().StartSubItem(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadFieldHeader() { return DefaultState().ReadFieldHeader(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private int SetTag(uint tag) { if ((_fieldNumber = (int)(tag >> 3)) < 1) { ThrowInvalidField(_fieldNumber); } WireType wireType = (WireType = (WireType)(tag & 7)); if (wireType == WireType.EndGroup) { if (_depth > 0) { return 0; } ThrowUnexpectedEndGroup(); } return _fieldNumber; } private static void ThrowInvalidField(int fieldNumber) { ThrowHelper.ThrowProtoException("Invalid field in source data: " + fieldNumber); } private static void ThrowUnexpectedEndGroup() { ThrowHelper.ThrowProtoException("Unexpected end-group in source data; this usually means the source data is corrupt"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryReadFieldHeader(int field) { return DefaultState().TryReadFieldHeader(field); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Hint(WireType wireType) { if (WireType != wireType && (wireType & (WireType)7) == WireType) { WireType = wireType; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Assert(WireType wireType) { DefaultState().Assert(wireType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SkipField() { DefaultState().SkipField(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadUInt64() { return DefaultState().ReadUInt64(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float ReadSingle() { return DefaultState().ReadSingle(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ReadBoolean() { return DefaultState().ReadBoolean(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] AppendBytes(byte[] value, ProtoReader reader) { return reader.DefaultState().AppendBytes(value); } private static int ReadByteOrThrow(Stream source) { int num = source.ReadByte(); if (num < 0) { ThrowEoF(); } return num; } public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber) { int bytesRead; return ReadLengthPrefix(source, expectHeader, style, out fieldNumber, out bytesRead); } public static int DirectReadLittleEndianInt32(Stream source) { return ReadByteOrThrow(source) | (ReadByteOrThrow(source) << 8) | (ReadByteOrThrow(source) << 16) | (ReadByteOrThrow(source) << 24); } public static int DirectReadBigEndianInt32(Stream source) { return (ReadByteOrThrow(source) << 24) | (ReadByteOrThrow(source) << 16) | (ReadByteOrThrow(source) << 8) | ReadByteOrThrow(source); } public static int DirectReadVarintInt32(Stream source) { ulong value; int num = TryReadUInt64Varint(source, out value); if (num <= 0) { ThrowEoF(); } return checked((int)value); } public static void DirectReadBytes(Stream source, byte[] buffer, int offset, int count) { if (source == null) { ThrowHelper.ThrowArgumentNullException("source"); } int num; while (count > 0 && (num = source.Read(buffer, offset, count)) > 0) { count -= num; offset += num; } if (count > 0) { ThrowEoF(); } } public static byte[] DirectReadBytes(Stream source, int count) { byte[] array = new byte[count]; DirectReadBytes(source, array, 0, count); return array; } public static string DirectReadString(Stream source, int length) { byte[] array = new byte[length]; DirectReadBytes(source, array, 0, length); return ProtoWriter.UTF8.GetString(array, 0, length); } public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber, out int bytesRead) { if (style == PrefixStyle.None) { bytesRead = (fieldNumber = 0); return int.MaxValue; } long num = ReadLongLengthPrefix(source, expectHeader, style, out fieldNumber, out bytesRead); return checked((int)num); } public static long ReadLongLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber, out int bytesRead) { fieldNumber = 0; switch (style) { case PrefixStyle.None: bytesRead = 0; return long.MaxValue; case PrefixStyle.Base128: { bytesRead = 0; ulong value; int num2; if (expectHeader) { num2 = TryReadUInt64Varint(source, out value); bytesRead += num2; if (num2 > 0) { if ((value & 7) != 2) { ThrowHelper.ThrowInvalidOperationException($"Unexpected wire-type: {(WireType)(value & 7)}, expected {WireType.String})"); } fieldNumber = (int)(value >> 3); num2 = TryReadUInt64Varint(source, out value); bytesRead += num2; if (bytesRead == 0) { ThrowEoF(); } return (long)value; } bytesRead = 0; return -1L; } num2 = TryReadUInt64Varint(source, out value); bytesRead += num2; if (bytesRead >= 0) { return (long)value; } return -1L; } case PrefixStyle.Fixed32: { int num3 = source.ReadByte(); if (num3 < 0) { bytesRead = 0; return -1L; } bytesRead = 4; return num3 | (ReadByteOrThrow(source) << 8) | (ReadByteOrThrow(source) << 16) | (ReadByteOrThrow(source) << 24); } case PrefixStyle.Fixed32BigEndian: { int num = source.ReadByte(); if (num < 0) { bytesRead = 0; return -1L; } bytesRead = 4; return (num << 24) | (ReadByteOrThrow(source) << 16) | (ReadByteOrThrow(source) << 8) | ReadByteOrThrow(source); } default: ThrowHelper.ThrowArgumentOutOfRangeException("style"); bytesRead = 0; return 0L; } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowEoF() { default(State).ThrowEoF(); } private static int TryReadUInt64Varint(Stream source, out ulong value) { value = 0uL; int num = source.ReadByte(); if (num < 0) { return 0; } value = (uint)num; if ((value & 0x80) == 0L) { return 1; } value &= 127uL; int num2 = 1; int num3 = 7; while (num2 < 9) { num = source.ReadByte(); if (num < 0) { ThrowEoF(); } value |= ((ulong)num & 0x7FuL) << num3; num3 += 7; num2++; if ((num & 0x80) == 0) { return num2; } } num = source.ReadByte(); if (num < 0) { ThrowEoF(); } if ((num & 1) == 0) { value |= ((ulong)num & 0x7FuL) << num3; return ++num2; } ThrowHelper.ThrowOverflowException(); return 0; } internal static void Seek(Stream source, long count, byte[] buffer) { if (source.CanSeek) { source.Seek(count, SeekOrigin.Current); count = 0L; } else if (buffer != null) { int num; while (count > buffer.Length && (num = source.Read(buffer, 0, buffer.Length)) > 0) { count -= num; } while (count > 0 && (num = source.Read(buffer, 0, (int)count)) > 0) { count -= num; } } else { buffer = BufferPool.GetBuffer(); try { int num2; while (count > buffer.Length && (num2 = source.Read(buffer, 0, buffer.Length)) > 0) { count -= num2; } while (count > 0 && (num2 = source.Read(buffer, 0, (int)count)) > 0) { count -= num2; } } finally { BufferPool.ReleaseBufferToPool(ref buffer); } } if (count > 0) { ThrowEoF(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendExtensionData(IExtensible instance) { DefaultState().AppendExtensionData(instance); } public static bool HasSubValue(WireType wireType, ProtoReader source) { if (source == null) { ThrowHelper.ThrowArgumentNullException("source"); } if (source.blockEnd64 <= source._longPosition || wireType == WireType.EndGroup) { return false; } source.WireType = wireType; return true; } internal Type DeserializeType(string value) { return TypeModel.DeserializeType(_model, value); } public Type ReadType() { return DefaultState().ReadType(); } public static object Merge(ProtoReader parent, object from, object to) { if (parent == null) { ThrowHelper.ThrowArgumentNullException("parent"); } TypeModel model = parent.Model; object userState = parent.UserState; if (model == null) { ThrowHelper.ThrowInvalidOperationException("Types cannot be merged unless a type-model has been specified"); } using MemoryStream memoryStream = new MemoryStream(); ProtoWriter.State state = ProtoWriter.State.Create(memoryStream, model, userState); try { model.SerializeRootFallback(ref state, from); } finally { state.Dispose(); } memoryStream.Position = 0L; using State state2 = State.Create(memoryStream, model, userState, -1L); return state2.DeserializeRootFallback(to, null); } protected internal abstract State DefaultState(); [MethodImpl(MethodImplOptions.NoInlining)] private static void NoContextThrowEoF() { default(State).ThrowEoF(); } [MethodImpl(MethodImplOptions.NoInlining)] private static void NoContextThrowOverflow() { default(State).ThrowOverflow(); } [Obsolete("If possible, please use the State API; a transitionary implementation is provided, but this API may be removed in a future version", false)] public static ProtoReader Create(Stream source, TypeModel model, SerializationContext context = null, long length = -1L) { return Create(source, model, (object)context, length); } internal static ProtoReader Create(Stream source, TypeModel model, object userState, long length) { StreamProtoReader streamProtoReader = Pool.TryGet() ?? new StreamProtoReader(); streamProtoReader.Init(source, model ?? TypeModel.DefaultModel, userState, length); return streamProtoReader; } private static bool ReflectionTryGetBuffer(MemoryStream ms, out ArraySegment buffer) { if ((object)s_origin != null && (object)s_buffer != null && ms.GetType() == typeof(MemoryStream)) { try { int offset = (int)s_origin.GetValue(ms); byte[] array = (byte[])s_buffer.GetValue(ms); buffer = new ArraySegment(array, offset, checked((int)ms.Length)); return true; } catch { } } buffer = default(ArraySegment); return false; } internal static bool TryConsumeSegmentRespectingPosition(Stream source, out ArraySegment data, long length) { if (source is MemoryStream { CanSeek: not false } memoryStream && (memoryStream.TryGetBuffer(out var buffer) || ReflectionTryGetBuffer(memoryStream, out buffer))) { int num = checked((int)memoryStream.Position); int num2 = buffer.Count - num; int offset = buffer.Offset + num; if (length >= 0 && length < num2) { num2 = (int)length; } data = new ArraySegment(buffer.Array, offset, num2); memoryStream.Seek(num2, SeekOrigin.Current); return true; } data = default(ArraySegment); return false; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true, Inherited = false)] public sealed class ProtoReservedAttribute : Attribute { public int From { get; } public int To { get; } public string Name { get; } public string Comment { get; } public ProtoReservedAttribute(int field, string comment = null) : this(field, field, comment) { } public ProtoReservedAttribute(int from, int to, string comment = null) { From = from; To = to; Comment = comment; } public ProtoReservedAttribute(string field, string comment = null) { Name = field; Comment = comment; } internal void Verify() { if (string.IsNullOrWhiteSpace(Name)) { if (From <= 0) { throw new ArgumentOutOfRangeException("From", "Invalid reservation definition"); } if (To < From) { throw new ArgumentOutOfRangeException("To", "Invalid reservation definition"); } } } } public abstract class ProtoWriter : IDisposable, ISerializationContext { [StructLayout(LayoutKind.Auto)] public ref struct State { private Span _span; private Memory _memory; private ProtoWriter _writer; internal readonly bool IsActive => !_span.IsEmpty; internal readonly Span Remaining { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _span.Slice(OffsetInCurrent); } } internal int RemainingInCurrent { get; private set; } internal int OffsetInCurrent { get; private set; } internal readonly TypeModel Model => _writer?.Model; internal readonly WireType WireType { get { return _writer.WireType; } set { _writer.WireType = value; } } internal readonly int Depth => _writer.Depth; internal readonly int FieldNumber { get { return _writer.fieldNumber; } private set { _writer.fieldNumber = value; } } public readonly ISerializationContext Context => _writer; public static State Create(IBufferWriter writer, TypeModel model, object userState = null) { return BufferWriterProtoWriter.CreateBufferWriterProtoWriter(writer, model, userState); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal State(ProtoWriter writer) { this = default(State); _writer = writer; } internal void Init(Memory memory) { _memory = memory; _span = memory.Span; RemainingInCurrent = _span.Length; } public void Flush() { if (_writer.TryFlush(ref this)) { _writer._needFlush = false; } } internal int ConsiderWritten() { int offsetInCurrent = OffsetInCurrent; ProtoWriter writer = _writer; this = default(State); _writer = writer; return offsetInCurrent; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LocalWriteFixed32(uint value) { BinaryPrimitives.WriteUInt32LittleEndian(Remaining, value); OffsetInCurrent += 4; RemainingInCurrent -= 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal readonly void ReverseLast32() { _span.Slice(OffsetInCurrent - 4, 4).Reverse(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LocalAdvance(int bytes) { OffsetInCurrent += bytes; RemainingInCurrent -= bytes; } internal void LocalWriteBytes(ReadOnlySpan span) { span.CopyTo(Remaining); OffsetInCurrent += span.Length; RemainingInCurrent -= span.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void LocalWriteFixed64(ulong value) { BinaryPrimitives.WriteUInt64LittleEndian(Remaining, value); OffsetInCurrent += 8; RemainingInCurrent -= 8; } internal void LocalWriteString(string value) { int bytes = UTF8.GetBytes(value.AsSpan(), Remaining); OffsetInCurrent += bytes; RemainingInCurrent -= bytes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal int LocalWriteVarint64(ulong value) { int num = WriteVarint64(value, _span, OffsetInCurrent); OffsetInCurrent += num; RemainingInCurrent -= num; return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int WriteVarint64(ulong value, Span span, int offset = 0) { int num = 0; do { span[offset++] = (byte)((value & 0x7F) | 0x80); num++; } while ((value >>= 7) != 0L); span[offset - 1] &= 127; return num; } internal int ReadFrom(Stream source) { ArraySegment segment; int num = ((!MemoryMarshal.TryGetArray((ReadOnlyMemory)_memory, out segment)) ? source.Read(Remaining) : source.Read(segment.Array, segment.Offset + OffsetInCurrent, RemainingInCurrent)); if (num > 0) { OffsetInCurrent += num; RemainingInCurrent -= num; } return num; } internal int LocalWriteVarint32(uint value) { int num = 0; Span span = _span; int offsetInCurrent = OffsetInCurrent; do { span[offsetInCurrent++] = (byte)((value & 0x7F) | 0x80); num++; } while ((value >>= 7) != 0); span[offsetInCurrent - 1] &= 127; OffsetInCurrent += num; RemainingInCurrent -= num; return num; } public void WriteString(int fieldNumber, string value, StringMap map = null) { if (value != null) { WriteFieldHeader(fieldNumber, WireType.String); WriteStringWithLengthPrefix(value, map); } } private void WriteStringWithLengthPrefix(string value, StringMap map) { ProtoWriter writer = _writer; if (string.IsNullOrEmpty(value)) { writer.AdvanceAndReset(writer.ImplWriteVarint32(ref this, 0u)); return; } int byteCount = UTF8.GetByteCount(value); writer.AdvanceAndReset(writer.ImplWriteVarint32(ref this, (uint)byteCount) + byteCount); writer.ImplWriteString(ref this, value, byteCount); } public void WriteString(string value, StringMap map = null) { WireType wireType = _writer.WireType; if (wireType == WireType.String) { WriteStringWithLengthPrefix(value, map); } else { ThrowInvalidSerializationOperation(); } } public void WriteType(Type value) { WriteString(_writer.SerializeType(value)); } public void WriteFieldHeader(int fieldNumber, WireType wireType) { ProtoWriter writer = _writer; if (writer.WireType != WireType.None) { FailPendingField(writer, fieldNumber, wireType); } if (fieldNumber < 0) { ThrowHelper.ThrowArgumentOutOfRangeException("fieldNumber"); } writer._needFlush = true; if (writer.packedFieldNumber == 0) { writer.fieldNumber = fieldNumber; writer.WireType = wireType; WriteHeaderCore(fieldNumber, wireType); } else { WritePackedField(writer, fieldNumber, wireType); } static void FailPendingField(ProtoWriter protoWriter, int num, WireType wireType2) { ThrowHelper.ThrowInvalidOperationException($"Cannot write a {wireType2}/{num} header until the {protoWriter.WireType}/{protoWriter.fieldNumber} data has been written; writer: {protoWriter}"); } static void WritePackedField(ProtoWriter protoWriter, int num, WireType wireType2) { if (protoWriter.packedFieldNumber == num) { if ((uint)wireType2 > 1u && wireType2 != WireType.Fixed32 && wireType2 != WireType.SignedVariant) { ThrowHelper.ThrowInvalidOperationException("Wire-type cannot be encoded as packed: " + wireType2); } protoWriter.fieldNumber = num; protoWriter.WireType = wireType2; } else { ThrowHelper.ThrowInvalidOperationException("Field mismatch during packed encoding; expected " + protoWriter.packedFieldNumber + " but received " + num); } } } public void WriteInt32Varint(int fieldNumber, int value) { WriteFieldHeader(fieldNumber, WireType.Variant); WriteInt32VarintImpl(value); } private void WriteInt32VarintImpl(int value) { ProtoWriter writer = _writer; if (value >= 0) { writer.AdvanceAndReset(writer.ImplWriteVarint32(ref this, (uint)value)); } else { writer.AdvanceAndReset(writer.ImplWriteVarint64(ref this, (ulong)value)); } } public void WriteInt32(int value) { ProtoWriter writer = _writer; switch (writer.WireType) { case WireType.Fixed32: writer.ImplWriteFixed32(ref this, (uint)value); writer.AdvanceAndReset(4); break; case WireType.Fixed64: writer.ImplWriteFixed64(ref this, (ulong)value); writer.AdvanceAndReset(8); break; case WireType.Variant: WriteInt32VarintImpl(value); break; case WireType.SignedVariant: writer.AdvanceAndReset(writer.ImplWriteVarint32(ref this, Zig(value))); break; default: ThrowInvalidSerializationOperation(); break; } } public void WriteSByte(sbyte value) { WriteInt32(value); } public void WriteInt16(short value) { WriteInt32(value); } public void WriteUInt16(ushort value) { WriteUInt32(value); } public void WriteByte(byte value) { WriteUInt32(value); } public void WriteBoolean(bool value) { WriteUInt32(value ? 1u : 0u); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteIntPtr(IntPtr value) { WriteInt64(value.ToInt64()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteUIntPtr(UIntPtr value) { WriteUInt64(value.ToUInt64()); } public void WriteUInt32(uint value) { ProtoWriter writer = _writer; switch (writer.WireType) { case WireType.Fixed32: writer.ImplWriteFixed32(ref this, value); writer.AdvanceAndReset(4); break; case WireType.Fixed64: writer.ImplWriteFixed64(ref this, value); writer.AdvanceAndReset(8); break; case WireType.Variant: { int count = writer.ImplWriteVarint32(ref this, value); writer.AdvanceAndReset(count); break; } default: ThrowInvalidSerializationOperation(); break; } } public unsafe void WriteDouble(double value) { ProtoWriter writer = _writer; switch (writer.WireType) { case WireType.Fixed32: { float num = (float)value; if (float.IsInfinity(num) && !double.IsInfinity(value)) { ThrowHelper.ThrowOverflowException(); } WriteSingle(num); break; } case WireType.Fixed64: writer.ImplWriteFixed64(ref this, *(ulong*)(&value)); writer.AdvanceAndReset(8); break; default: ThrowInvalidSerializationOperation(); break; } } public unsafe void WriteSingle(float value) { ProtoWriter writer = _writer; switch (writer.WireType) { case WireType.Fixed32: writer.ImplWriteFixed32(ref this, *(uint*)(&value)); writer.AdvanceAndReset(4); break; case WireType.Fixed64: WriteDouble(value); break; default: ThrowInvalidSerializationOperation(); break; } } public void WriteInt64(long value) { ProtoWriter writer = _writer; switch (writer.WireType) { case WireType.Fixed64: writer.ImplWriteFixed64(ref this, (ulong)value); writer.AdvanceAndReset(8); break; case WireType.Variant: writer.AdvanceAndReset(writer.ImplWriteVarint64(ref this, (ulong)value)); break; case WireType.SignedVariant: writer.AdvanceAndReset(writer.ImplWriteVarint64(ref this, Zig(value))); break; case WireType.Fixed32: writer.ImplWriteFixed32(ref this, checked((uint)(int)value)); writer.AdvanceAndReset(4); break; default: ThrowInvalidSerializationOperation(); break; } } public void WriteUInt64(ulong value) { ProtoWriter writer = _writer; switch (writer.WireType) { case WireType.Fixed64: writer.ImplWriteFixed64(ref this, value); writer.AdvanceAndReset(8); break; case WireType.Variant: { int count = writer.ImplWriteVarint64(ref this, value); writer.AdvanceAndReset(count); break; } case WireType.Fixed32: writer.ImplWriteFixed32(ref this, checked((uint)value)); writer.AdvanceAndReset(4); break; default: ThrowInvalidSerializationOperation(); break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteMessage<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(SerializerFeatures features, T value, ISerializer serializer = null) { _writer.WriteMessage(ref this, value, serializer, PrefixStyle.Base128, features.ApplyRecursionCheck()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteMessage<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(int fieldNumber, SerializerFeatures features, T value, ISerializer serializer = null) { if (!TypeHelper.CanBeNull || !TypeHelper.ValueChecker.IsNull(value)) { WriteFieldHeader(fieldNumber, features.IsGroup() ? WireType.StartGroup : WireType.String); _writer.WriteMessage(ref this, value, serializer, PrefixStyle.Base128, features.ApplyRecursionCheck()); } } public void WriteGroup<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(int fieldNumber, SerializerFeatures features, T value, ISerializer serializer = null) { if (!TypeHelper.CanBeNull || !TypeHelper.ValueChecker.IsNull(value)) { WriteFieldHeader(fieldNumber, WireType.StartGroup); _writer.WriteMessage(ref this, value, serializer, PrefixStyle.Base128, features.ApplyRecursionCheck()); } } public void WriteAny<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(int fieldNumber, T value, ISerializer serializer = null) { if (serializer == null) { serializer = TypeModel.GetSerializer(Model); } WriteAny(fieldNumber, serializer.Features, value, serializer); } internal static WireType AssertWrappedAndGetWireType(ref SerializerFeatures features, out bool fieldPresence) { if (features.IsRepeated()) { fieldPresence = false; return AssertWrappedAndGetWireType(ref features, SerializerFeatures.OptionWrappedCollection, SerializerFeatures.OptionWrappedCollectionGroup); } fieldPresence = features.HasAny(SerializerFeatures.OptionWrappedValueFieldPresence); return AssertWrappedAndGetWireType(ref features, SerializerFeatures.OptionWrappedValue, SerializerFeatures.OptionWrappedValueGroup); static WireType AssertWrappedAndGetWireType(ref SerializerFeatures reference, SerializerFeatures demanded, SerializerFeatures group) { if (!reference.HasAny(demanded)) { ThrowHelper.ThrowInvalidOperationException(string.Format("{0} called for {1}, but {2} was not specified", "WriteWrapped", reference.GetCategory(), demanded)); } reference &= ~demanded; if (!reference.HasAny(group)) { return WireType.String; } return WireType.StartGroup; } } public void WriteWrapped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(int fieldNumber, SerializerFeatures features, T value, ISerializer serializer = null) { if (serializer == null) { serializer = TypeModel.GetSerializer(Model); } features.InheritFrom(serializer.Features); bool fieldPresence; WireType wireType = AssertWrappedAndGetWireType(ref features, out fieldPresence); bool flag = TypeHelper.CanBeNull && TypeHelper.ValueChecker.IsNull(value); if (!(!fieldPresence && flag)) { WriteFieldHeader(fieldNumber, wireType); if (!flag && (fieldPresence || TypeHelper.ValueChecker.HasNonTrivialValue(value))) { GetWriter().WriteWrappedItem(ref this, features, value, serializer); } else { GetWriter().WriteEmptyWrappedItem(ref this); } } } public void WriteAny<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(int fieldNumber, SerializerFeatures features, T value, ISerializer serializer = null) { if (serializer == null) { serializer = TypeModel.GetSerializer(Model); } features.InheritFrom(serializer.Features); if (features.HasAny(SerializerFeatures.OptionWrappedValue)) { WriteWrapped(fieldNumber, features, value, serializer); } else if (!TypeHelper.CanBeNull || !TypeHelper.ValueChecker.IsNull(value)) { switch (features.GetCategory()) { case SerializerFeatures.CategoryRepeated: ((IRepeatedSerializer)serializer).WriteRepeated(ref this, fieldNumber, features, value); break; case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: WriteFieldHeader(fieldNumber, features.GetWireType()); _writer.WriteMessage(ref this, value, serializer, PrefixStyle.Base128, features.ApplyRecursionCheck()); break; case SerializerFeatures.CategoryScalar: WriteFieldHeader(fieldNumber, features.GetWireType()); serializer.Write(ref this, value); break; default: features.ThrowInvalidCategory(); break; } } } public void WriteSubType<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value, ISubTypeSerializer serializer = null) where T : class { _writer.WriteSubType(ref this, value, serializer ?? TypeModel.GetSubTypeSerializer(Model)); } public void WriteSubType<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(int fieldNumber, T value, ISubTypeSerializer serializer = null) where T : class { WriteFieldHeader(fieldNumber, WireType.String); _writer.WriteSubType(ref this, value, serializer ?? TypeModel.GetSubTypeSerializer(Model)); } public void WriteBaseType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T value, ISubTypeSerializer serializer = null) where T : class { (serializer ?? TypeModel.GetSubTypeSerializer(Model)).WriteSubType(ref this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ISerializer GetSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return TypeModel.GetSerializer(Model); } internal readonly long GetPosition() { return _writer._position64; } internal readonly ProtoWriter GetWriter() { return _writer; } public void WriteBytes(ReadOnlySequence data) { ProtoWriter writer = _writer; int num = checked((int)data.Length); switch (writer.WireType) { case WireType.Fixed32: if (num != 4) { ThrowHelper.ThrowArgumentException("length"); } writer.ImplWriteBytes(ref this, data); writer.AdvanceAndReset(4); break; case WireType.Fixed64: if (num != 8) { ThrowHelper.ThrowArgumentException("length"); } writer.ImplWriteBytes(ref this, data); writer.AdvanceAndReset(8); break; case WireType.String: writer.AdvanceAndReset(writer.ImplWriteVarint32(ref this, (uint)num) + num); if (num != 0) { writer.ImplWriteBytes(ref this, data); } break; default: ThrowInvalidSerializationOperation(); break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteBytes(ArraySegment data) { WriteBytes(new ReadOnlyMemory(data.Array, data.Offset, data.Count)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteBytes(byte[] data) { WriteBytes(new ReadOnlyMemory(data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteBytes(TStorage value, IMemoryConverter converter = null) { WriteBytes((ReadOnlyMemory)(converter ?? DefaultMemoryConverter.GetFor(Model)).GetMemory(in value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteBytes(Memory data) { WriteBytes((ReadOnlySpan)data.Span); } public void WriteBytes(ReadOnlyMemory data) { WriteBytes(data.Span); } public void WriteBytes(ReadOnlySpan data) { ProtoWriter writer = _writer; int length = data.Length; switch (writer.WireType) { case WireType.Fixed32: if (length != 4) { ThrowHelper.ThrowArgumentException("length"); } writer.ImplWriteBytes(ref this, data); writer.AdvanceAndReset(4); break; case WireType.Fixed64: if (length != 8) { ThrowHelper.ThrowArgumentException("length"); } writer.ImplWriteBytes(ref this, data); writer.AdvanceAndReset(8); break; case WireType.String: writer.AdvanceAndReset(writer.ImplWriteVarint32(ref this, (uint)length) + length); if (length != 0) { writer.ImplWriteBytes(ref this, data); } break; default: ThrowInvalidSerializationOperation(); break; } } public long SerializeRoot<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value, ISerializer serializer = null) { try { CheckClear(); if (serializer == null) { serializer = TypeModel.GetSerializer(Model); } long position = GetPosition(); WriteAsRoot(value, serializer); CheckClear(); long position2 = GetPosition(); return position2 - position; } catch { Abandon(); throw; } } internal void WriteAsRoot<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value, ISerializer serializer) { SerializerFeatures serializerFeatures = serializer.Features; SerializerFeatures category = serializerFeatures.GetCategory(); if (category == SerializerFeatures.CategoryMessageWrappedAtRoot) { WriteMessage(1, SerializerFeatures.CategoryRepeated, value, serializer); } else { if (TypeHelper.CanBeNull && TypeHelper.ValueChecker.IsNull(value)) { return; } switch (category) { case SerializerFeatures.CategoryScalar: WriteFieldHeader(1, serializerFeatures.GetWireType()); serializer.Write(ref this, value); break; case SerializerFeatures.CategoryMessage: serializer.Write(ref this, value); break; case SerializerFeatures.CategoryRepeated: if (Model.OmitsOption(TypeModel.TypeModelOptions.AllowPackedEncodingAtRoot)) { serializerFeatures |= SerializerFeatures.OptionPackedDisabled; } ((IRepeatedSerializer)serializer).WriteRepeated(ref this, 1, serializerFeatures, value); break; default: serializerFeatures.ThrowInvalidCategory(); break; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly void Abandon() { _writer?.Abandon(); } private void CheckClear() { _writer?.CheckClear(ref this); } internal void WritePackedPrefix(int elementCount, WireType wireType) { if (WireType != WireType.String) { ThrowHelper.ThrowInvalidOperationException("Invalid wire-type: " + WireType); } if (elementCount < 0) { ThrowHelper.ThrowArgumentOutOfRangeException("elementCount"); } ulong value; switch (wireType) { case WireType.Fixed32: value = (ulong)((long)elementCount << 2); break; case WireType.Fixed64: value = (ulong)((long)elementCount << 3); break; default: ThrowHelper.ThrowArgumentOutOfRangeException("wireType", "Invalid wire-type: " + wireType); value = 0uL; break; } int count = _writer.ImplWriteVarint64(ref this, value); _writer.AdvanceAndReset(count); } internal void WriteObject(object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int fieldNumber) { TypeModel model = Model; if (model == null) { ThrowHelper.ThrowInvalidOperationException("Cannot serialize sub-objects unless a model is provided"); } if ((object)type == null) { type = value.GetType(); } if (WireType != WireType.None) { ThrowInvalidSerializationOperation(); } switch (style) { case PrefixStyle.Base128: WireType = WireType.String; FieldNumber = fieldNumber; if (fieldNumber > 0) { WriteHeaderCore(fieldNumber, WireType.String); } break; case PrefixStyle.Fixed32: case PrefixStyle.Fixed32BigEndian: FieldNumber = 0; WireType = WireType.Fixed32; break; default: ThrowHelper.ThrowArgumentOutOfRangeException("style"); break; } SubItemToken token = StartSubItem(value, style); if (!DynamicStub.TrySerializeAny(1, SerializerFeatures.CategoryMessageWrappedAtRoot, type, Model, ref this, value)) { TypeModel.ThrowUnexpectedType(value.GetType(), Model); } EndSubItem(token, style); } internal void WriteHeaderCore(int fieldNumber, WireType wireType) { uint value = (uint)(fieldNumber << 3) | (uint)(wireType & (WireType)7); int num = _writer.ImplWriteVarint32(ref this, value); _writer.Advance(num); } [Obsolete("If possible, please use the WriteMessage API; this API may not work correctly with all writers", false)] public SubItemToken StartSubItem(object instance) { return StartSubItem(instance, PrefixStyle.Base128); } public void Dispose() { ProtoWriter writer = _writer; this = default(State); writer?.Dispose(); } [Obsolete("If possible, please use the WriteMessage API; this API may not work correctly with all writers", false)] internal SubItemToken StartSubItem(object instance, PrefixStyle style) { _writer.PreSubItem(ref this, instance); switch (WireType) { case WireType.StartGroup: WireType = WireType.None; return new SubItemToken(-FieldNumber); case WireType.Fixed32: if ((uint)(style - 2) > 1u) { ThrowInvalidSerializationOperation(); return default(SubItemToken); } goto case WireType.String; case WireType.String: return _writer.ImplStartLengthPrefixedSubItem(ref this, instance, style); default: ThrowInvalidSerializationOperation(); return default(SubItemToken); } } [Obsolete("If possible, please use the WriteMessage API; this API may not work correctly with all writers", false)] internal void EndSubItem(SubItemToken token, PrefixStyle style) { _writer.PostSubItem(ref this); int num = (int)token.value64; if (num < 0) { WriteHeaderCore(-num, WireType.EndGroup); WireType = WireType.None; } else { _writer.ImplEndLengthPrefixedSubItem(ref this, token, style); } } public void Close() { CheckClear(); _writer?.Cleanup(); } [Obsolete("If possible, please use the WriteMessage API; this API may not work correctly with all writers", false)] public void EndSubItem(SubItemToken token) { EndSubItem(token, PrefixStyle.Base128); } public void AppendExtensionData(IExtensible instance) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } if (WireType != WireType.None) { ThrowInvalidSerializationOperation(); } AppendExtensionDataImpl(instance.GetExtensionObject(createIfMissing: false)); } private void AppendExtensionDataImpl(IExtension extn) { if (extn == null) { return; } Stream stream = extn.BeginQuery(); try { if (ProtoReader.TryConsumeSegmentRespectingPosition(stream, out var data, -1L)) { _writer.ImplWriteBytes(ref this, new ReadOnlySpan(data.Array, data.Offset, data.Count)); _writer.Advance(data.Count); } else { _writer.ImplCopyRawFromStream(ref this, stream); } } finally { extn.EndQuery(stream); } } public void AppendExtensionData(ITypedExtensible instance, Type type) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } if (WireType != WireType.None) { ThrowInvalidSerializationOperation(); } AppendExtensionDataImpl(instance.GetExtensionObject(type, createIfMissing: false)); } [MethodImpl(MethodImplOptions.NoInlining)] internal void ThrowInvalidSerializationOperation() { if (_writer == null) { ThrowHelper.ThrowProtoException("No underlying writer"); } ThrowHelper.ThrowProtoException($"Invalid serialization operation with wire-type {WireType} at position {GetPosition()}, depth {Depth}"); } [MethodImpl(MethodImplOptions.NoInlining)] internal readonly void ThrowTooDeep(int depth) { ThrowHelper.ThrowInvalidOperationException("Maximum model depth exceeded (see TypeModel.MaxDepth): " + depth); } public readonly void SetPackedField(int fieldNumber) { if (fieldNumber <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException("fieldNumber"); } _writer.packedFieldNumber = fieldNumber; } public readonly void ClearPackedField(int fieldNumber) { if (fieldNumber != _writer.packedFieldNumber) { ThrowWrongPackedField(fieldNumber, _writer); } _writer.packedFieldNumber = 0; static void ThrowWrongPackedField(int num, ProtoWriter writer) { ThrowHelper.ThrowInvalidOperationException("Field mismatch during packed encoding; expected " + writer.packedFieldNumber + " but received " + num); } } public void ThrowEnumException(object enumValue) { string arg = ((enumValue == null) ? "" : (enumValue.GetType().FullName + "." + enumValue.ToString())); ThrowHelper.ThrowProtoException($"No wire-value is mapped to the enum {arg} at position {GetPosition()}"); } public static State Create(Stream dest, TypeModel model, object userState = null) { StreamProtoWriter writer = StreamProtoWriter.CreateStreamProtoWriter(dest, model, userState); return new State(writer); } } private sealed class BufferWriterProtoWriter : ProtoWriter { private IBufferWriter _writer; private readonly NullProtoWriter _nullWriter; private protected override bool ImplDemandFlushOnDispose => true; internal static State CreateBufferWriterProtoWriter(IBufferWriter writer, TypeModel model, object userState) { if (writer == null) { ThrowHelper.ThrowArgumentNullException("writer"); } BufferWriterProtoWriter bufferWriterProtoWriter = Pool.TryGet() ?? new BufferWriterProtoWriter(); bufferWriterProtoWriter.Init(model, userState, impactCount: true); bufferWriterProtoWriter._writer = writer; return new State(bufferWriterProtoWriter); } internal override void Init(TypeModel model, object userState, bool impactCount) { base.Init(model, userState, impactCount); _nullWriter.Init(model, userState, impactCount: false); } private BufferWriterProtoWriter() { _nullWriter = new NullProtoWriter(netCache); } private protected override void ClearKnownObjects() { } internal override void Dispose() { base.Dispose(); Pool.Put(this); } private protected override void Cleanup() { base.Cleanup(); _nullWriter.Cleanup(); _writer = null; } protected internal override State DefaultState() { ThrowHelper.ThrowInvalidOperationException("You must retain and pass the state from ProtoWriter.CreateForBufferWriter"); return default(State); } private protected override bool TryFlush(ref State state) { if (state.IsActive) { int num = 0; bool flag = false; try { num = state.ConsiderWritten(); flag = true; _writer.Advance(num); } catch (Exception ex) { IDictionary data = ex.Data; if (data != null) { data.Add("ProtoBuf.Operation", flag ? "Advance" : "ConsiderWritten"); data.Add("ProtoBuf.Position", _position64); data.Add("ProtoBuf.Flushing", num); } throw; } } return true; } private protected override void ImplWriteFixed32(ref State state, uint value) { if (state.RemainingInCurrent < 4) { GetBuffer(ref state); } state.LocalWriteFixed32(value); } private protected override void ImplWriteFixed64(ref State state, ulong value) { if (state.RemainingInCurrent < 8) { GetBuffer(ref state); } state.LocalWriteFixed64(value); } private protected override void ImplWriteString(ref State state, string value, int expectedBytes) { if (expectedBytes <= state.RemainingInCurrent) { state.LocalWriteString(value); } else { FallbackWriteString(ref state, value, expectedBytes); } } private void FallbackWriteString(ref State state, string value, int expectedBytes) { GetBuffer(ref state); if (expectedBytes <= state.RemainingInCurrent) { state.LocalWriteString(value); return; } byte[] array = ArrayPool.Shared.Rent(expectedBytes); try { UTF8.GetBytes(value, 0, value.Length, array, 0); FallbackWriteBytes(ref state, new ReadOnlySpan(array, 0, expectedBytes)); } finally { ArrayPool.Shared.Return(array); } } [MethodImpl(MethodImplOptions.NoInlining)] private void GetBuffer(ref State state) { IBufferWriter writer = _writer; if (writer == null) { ThrowNoWriter(); } TryFlush(ref state); int num = ((model == null) ? 1024 : model.BufferSize); bool flag = false; try { Memory memory = _writer.GetMemory(num); flag = true; state.Init(memory); } catch (Exception ex) { IDictionary data = ex.Data; if (data != null) { data.Add("ProtoBuf.Operation", flag ? "Init" : "GetMemory"); data.Add("ProtoBuf.Position", _position64); data.Add("ProtoBuf.Requesting", num); } throw; } static void ThrowNoWriter() { throw new InvalidOperationException("Invalid state: there is no writer for this instance"); } } private protected override void ImplWriteBytes(ref State state, ReadOnlySpan bytes) { if (bytes.Length <= state.RemainingInCurrent) { state.LocalWriteBytes(bytes); } else { FallbackWriteBytes(ref state, bytes); } } private protected override void ImplWriteBytes(ref State state, ReadOnlySequence data) { if (data.IsSingleSegment) { ReadOnlySpan span = data.First.Span; if (span.Length <= state.RemainingInCurrent) { state.LocalWriteBytes(span); } else { FallbackWriteBytes(ref state, span); } return; } ReadOnlySequence.Enumerator enumerator = data.GetEnumerator(); while (enumerator.MoveNext()) { ReadOnlySpan span2 = enumerator.Current.Span; if (span2.Length <= state.RemainingInCurrent) { state.LocalWriteBytes(span2); } else { FallbackWriteBytes(ref state, span2); } } } [MethodImpl(MethodImplOptions.NoInlining)] private void FallbackWriteBytes(ref State state, ReadOnlySpan span) { while (true) { GetBuffer(ref state); int remainingInCurrent = state.RemainingInCurrent; if (span.Length <= remainingInCurrent) { break; } state.LocalWriteBytes(span.Slice(0, remainingInCurrent)); span = span.Slice(remainingInCurrent); } state.LocalWriteBytes(span); } private protected override int ImplWriteVarint32(ref State state, uint value) { if (state.RemainingInCurrent < 5) { GetBuffer(ref state); } return state.LocalWriteVarint32(value); } internal override int ImplWriteVarint64(ref State state, ulong value) { if (state.RemainingInCurrent < 10) { GetBuffer(ref state); } return state.LocalWriteVarint64(value); } protected internal override void WriteMessage(ref State state, T value, ISerializer serializer, PrefixStyle style, bool recursionCheck) { switch (base.WireType) { case WireType.String: case WireType.Fixed32: PreSubItem(ref state, (TypeHelper.IsReferenceType && recursionCheck) ? ((object)value) : null); WriteWithLengthPrefix(ref state, value, serializer, style); PostSubItem(ref state); break; default: base.WriteMessage(ref state, value, serializer, style, recursionCheck); break; } } internal override void WriteWrappedItem(ref State state, SerializerFeatures features, T value, ISerializer serializer) { switch (base.WireType) { case WireType.String: { if (serializer == null) { serializer = TypeModel.GetSerializer(base.Model); } long num = MeasureAny(_nullWriter, 1, features, value, serializer); AdvanceAndReset(ImplWriteVarint64(ref state, (ulong)num)); if (num != 0L) { long position = GetPosition(ref state); state.WriteAny(1, features, value, serializer); long position2 = GetPosition(ref state); long num2 = position2 - position; if (num2 != num) { ThrowHelper.ThrowInvalidOperationException($"Length mismatch; calculated '{num}', actual '{num2}'"); } } break; } case WireType.StartGroup: base.WriteWrappedItem(ref state, features, value, serializer); break; default: ThrowHelper.ThrowArgumentOutOfRangeException("WireType"); break; } } internal override void WriteWrappedCollection(ref State state, SerializerFeatures features, TCollection values, RepeatedSerializer serializer, ISerializer valueSerializer) { switch (base.WireType) { case WireType.String: { if (valueSerializer == null) { valueSerializer = TypeModel.GetSerializer(base.Model); } long num = MeasureRepeated(_nullWriter, 1, features, values, serializer, valueSerializer); AdvanceAndReset(ImplWriteVarint64(ref state, (ulong)num)); if (num != 0L) { long position = GetPosition(ref state); serializer.WriteRepeated(ref state, 1, features, values, valueSerializer); long position2 = GetPosition(ref state); long num2 = position2 - position; if (num2 != num) { ThrowHelper.ThrowInvalidOperationException($"Length mismatch; calculated '{num}', actual '{num2}'"); } } break; } case WireType.StartGroup: base.WriteWrappedCollection(ref state, features, values, serializer, valueSerializer); break; default: ThrowHelper.ThrowArgumentOutOfRangeException("WireType"); break; } } internal override void WriteWrappedMap(ref State state, SerializerFeatures features, TCollection values, MapSerializer serializer, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { switch (base.WireType) { case WireType.String: { long num = MeasureMap(_nullWriter, 1, features, values, serializer, keyFeatures, valueFeatures, keySerializer, valueSerializer); AdvanceAndReset(ImplWriteVarint64(ref state, (ulong)num)); if (num != 0L) { long position = GetPosition(ref state); serializer.WriteMap(ref state, 1, features, values, keyFeatures, valueFeatures, keySerializer, valueSerializer); long position2 = GetPosition(ref state); long num2 = position2 - position; if (num2 != num) { ThrowHelper.ThrowInvalidOperationException($"Length mismatch; calculated '{num}', actual '{num2}'"); } } break; } case WireType.StartGroup: base.WriteWrappedMap(ref state, features, values, serializer, keyFeatures, valueFeatures, keySerializer, valueSerializer); break; default: ThrowHelper.ThrowArgumentOutOfRangeException("WireType"); break; } } protected internal override void WriteSubType(ref State state, T value, ISubTypeSerializer serializer) { switch (base.WireType) { case WireType.String: case WireType.Fixed32: WriteWithLengthPrefix(ref state, value, serializer); break; default: base.WriteSubType(ref state, value, serializer); break; } } private void WriteWithLengthPrefix(ref State state, T value, ISerializer serializer, PrefixStyle style) { if (serializer == null) { serializer = TypeModel.GetSerializer(base.Model); } long num = Measure(_nullWriter, value, serializer); switch (style) { case PrefixStyle.Base128: AdvanceAndReset(ImplWriteVarint64(ref state, (ulong)num)); break; case PrefixStyle.Fixed32: case PrefixStyle.Fixed32BigEndian: ImplWriteFixed32(ref state, checked((uint)num)); if (style == PrefixStyle.Fixed32BigEndian) { state.ReverseLast32(); } AdvanceAndReset(4); break; default: ThrowHelper.ThrowNotImplementedException($"Sub-object prefix style not implemented: {style}"); break; case PrefixStyle.None: break; } if (num != 0L) { long position = GetPosition(ref state); serializer.Write(ref state, value); long position2 = GetPosition(ref state); long num2 = position2 - position; if (num2 != num) { ThrowHelper.ThrowInvalidOperationException($"Length mismatch; calculated '{num}', actual '{num2}'"); } } } private void WriteWithLengthPrefix(ref State state, T value, ISubTypeSerializer serializer) where T : class { if (serializer == null) { serializer = TypeModel.GetSubTypeSerializer(base.Model); } long num = Measure(_nullWriter, value, serializer); AdvanceAndReset(ImplWriteVarint64(ref state, (ulong)num)); long position = GetPosition(ref state); serializer.WriteSubType(ref state, value); long position2 = GetPosition(ref state); long num2 = position2 - position; if (num2 != num) { ThrowHelper.ThrowInvalidOperationException($"Length mismatch; calculated '{num}', actual '{num2}'"); } } private protected override void ImplEndLengthPrefixedSubItem(ref State state, SubItemToken token, PrefixStyle style) { ThrowHelper.ThrowNotSupportedException("You must use the WriteMessage API with this writer type"); } private protected override SubItemToken ImplStartLengthPrefixedSubItem(ref State state, object instance, PrefixStyle style) { ThrowHelper.ThrowNotSupportedException("You must use the WriteMessage API with this writer type"); return default(SubItemToken); } private protected override void ImplCopyRawFromStream(ref State state, Stream source) { while (true) { if (state.RemainingInCurrent == 0) { GetBuffer(ref state); } int num = state.ReadFrom(source); if (num > 0) { Advance(num); continue; } break; } } } [StructLayout(LayoutKind.Auto)] internal readonly struct WriteState { internal readonly long Position; internal readonly WireType WireType; internal readonly int FieldNumber; internal WriteState(long position, int fieldNumber, WireType wireType) { Position = position; FieldNumber = fieldNumber; WireType = wireType; } } internal sealed class NullProtoWriter : ProtoWriter { private long _abortAfter; private protected override bool ImplDemandFlushOnDispose => false; protected internal override State DefaultState() { return new State(this); } internal static State CreateNullProtoWriter(TypeModel model, object userState, long abortAfter) { NullProtoWriter nullProtoWriter = Pool.TryGet() ?? new NullProtoWriter(); nullProtoWriter.Init(model, userState, impactCount: true); nullProtoWriter._abortAfter = ((abortAfter < 0) ? long.MaxValue : abortAfter); return new State(nullProtoWriter); } private NullProtoWriter() { } internal NullProtoWriter(NetObjectCache knownObjects) : base(knownObjects) { _abortAfter = long.MaxValue; } internal override void Dispose() { base.Dispose(); Pool.Put(this); } private protected override void ImplCopyRawFromStream(ref State state, Stream source) { byte[] array = ArrayPool.Shared.Rent(8192); try { while (true) { int num = source.Read(array, 0, array.Length); if (num <= 0) { break; } Advance(num); CheckOversized(ref state); } } finally { ArrayPool.Shared.Return(array); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void CheckOversized(long max, long actual) { if (max >= 0 && actual > max) { ThrowHelper.ThrowProtoException($"Length {actual} exceeds constrained size of {max} bytes"); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void CheckOversized(ref State state) { long position = state.GetPosition(); if (position > _abortAfter) { CheckOversized(_abortAfter, position); } } protected internal override void WriteMessage(ref State state, T value, ISerializer serializer, PrefixStyle style, bool recursionCheck) { long length = Measure(this, value, serializer ?? TypeModel.GetSerializer(base.Model)); AdvanceSubMessage(ref state, length, style); } internal override void WriteWrappedItem(ref State state, SerializerFeatures features, T value, ISerializer serializer) { long length = MeasureAny(this, 1, features, value, serializer ?? TypeModel.GetSerializer(base.Model)); AdvanceSubMessage(ref state, length, PrefixStyle.Base128); } internal override void WriteWrappedCollection(ref State state, SerializerFeatures features, TCollection values, RepeatedSerializer serializer, ISerializer valueSerializer) { long length = MeasureRepeated(this, 1, features, values, serializer, valueSerializer ?? TypeModel.GetSerializer(base.Model)); AdvanceSubMessage(ref state, length, PrefixStyle.Base128); } internal override void WriteWrappedMap(ref State state, SerializerFeatures features, TCollection values, MapSerializer serializer, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { long length = MeasureMap(this, 1, features, values, serializer, keyFeatures, valueFeatures, keySerializer, valueSerializer); AdvanceSubMessage(ref state, length, PrefixStyle.Base128); } private void AdvanceSubMessage(ref State state, long length, PrefixStyle style) { long num; switch (base.WireType) { case WireType.String: case WireType.Fixed32: switch (style) { case PrefixStyle.None: num = 0L; break; case PrefixStyle.Fixed32: case PrefixStyle.Fixed32BigEndian: num = 4L; break; case PrefixStyle.Base128: num = ImplWriteVarint64(ref state, (ulong)length); break; default: state.ThrowInvalidSerializationOperation(); num = 0L; break; } break; case WireType.StartGroup: num = ImplWriteVarint32(ref state, (uint)(fieldNumber << 3)); break; default: state.ThrowInvalidSerializationOperation(); num = 0L; break; } Advance(num + length); CheckOversized(ref state); base.WireType = WireType.None; } protected internal override void WriteSubType(ref State state, T value, ISubTypeSerializer serializer) { if (serializer == null) { serializer = TypeModel.GetSubTypeSerializer(base.Model); } long length = Measure(this, value, serializer); AdvanceSubMessage(ref state, length, PrefixStyle.Base128); } private protected override SubItemToken ImplStartLengthPrefixedSubItem(ref State state, object instance, PrefixStyle style) { base.WireType = WireType.None; return new SubItemToken(_position64); } private protected override void ImplEndLengthPrefixedSubItem(ref State state, SubItemToken token, PrefixStyle style) { long value = _position64 - token.value64; int num; switch (style) { case PrefixStyle.Fixed32: case PrefixStyle.Fixed32BigEndian: num = 4; break; case PrefixStyle.Base128: num = ImplWriteVarint64(ref state, (ulong)value); break; default: state.ThrowInvalidSerializationOperation(); goto case PrefixStyle.None; case PrefixStyle.None: num = 0; break; } Advance(num); CheckOversized(ref state); } private protected override void ImplWriteBytes(ref State state, ReadOnlySpan data) { } private protected override void ImplWriteBytes(ref State state, ReadOnlySequence data) { } private protected override void ImplWriteFixed32(ref State state, uint value) { } private protected override void ImplWriteFixed64(ref State state, ulong value) { } private protected override void ImplWriteString(ref State state, string value, int expectedBytes) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected override int ImplWriteVarint32(ref State state, uint value) { return MeasureUInt32(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal override int ImplWriteVarint64(ref State state, ulong value) { return MeasureUInt64(value); } private protected override bool TryFlush(ref State state) { return true; } } private class StreamProtoWriter : ProtoWriter { private Stream dest; private int flushLock; private byte[] ioBuffer; private int ioIndex; private protected override bool ImplDemandFlushOnDispose => true; protected internal override State DefaultState() { return new State(this); } private StreamProtoWriter() { } internal static StreamProtoWriter CreateStreamProtoWriter(Stream dest, TypeModel model, object userState) { StreamProtoWriter streamProtoWriter = Pool.TryGet() ?? new StreamProtoWriter(); streamProtoWriter.Init(model, userState, impactCount: true); if (dest == null) { ThrowHelper.ThrowArgumentNullException("dest"); } if (!dest.CanWrite) { ThrowHelper.ThrowArgumentException("Cannot write to stream", "dest"); } streamProtoWriter.dest = dest; streamProtoWriter.ioBuffer = BufferPool.GetBuffer(); return streamProtoWriter; } internal override void Init(TypeModel model, object userState, bool impactCount) { base.Init(model, userState, impactCount); ioIndex = 0; flushLock = 0; } internal override void Dispose() { base.Dispose(); Pool.Put(this); } private protected override void Cleanup() { base.Cleanup(); dest = null; BufferPool.ReleaseBufferToPool(ref ioBuffer); } private static void IncrementedAndReset(int length, StreamProtoWriter writer) { writer.ioIndex += length; writer.Advance(length); writer.WireType = WireType.None; } private protected override bool TryFlush(ref State state) { if (flushLock != 0) { return false; } if (ioIndex != 0 && dest != null) { dest.Write(ioBuffer, 0, ioIndex); ioIndex = 0; } return true; } private static void DemandSpace(int required, StreamProtoWriter writer, ref State state) { if (writer.ioBuffer.Length - writer.ioIndex < required) { TryFlushOrResize(required, writer, ref state); } } private static void TryFlushOrResize(int required, StreamProtoWriter writer, ref State state) { if (!writer.TryFlush(ref state) || writer.ioBuffer.Length - writer.ioIndex < required) { BufferPool.ResizeAndFlushLeft(ref writer.ioBuffer, required + writer.ioIndex, 0, writer.ioIndex); } } private protected override void ImplWriteBytes(ref State state, ReadOnlySpan bytes) { int length = bytes.Length; if (flushLock != 0 || length <= ioBuffer.Length) { DemandSpace(length, this, ref state); bytes.CopyTo(new Span(ioBuffer, ioIndex, length)); ioIndex += length; } else { state.Flush(); dest.Write(bytes); } } private protected override void ImplWriteBytes(ref State state, ReadOnlySequence data) { int num = checked((int)data.Length); if (num == 0) { return; } if (flushLock != 0 || num <= ioBuffer.Length) { DemandSpace(num, this, ref state); data.CopyTo(new Span(ioBuffer, ioIndex, num)); ioIndex += num; return; } state.Flush(); ReadOnlySequence.Enumerator enumerator = data.GetEnumerator(); while (enumerator.MoveNext()) { ReadOnlyMemory current = enumerator.Current; dest.Write(current.Span); } } private protected override void ImplWriteString(ref State state, string value, int expectedBytes) { DemandSpace(expectedBytes, this, ref state); int bytes = UTF8.GetBytes(value, 0, value.Length, ioBuffer, ioIndex); ioIndex += bytes; } private static void WriteUInt32ToBuffer(uint value, byte[] buffer, int index) { BinaryPrimitives.WriteUInt32LittleEndian(buffer.AsSpan(index, 4), value); } private protected override void ImplWriteFixed32(ref State state, uint value) { DemandSpace(4, this, ref state); WriteUInt32ToBuffer(value, ioBuffer, ioIndex); ioIndex += 4; } private protected override void ImplWriteFixed64(ref State state, ulong value) { DemandSpace(8, this, ref state); byte[] array = ioBuffer; int start = ioIndex; BinaryPrimitives.WriteUInt64LittleEndian(array.AsSpan(start, 8), value); ioIndex += 8; } internal override int ImplWriteVarint64(ref State state, ulong value) { DemandSpace(10, this, ref state); int num = 0; do { ioBuffer[ioIndex++] = (byte)((value & 0x7F) | 0x80); num++; } while ((value >>= 7) != 0L); ioBuffer[ioIndex - 1] &= 127; return num; } private protected override int ImplWriteVarint32(ref State state, uint value) { DemandSpace(5, this, ref state); int num = 0; do { ioBuffer[ioIndex++] = (byte)((value & 0x7F) | 0x80); num++; } while ((value >>= 7) != 0); ioBuffer[ioIndex - 1] &= 127; return num; } private protected override void ImplCopyRawFromStream(ref State state, Stream source) { byte[] array = ioBuffer; int num = array.Length - ioIndex; int num2 = 1; while (num > 0 && (num2 = source.Read(array, ioIndex, num)) > 0) { ioIndex += num2; Advance(num2); num -= num2; } if (num2 <= 0) { return; } if (flushLock == 0) { state.Flush(); while ((num2 = source.Read(array, 0, array.Length)) > 0) { dest.Write(array, 0, num2); Advance(num2); } return; } while (true) { DemandSpace(128, this, ref state); if ((num2 = source.Read(ioBuffer, ioIndex, ioBuffer.Length - ioIndex)) > 0) { Advance(num2); ioIndex += num2; continue; } break; } } private protected override SubItemToken ImplStartLengthPrefixedSubItem(ref State state, object instance, PrefixStyle style) { switch (base.WireType) { case WireType.String: base.WireType = WireType.None; DemandSpace(32, this, ref state); flushLock++; Advance(1L); return new SubItemToken(ioIndex++); case WireType.Fixed32: { DemandSpace(32, this, ref state); flushLock++; SubItemToken result = new SubItemToken(ioIndex); IncrementedAndReset(4, this); return result; } default: state.ThrowInvalidSerializationOperation(); return default(SubItemToken); } } private protected override void ImplEndLengthPrefixedSubItem(ref State state, SubItemToken token, PrefixStyle style) { int num = (int)token.value64; switch (style) { case PrefixStyle.Fixed32: { int num2 = ioIndex - num - 4; WriteUInt32ToBuffer((uint)num2, ioBuffer, num); break; } case PrefixStyle.Fixed32BigEndian: { int num2 = ioIndex - num - 4; byte[] array2 = ioBuffer; WriteUInt32ToBuffer((uint)num2, array2, num); byte b = array2[num]; array2[num] = array2[num + 3]; array2[num + 3] = b; b = array2[num + 1]; array2[num + 1] = array2[num + 2]; array2[num + 2] = b; break; } case PrefixStyle.Base128: { int num2 = ioIndex - num - 1; int num3 = 0; uint num4 = (uint)num2; while ((num4 >>= 7) != 0) { num3++; } if (num3 == 0) { ioBuffer[num] = (byte)(num2 & 0x7F); break; } DemandSpace(num3, this, ref state); byte[] array = ioBuffer; Buffer.BlockCopy(array, num + 1, array, num + 1 + num3, num2); num4 = (uint)num2; do { array[num++] = (byte)((num4 & 0x7F) | 0x80); } while ((num4 >>= 7) != 0); array[num - 1] = (byte)(array[num - 1] & -129); Advance(num3); ioIndex += num3; break; } default: ThrowHelper.ThrowArgumentOutOfRangeException("style"); break; } if (--flushLock == 0 && ioIndex >= 1024) { state.Flush(); } } } private const MethodImplOptions HotPath = MethodImplOptions.AggressiveInlining; internal const string PreferWriteMessage = "If possible, please use the WriteMessage API; this API may not work correctly with all writers"; private TypeModel model; private int packedFieldNumber; private protected readonly NetObjectCache netCache; private int fieldNumber; private int _depth; private const int RecursionCheckDepth = 25; private List recursionStack; private bool _needFlush; private long _position64; protected internal static readonly UTF8Encoding UTF8 = new UTF8Encoding(); internal WireType WireType { get; set; } [Obsolete("Prefer UserState")] public SerializationContext Context => SerializationContext.AsSerializationContext(this); public object UserState { get; private set; } internal int Depth => _depth; public TypeModel Model { get { return model; } internal set { model = value; } } private protected abstract bool ImplDemandFlushOnDispose { get; } [Obsolete("Please migrate to TypeModel.BufferSize")] public static int BufferSize { get { return TypeModel.DefaultModel.BufferSize; } set { TypeModel.DefaultModel.BufferSize = value; } } void IDisposable.Dispose() { Dispose(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) { writer.DefaultState().WriteFieldHeader(fieldNumber, wireType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBytes(byte[] data, ProtoWriter writer) { writer.DefaultState().WriteBytes(data); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBytes(byte[] data, int offset, int length, ProtoWriter writer) { writer.DefaultState().WriteBytes(new ReadOnlyMemory(data, offset, length)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Obsolete("If possible, please use the WriteMessage API; this API may not work correctly with all writers", false)] public static SubItemToken StartSubItem(object instance, ProtoWriter writer) { return writer.DefaultState().StartSubItem(instance, PrefixStyle.Base128); } private void PreSubItem(ref State state, object instance) { if (_depth < 0) { state.ThrowInvalidSerializationOperation(); } if (++_depth >= ((model == null) ? 512 : model.MaxDepth)) { state.ThrowTooDeep(_depth); } if (_depth > 25) { CheckRecursionStackAndPush(instance); } if (packedFieldNumber != 0) { ThrowHelper.ThrowInvalidOperationException("Cannot begin a sub-item while performing packed encoding"); } } private void CheckRecursionStackAndPush(object instance) { if (recursionStack == null) { recursionStack = new List(); } else if (instance != null) { int num = 0; foreach (object item in recursionStack) { if (item == instance) { ThrowHelper.ThrowProtoException($"Possible recursion detected (offset: {recursionStack.Count - num} level(s)): {instance}"); } num++; } } recursionStack.Add(instance); } private void PopRecursionStack() { recursionStack.RemoveAt(recursionStack.Count - 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Obsolete("If possible, please use the WriteMessage API; this API may not work correctly with all writers", false)] public static void EndSubItem(SubItemToken token, ProtoWriter writer) { writer.DefaultState().EndSubItem(token, PrefixStyle.Base128); } private void PostSubItem(ref State state) { if (WireType != WireType.None) { state.ThrowInvalidSerializationOperation(); } if (_depth <= 0) { state.ThrowInvalidSerializationOperation(); } if (_depth-- > 25) { PopRecursionStack(); } packedFieldNumber = 0; } private protected ProtoWriter() { netCache = new NetObjectCache(); } private protected ProtoWriter(NetObjectCache knownObjects) { netCache = knownObjects; } internal virtual void Init(TypeModel model, object userState, bool impactCount) { _position64 = 0L; _needFlush = false; packedFieldNumber = 0; _depth = 0; fieldNumber = 0; this.model = model; WireType = WireType.None; if (userState is SerializationContext serializationContext) { serializationContext.Freeze(); } UserState = userState; } internal WriteState ResetWriteState() { WriteState result = new WriteState(_position64, fieldNumber, WireType); _position64 = 0L; fieldNumber = 0; WireType = WireType.None; return result; } internal void SetWriteState(WriteState state) { _position64 = state.Position; fieldNumber = state.FieldNumber; WireType = state.WireType; } internal virtual void Dispose() { Cleanup(); } private protected virtual void Cleanup() { if (_depth == 0 && _needFlush && ImplDemandFlushOnDispose) { ThrowHelper.ThrowInvalidOperationException("Writer was disposed without being flushed; data may be lost - you should ensure that Flush (or Abandon) is called"); } recursionStack?.Clear(); ClearKnownObjects(); model = null; UserState = null; } private protected virtual void ClearKnownObjects() { netCache?.Clear(); } protected internal virtual void WriteMessage<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(ref State state, T value, ISerializer serializer, PrefixStyle style, bool recursionCheck) { SubItemToken token = state.StartSubItem((TypeHelper.IsReferenceType && recursionCheck) ? ((object)value) : null, style); (serializer ?? TypeModel.GetSerializer(model)).Write(ref state, value); state.EndSubItem(token, style); } internal virtual void WriteWrappedCollection(ref State state, SerializerFeatures features, TCollection values, RepeatedSerializer serializer, ISerializer valueSerializer) { SubItemToken token = state.StartSubItem(null); serializer.WriteRepeated(ref state, 1, features, values, valueSerializer); state.EndSubItem(token); } internal virtual void WriteWrappedMap(ref State state, SerializerFeatures features, TCollection values, MapSerializer serializer, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { SubItemToken token = state.StartSubItem(null); serializer.WriteMap(ref state, 1, features, values, keyFeatures, valueFeatures, keySerializer, valueSerializer); state.EndSubItem(token); } internal void WriteEmptyWrappedItem(ref State state) { switch (WireType) { case WireType.String: AdvanceAndReset(ImplWriteVarint32(ref state, 0u)); break; case WireType.StartGroup: state.WriteHeaderCore(state.FieldNumber, WireType.EndGroup); WireType = WireType.None; break; default: ThrowHelper.ThrowArgumentOutOfRangeException("WireType"); break; } } internal virtual void WriteWrappedItem(ref State state, SerializerFeatures features, T value, ISerializer serializer) { SubItemToken token = state.StartSubItem((TypeHelper.IsReferenceType & features.ApplyRecursionCheck()) ? ((object)value) : null, PrefixStyle.Base128); state.WriteAny(1, features, value, serializer); state.EndSubItem(token); } protected internal virtual void WriteSubType<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(ref State state, T value, ISubTypeSerializer serializer) where T : class { SubItemToken token = state.StartSubItem(null, PrefixStyle.Base128); serializer.WriteSubType(ref state, value); state.EndSubItem(token, PrefixStyle.Base128); } public void Abandon() { _needFlush = false; } internal long GetPosition(ref State state) { return _position64; } private protected void Advance(long count) { _position64 += count; } internal void AdvanceAndReset(int count) { _position64 += count; WireType = WireType.None; } internal void AdvanceAndReset(long count) { _position64 += count; WireType = WireType.None; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Close() { DefaultState().Close(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void CheckClear(ref State state) { if (_depth != 0 || !TryFlush(ref state)) { ThrowHelper.ThrowInvalidOperationException($"The writer is in an incomplete state (depth: {_depth}, type: {GetType().Name}, field: {fieldNumber}, wire-type: {WireType}, position: {state.GetPosition()})"); } _needFlush = false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint Zig(int value) { return (uint)((value << 1) ^ (value >> 31)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static ulong Zig(long value) { return (ulong)((value << 1) ^ (value >> 63)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteString(string value, ProtoWriter writer) { writer.DefaultState().WriteString(value); } private protected abstract void ImplWriteString(ref State state, string value, int expectedBytes); private protected abstract int ImplWriteVarint32(ref State state, uint value); internal abstract int ImplWriteVarint64(ref State state, ulong value); private protected abstract void ImplWriteFixed32(ref State state, uint value); private protected abstract void ImplWriteFixed64(ref State state, ulong value); private protected abstract void ImplWriteBytes(ref State state, ReadOnlySpan data); private protected abstract void ImplWriteBytes(ref State state, ReadOnlySequence data); private protected abstract void ImplCopyRawFromStream(ref State state, Stream source); private protected abstract SubItemToken ImplStartLengthPrefixedSubItem(ref State state, object instance, PrefixStyle style); private protected abstract void ImplEndLengthPrefixedSubItem(ref State state, SubItemToken token, PrefixStyle style); private protected abstract bool TryFlush(ref State state); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteUInt64(ulong value, ProtoWriter writer) { writer.DefaultState().WriteUInt64(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt64(long value, ProtoWriter writer) { writer.DefaultState().WriteInt64(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteUInt32(uint value, ProtoWriter writer) { writer.DefaultState().WriteUInt32(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt16(short value, ProtoWriter writer) { writer.DefaultState().WriteInt16(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteUInt16(ushort value, ProtoWriter writer) { writer.DefaultState().WriteUInt16(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteByte(byte value, ProtoWriter writer) { writer.DefaultState().WriteByte(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteSByte(sbyte value, ProtoWriter writer) { writer.DefaultState().WriteSByte(value); } public static void WriteInt32(int value, ProtoWriter writer) { writer.DefaultState().WriteInt32(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDouble(double value, ProtoWriter writer) { writer.DefaultState().WriteDouble(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteSingle(float value, ProtoWriter writer) { writer.DefaultState().WriteSingle(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ThrowEnumException(ProtoWriter writer, object enumValue) { writer.DefaultState().ThrowEnumException(enumValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteBoolean(bool value, ProtoWriter writer) { writer.DefaultState().WriteBoolean(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) { writer.DefaultState().AppendExtensionData(instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetPackedField(int fieldNumber, ProtoWriter writer) { writer.DefaultState().SetPackedField(fieldNumber); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ClearPackedField(int fieldNumber, ProtoWriter writer) { writer.DefaultState().ClearPackedField(fieldNumber); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WritePackedPrefix(int elementCount, WireType wireType, ProtoWriter writer) { writer.DefaultState().WritePackedPrefix(elementCount, wireType); } internal string SerializeType(Type type) { return TypeModel.SerializeType(model, type); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteType(Type value, ProtoWriter writer) { writer.DefaultState().WriteType(value); } internal static long MeasureRepeated(NullProtoWriter writer, int fieldNumber, SerializerFeatures features, TCollection values, RepeatedSerializer serializer, ISerializer valueSerializer) { object obj = null; long length; if (TypeHelper.IsReferenceType) { obj = values; if (obj == null) { return 0L; } if (writer.netCache.TryGetKnownLength(obj, null, out length)) { return length; } } WriteState writeState = writer.ResetWriteState(); State state = new State(writer); serializer.WriteRepeated(ref state, fieldNumber, features, values, valueSerializer); length = state.GetPosition(); writer.SetWriteState(writeState); if (obj != null) { writer.netCache.SetKnownLength(obj, null, length); } return length; } internal static long MeasureMap(NullProtoWriter writer, int fieldNumber, SerializerFeatures features, TCollection values, MapSerializer serializer, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { object obj = null; long length; if (TypeHelper.IsReferenceType) { obj = values; if (obj == null) { return 0L; } if (writer.netCache.TryGetKnownLength(obj, null, out length)) { return length; } } WriteState writeState = writer.ResetWriteState(); State state = new State(writer); serializer.WriteMap(ref state, fieldNumber, features, values, keyFeatures, valueFeatures, keySerializer, valueSerializer); length = state.GetPosition(); writer.SetWriteState(writeState); if (obj != null) { writer.netCache.SetKnownLength(obj, null, length); } return length; } internal static long MeasureAny(NullProtoWriter writer, int fieldNumber, SerializerFeatures features, T value, ISerializer serializer) { WriteState writeState = writer.ResetWriteState(); State state = new State(writer); state.WriteAny(fieldNumber, features, value, serializer); long position = state.GetPosition(); writer.SetWriteState(writeState); return position; } internal static long Measure(NullProtoWriter writer, T value, ISerializer serializer) { object obj = null; long length; if (TypeHelper.IsReferenceType) { obj = value; if (obj == null) { return 0L; } if (writer.netCache.TryGetKnownLength(obj, null, out length)) { return length; } } WriteState writeState = writer.ResetWriteState(); State state = new State(writer); serializer.Write(ref state, value); length = state.GetPosition(); writer.SetWriteState(writeState); if (obj != null) { writer.netCache.SetKnownLength(obj, null, length); } return length; } internal static long Measure(NullProtoWriter writer, T value, ISubTypeSerializer serializer) where T : class { if (value == null) { return 0L; } if (writer.netCache.TryGetKnownLength(value, typeof(T), out var length)) { return length; } WriteState writeState = writer.ResetWriteState(); State state = new State(writer); serializer.WriteSubType(ref state, value); length = state.GetPosition(); writer.SetWriteState(writeState); writer.netCache.SetKnownLength(value, typeof(T), length); return length; } internal static State CreateNull(TypeModel model, object userState, long abortAfter) { return NullProtoWriter.CreateNullProtoWriter(model, userState, abortAfter); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MeasureInt32(int value) { if (value >= 0) { return MeasureUInt32((uint)value); } return 10; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MeasureUInt32(uint value) { int num = 1; while ((value >>= 7) != 0) { num++; } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MeasureInt64(long value) { if (value >= 0) { return MeasureUInt64((ulong)value); } return 10; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MeasureUInt64(ulong value) { int num = 1; while ((value >>= 7) != 0L) { num++; } return num; } protected internal abstract State DefaultState(); internal void InitializeFrom(ProtoWriter writer) { netCache?.InitializeFrom(writer?.netCache); } internal void CopyBack(ProtoWriter writer) { netCache?.CopyBack(writer?.netCache); } internal int GetLengthHits(out int misses) { misses = netCache?.LengthMisses ?? 0; return netCache?.LengthHits ?? 0; } [Obsolete("If possible, please use the State API; a transitionary implementation is provided, but this API may be removed in a future version", false)] public static ProtoWriter Create(Stream dest, TypeModel model, SerializationContext context = null) { return StreamProtoWriter.CreateStreamProtoWriter(dest, model, context); } } public sealed class SerializationContext { private bool frozen; private object context; private StreamingContextStates state = StreamingContextStates.Persistence; public object Context { get { return context; } set { if (context != value) { ThrowIfFrozen(); context = value; } } } internal static SerializationContext Default { get; } = new SerializationContext { frozen = true }; public StreamingContextStates State { get { return state; } set { if (state != value) { ThrowIfFrozen(); state = value; } } } internal void Freeze() { frozen = true; } private void ThrowIfFrozen() { if (frozen) { ThrowHelper.ThrowInvalidOperationException("The serialization-context cannot be changed once it is in use"); } } public static implicit operator StreamingContext(SerializationContext ctx) { if (ctx == null) { return new StreamingContext(StreamingContextStates.Persistence); } return new StreamingContext(ctx.state, ctx.context); } public static implicit operator SerializationContext(StreamingContext ctx) { return new SerializationContext { Context = ctx.Context, State = ctx.State }; } public static StreamingContext AsStreamingContext(ISerializationContext context) { object obj = context?.UserState; if (obj is SerializationContext serializationContext) { return new StreamingContext(serializationContext.state, serializationContext.context); } return new StreamingContext(StreamingContextStates.Persistence, obj); } public static SerializationContext AsSerializationContext(ISerializationContext context) { object obj = context?.UserState; if (obj != null) { if (obj is SerializationContext result) { return result; } return new SerializationContext { context = context, frozen = true }; } return Default; } } public sealed class StringMap { } [StructLayout(LayoutKind.Auto)] public readonly struct SubItemToken { internal readonly long value64; public override string ToString() { if (value64 < 0) { return $"Group {-value64}"; } if (value64 == long.MaxValue) { return "Message (restores to end when ended)"; } return "Message (restores to value64 when ended)"; } public override int GetHashCode() { return value64.GetHashCode(); } public override bool Equals(object obj) { if (obj is SubItemToken subItemToken) { return subItemToken.value64 == value64; } return false; } internal SubItemToken(long value) { value64 = value; } } public static class TypedExtensible { public static bool TryGetValue(this ITypedExtensible instance, int tag, out TValue value, Type type = null, DataFormat format = DataFormat.Default, TypeModel model = null) { IExtension extension = GetExtension(instance, type, createIfMissing: false, ref model); value = default(TValue); bool result = false; if (extension != null) { foreach (TValue extendedValue in ExtensibleUtil.GetExtendedValues(model, typeof(TValue), extension, tag, format, singleton: true)) { value = extendedValue; result = true; } } return result; } public static TValue GetValue(this ITypedExtensible instance, int tag, Type type = null, DataFormat format = DataFormat.Default, TypeModel model = null) { if (!instance.TryGetValue(tag, out var value, type, format, model)) { return default(TValue); } return value; } public static IEnumerable GetValues(this ITypedExtensible instance, int tag, Type type = null, DataFormat format = DataFormat.Default, TypeModel model = null) { IExtension extension = GetExtension(instance, type, createIfMissing: false, ref model); if (extension != null) { return ExtensibleUtil.GetExtendedValues(model, typeof(TValue), extension, tag, format, singleton: false).Cast(); } return Enumerable.Empty(); } public static void AppendValue(this ITypedExtensible instance, int tag, TValue value, Type type = null, DataFormat format = DataFormat.Default, TypeModel model = null) { object obj = value; if (obj == null) { ThrowHelper.ThrowArgumentNullException("value"); } ExtensibleUtil.AppendExtendValue(model, GetExtension(instance, type, createIfMissing: true, ref model), tag, format, obj); } private static IExtension GetExtension(ITypedExtensible instance, Type type, bool createIfMissing, ref TypeModel model) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } Type type2 = instance.GetType(); if ((object)type == null) { type = type2; } if (!type.IsClass) { ThrowHelper.ThrowNotSupportedException("Extension fields can only be used with class target types ('" + type.NormalizeName() + "' is not valid)"); } if ((object)type != type2) { if (model == null) { model = TypeModel.DefaultModel; } if (type == typeof(object) || type == typeof(Extensible) || !type.IsAssignableFrom(type2) || (!(model is TypeModel.NullModel) && !model.CanSerializeContractType(type))) { ThrowHelper.ThrowInvalidOperationException("The extension field target type '" + type.NormalizeName() + "' is not a valid base-type of '" + type2.NormalizeName() + "'"); } } return instance.GetExtensionObject(type, createIfMissing); } } public delegate Type TypeResolver(int fieldNumber); public enum WireType { None = -1, [Obsolete("This is an embarrassing typo... sorry; see also: Varint")] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] Variant = 0, Varint = 0, Fixed64 = 1, String = 2, StartGroup = 3, EndGroup = 4, Fixed32 = 5, [Obsolete("This is an embarrassing typo... sorry; see also: SignedVarint")] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] SignedVariant = 8, [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] SignedVarint = 8 } } namespace ProtoBuf.WellKnownTypes { [StructLayout(LayoutKind.Auto)] [ProtoContract(Name = ".google.protobuf.Duration", Serializer = typeof(PrimaryTypeProvider), Origin = "google/protobuf/duration.proto")] public readonly struct Duration { [ProtoMember(1, Name = "seconds", DataFormat = DataFormat.Default)] public long Seconds { get; } [ProtoMember(2, Name = "nanos", DataFormat = DataFormat.Default)] public int Nanoseconds { get; } public Duration(long seconds, int nanoseconds) { Seconds = seconds; Nanoseconds = nanoseconds; } public Duration(TimeSpan value) : this(value.Ticks) { } internal Duration(long ticks) { Seconds = PrimaryTypeProvider.ToDurationSeconds(ticks, out var nanos, isTimestamp: false); Nanoseconds = nanos; } public TimeSpan AsTimeSpan() { return TimeSpan.FromTicks(ToTicks()); } internal long ToTicks() { return PrimaryTypeProvider.ToTicks(Seconds, Nanoseconds); } public static implicit operator TimeSpan(Duration value) { return value.AsTimeSpan(); } public static implicit operator Duration(TimeSpan value) { return new Duration(value); } public Duration Normalize() { long seconds = Seconds; int nanos = Nanoseconds; PrimaryTypeProvider.NormalizeSecondsNanoseconds(ref seconds, ref nanos, isTimestamp: false); return new Duration(seconds, nanos); } } [StructLayout(LayoutKind.Explicit, Size = 1)] [ProtoContract(Name = ".google.protobuf.Empty", Serializer = typeof(PrimaryTypeProvider), Origin = "google/protobuf/empty.proto")] public readonly struct Empty { } [StructLayout(LayoutKind.Auto)] [ProtoContract(Name = ".google.protobuf.Timestamp", Serializer = typeof(PrimaryTypeProvider), Origin = "google/protobuf/timestamp.proto")] public readonly struct Timestamp : IComparable, IEquatable { private static readonly DateTime TimestampEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); [ProtoMember(1, Name = "seconds", DataFormat = DataFormat.Default)] public long Seconds { get; } [ProtoMember(2, Name = "nanos", DataFormat = DataFormat.Default)] public int Nanoseconds { get; } public Timestamp(long seconds, int nanoseconds) { Seconds = seconds; Nanoseconds = nanoseconds; } public Timestamp(DateTime value) { Seconds = PrimaryTypeProvider.ToDurationSeconds((value - TimestampEpoch).Ticks, out var nanos, isTimestamp: true); Nanoseconds = nanos; } public Timestamp Normalize() { long seconds = Seconds; int nanos = Nanoseconds; PrimaryTypeProvider.NormalizeSecondsNanoseconds(ref seconds, ref nanos, isTimestamp: true); return new Timestamp(seconds, nanos); } public DateTime AsDateTime() { return TimestampEpoch.AddTicks(PrimaryTypeProvider.ToTicks(Seconds, Nanoseconds)); } public int CompareTo(Timestamp other) { if (Seconds != other.Seconds) { return Seconds.CompareTo(other.Seconds); } return Nanoseconds.CompareTo(other.Nanoseconds); } public bool Equals(Timestamp other) { if (Seconds == other.Seconds) { return Nanoseconds == other.Nanoseconds; } return false; } public static implicit operator DateTime(Timestamp value) { return value.AsDateTime(); } public static implicit operator Timestamp(DateTime value) { return new Timestamp(value); } } } namespace ProtoBuf.Serializers { public static class EnumSerializer { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateSByte() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateInt16() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateInt32() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateInt64() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateByte() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateUInt16() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateUInt32() where T : unmanaged { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EnumSerializer CreateUInt64() where T : unmanaged { return SerializerCache>.InstanceField; } } public abstract class EnumSerializer : ISerializer, ISerializer where TEnum : unmanaged { SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; [MethodImpl(MethodImplOptions.AggressiveInlining)] TEnum? ISerializer.Read(ref ProtoReader.State state, TEnum? value) { return Read(ref state, default(TEnum)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] void ISerializer.Write(ref ProtoWriter.State state, TEnum? value) { Write(ref state, value.Value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public abstract TEnum Read(ref ProtoReader.State state, TEnum value); [MethodImpl(MethodImplOptions.AggressiveInlining)] public abstract void Write(ref ProtoWriter.State state, TEnum value); private protected EnumSerializer() { } } internal abstract class EnumSerializer : EnumSerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer where TEnum : unmanaged where TRaw : unmanaged { private protected const int NegLength = 10; private protected unsafe EnumSerializer() { Type typeFromHandle = typeof(TEnum); if (sizeof(TEnum) != sizeof(TRaw) || !typeFromHandle.IsEnum || Enum.GetUnderlyingType(typeFromHandle) != typeof(TRaw)) { ThrowHelper.ThrowInvalidOperationException(typeof(TEnum).NormalizeName() + " is not a valid enum for " + typeof(TRaw).NormalizeName()); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected abstract TRaw Read(ref ProtoReader.State state); [MethodImpl(MethodImplOptions.AggressiveInlining)] protected abstract void Write(ref ProtoWriter.State state, TRaw value); [MethodImpl(MethodImplOptions.AggressiveInlining)] public abstract int MeasureVarint(TRaw value); [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual int MeasureSignedVarint(TRaw value) { return -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe override TEnum Read(ref ProtoReader.State state, TEnum value) { TRaw val = Read(ref state); return *(TEnum*)(&val); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe override void Write(ref ProtoWriter.State state, TEnum value) { Write(ref state, *(TRaw*)(&value)); } public unsafe int Measure(ISerializationContext context, WireType wireType, TEnum value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => MeasureVarint(*(TRaw*)(&value)), WireType.SignedVariant => MeasureSignedVarint(*(TRaw*)(&value)), _ => -1, }; } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, TEnum? value) { return Measure(context, wireType, value.Value); } } internal sealed class EnumSerializerSByte : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override sbyte Read(ref ProtoReader.State state) { return state.ReadSByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, sbyte value) { state.WriteSByte(value); } public override int MeasureVarint(sbyte value) { if (value >= 0) { return ProtoWriter.MeasureUInt32((uint)value); } return 10; } public override int MeasureSignedVarint(sbyte value) { return ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value)); } } internal sealed class EnumSerializerInt16 : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override short Read(ref ProtoReader.State state) { return state.ReadInt16(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, short value) { state.WriteInt16(value); } public override int MeasureVarint(short value) { if (value >= 0) { return ProtoWriter.MeasureUInt32((uint)value); } return 10; } public override int MeasureSignedVarint(short value) { return ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value)); } } internal sealed class EnumSerializerInt32 : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override int Read(ref ProtoReader.State state) { return state.ReadInt32(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, int value) { state.WriteInt32(value); } public override int MeasureVarint(int value) { if (value >= 0) { return ProtoWriter.MeasureUInt32((uint)value); } return 10; } public override int MeasureSignedVarint(int value) { return ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value)); } } internal sealed class EnumSerializerInt64 : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override long Read(ref ProtoReader.State state) { return state.ReadInt64(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, long value) { state.WriteInt64(value); } public override int MeasureVarint(long value) { return ProtoWriter.MeasureUInt64((ulong)value); } public override int MeasureSignedVarint(long value) { return ProtoWriter.MeasureUInt64(ProtoWriter.Zig(value)); } } internal sealed class EnumSerializerByte : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override byte Read(ref ProtoReader.State state) { return state.ReadByte(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, byte value) { state.WriteByte(value); } public override int MeasureVarint(byte value) { return ProtoWriter.MeasureUInt32(value); } } internal sealed class EnumSerializerUInt16 : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override ushort Read(ref ProtoReader.State state) { return state.ReadUInt16(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, ushort value) { state.WriteUInt16(value); } public override int MeasureVarint(ushort value) { return ProtoWriter.MeasureUInt32(value); } } internal sealed class EnumSerializerUInt32 : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override uint Read(ref ProtoReader.State state) { return state.ReadUInt32(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, uint value) { state.WriteUInt32(value); } public override int MeasureVarint(uint value) { return ProtoWriter.MeasureUInt32(value); } } internal sealed class EnumSerializerUInt64 : EnumSerializer where T : unmanaged { [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override ulong Read(ref ProtoReader.State state) { return state.ReadUInt64(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override void Write(ref ProtoWriter.State state, ulong value) { state.WriteUInt64(value); } public override int MeasureVarint(ulong value) { return ProtoWriter.MeasureUInt64(value); } } public interface IMemoryConverter { TStorage NonNull(in TStorage value); int GetLength(in TStorage value); Memory GetMemory(in TStorage value); Memory Expand(ISerializationContext context, ref TStorage value, int additionalCapacity); } public sealed class DefaultMemoryConverter : IMemoryConverter, IMemoryConverter, T>, IMemoryConverter, T>, IMemoryConverter, T> { public static DefaultMemoryConverter Instance { get; } = new DefaultMemoryConverter(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static IMemoryConverter GetFor(TypeModel model) { return (model?.GetSerializerCore(CompatibilityLevel.NotSpecified) as IMemoryConverter) ?? (Instance as IMemoryConverter) ?? NotSupported(); } [MethodImpl(MethodImplOptions.NoInlining)] private static IMemoryConverter NotSupported() { ThrowHelper.ThrowInvalidOperationException("No memory-converter is available for storage " + typeof(TStorage).NormalizeName() + " with element-type " + typeof(T).NormalizeName() + "."); return null; } private DefaultMemoryConverter() { } T[] IMemoryConverter.NonNull(in T[] value) { return value ?? Array.Empty(); } int IMemoryConverter.GetLength(in T[] value) { if (value != null) { return value.Length; } return 0; } Memory IMemoryConverter.GetMemory(in T[] value) { return new Memory(value); } Memory IMemoryConverter.Expand(ISerializationContext context, ref T[] value, int additionalCapacity) { int num = ((value != null) ? value.Length : 0); Array.Resize(ref value, num + additionalCapacity); return new Memory(value, num, additionalCapacity); } ArraySegment IMemoryConverter, T>.NonNull(in ArraySegment value) { return value; } int IMemoryConverter, T>.GetLength(in ArraySegment value) { return value.Count; } Memory IMemoryConverter, T>.GetMemory(in ArraySegment value) { return new Memory(value.Array, value.Offset, value.Count); } Memory IMemoryConverter, T>.Expand(ISerializationContext context, ref ArraySegment value, int additionalCapacity) { int count = value.Count; T[] array = new T[count + additionalCapacity]; if (count != 0) { Array.Copy(value.Array, value.Offset, array, 0, count); } value = new ArraySegment(array); return new Memory(array, count, additionalCapacity); } Memory IMemoryConverter, T>.NonNull(in Memory value) { return value; } int IMemoryConverter, T>.GetLength(in Memory value) { return value.Length; } Memory IMemoryConverter, T>.GetMemory(in Memory value) { return value; } Memory IMemoryConverter, T>.Expand(ISerializationContext context, ref Memory value, int additionalCapacity) { Memory memory = value; value = new T[memory.Length + additionalCapacity]; memory.CopyTo(value); return value.Slice(memory.Length); } ReadOnlyMemory IMemoryConverter, T>.NonNull(in ReadOnlyMemory value) { return value; } int IMemoryConverter, T>.GetLength(in ReadOnlyMemory value) { return value.Length; } Memory IMemoryConverter, T>.GetMemory(in ReadOnlyMemory value) { return MemoryMarshal.AsMemory(value); } Memory IMemoryConverter, T>.Expand(ISerializationContext context, ref ReadOnlyMemory value, int additionalCapacity) { int length = value.Length; Memory memory = new T[length + additionalCapacity]; value.CopyTo(memory); value = memory; return memory.Slice(length); } } [Flags] public enum SerializerFeatures { WireTypeVarint = 0x10, WireTypeFixed64 = 0x11, WireTypeString = 0x12, WireTypeStartGroup = 0x13, WireTypeFixed32 = 0x15, WireTypeSignedVarint = 0x18, WireTypeSpecified = 0x10, CategoryRepeated = 0, CategoryScalar = 0x20, CategoryMessage = 0x40, CategoryMessageWrappedAtRoot = 0x60, OptionPackedDisabled = 0x80, OptionClearCollection = 0x100, OptionFailOnDuplicateKey = 0x200, OptionSkipRecursionCheck = 0x400, OptionWrappedValue = 0x800, OptionWrappedValueGroup = 0x1000, OptionWrappedValueFieldPresence = 0x2000, OptionWrappedCollection = 0x4000, OptionWrappedCollectionGroup = 0x8000 } internal static class SerializerFeaturesExtensions { private const SerializerFeatures CategoryMask = SerializerFeatures.CategoryMessageWrappedAtRoot; private const SerializerFeatures WireTypeMask = (SerializerFeatures)15; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SerializerFeatures AsFeatures(this WireType wireType) { if (wireType != WireType.None) { return (SerializerFeatures)((wireType & (WireType)15) | (WireType)16); } return SerializerFeatures.CategoryRepeated; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SerializerFeatures GetCategory(this SerializerFeatures features) { return features & SerializerFeatures.CategoryMessageWrappedAtRoot; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InheritFrom(this ref SerializerFeatures features, SerializerFeatures overrides) { if ((features & SerializerFeatures.CategoryMessageWrappedAtRoot) == 0) { features |= overrides & SerializerFeatures.CategoryMessageWrappedAtRoot; } if ((features & SerializerFeatures.WireTypeVarint) == 0) { features |= overrides & (SerializerFeatures)31; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void HintIfNeeded(this SerializerFeatures features, ref ProtoReader.State state) { if ((features & (SerializerFeatures)15) == (SerializerFeatures)8) { state.Hint(WireType.SignedVariant); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidCategory(this SerializerFeatures features) { SerializerFeatures category = features.GetCategory(); string message = ((category == features) ? $"The category {category} is not expected in this context" : $"The category {category} is not expected in this context (full features: {features})"); ThrowHelper.ThrowInvalidOperationException(message); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsPackedDisabled(this SerializerFeatures features) { return (features & (SerializerFeatures.OptionPackedDisabled | SerializerFeatures.OptionWrappedValue)) != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsScalar(this SerializerFeatures features) { return features.GetCategory() == SerializerFeatures.CategoryScalar; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsRepeated(this SerializerFeatures features) { return (features & SerializerFeatures.CategoryMessageWrappedAtRoot) == 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsGroup(this SerializerFeatures features) { return (features & (SerializerFeatures)31) == SerializerFeatures.WireTypeStartGroup; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasAny(this SerializerFeatures features, SerializerFeatures values) { return (features & values) != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T DefaultFor(this SerializerFeatures features) { if (!features.HasAny(SerializerFeatures.OptionWrappedValue)) { return TypeHelper.Default; } return default(T); } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowWireTypeNotSpecified() { ThrowHelper.ThrowInvalidOperationException("The serializer features provided do not include a wire-type"); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static WireType GetWireType(this SerializerFeatures features) { if ((features & SerializerFeatures.WireTypeVarint) == 0) { ThrowWireTypeNotSpecified(); } return (WireType)(features & (SerializerFeatures)15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ApplyRecursionCheck(this SerializerFeatures features) { return (features & SerializerFeatures.OptionSkipRecursionCheck) == 0; } } public interface ISerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> { SerializerFeatures Features { get; } T Read(ref ProtoReader.State state, T value); void Write(ref ProtoWriter.State state, T value); } public interface ISerializerProxy<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> { ISerializer Serializer { get; } } internal interface IMeasuringSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> : ISerializer { int Measure(ISerializationContext context, WireType wireType, T value); } public interface IRepeatedSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> : ISerializer { void WriteRepeated(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures features, T values); T ReadRepeated(ref ProtoReader.State state, SerializerFeatures features, T values); } [Obsolete("This API is deprecated and is never used; it will be removed soon", true)] public interface IObjectSerializer : ISerializer { Type BaseType { get; } } public interface ISubTypeSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> where T : class { void WriteSubType(ref ProtoWriter.State state, T value); T ReadSubType(ref ProtoReader.State state, SubTypeState value); } [StructLayout(LayoutKind.Auto)] public struct SubTypeState<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> where T : class { private readonly ISerializationContext _context; private readonly Func _ctor; private object _value; private Action _onBeforeDeserialize; public T Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return (_value as T) ?? Cast(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { _value = value; } } internal readonly object RawValue => _value; public readonly bool HasValue => _value != null; public static SubTypeState Create(ISerializationContext context, TValue value) where TValue : class, T { return new SubTypeState(context, TypeHelper.Factory, value, null); } private SubTypeState(ISerializationContext context, Func ctor, object value, Action onBeforeDeserialize) { _context = context; _ctor = ctor; _value = value; _onBeforeDeserialize = onBeforeDeserialize; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void CreateIfNeeded() { _ = Value; } [MethodImpl(MethodImplOptions.NoInlining)] private T Cast() { T val = ((_ctor as Func) ?? TypeHelper.Factory)(_context); if (_value != null) { val = Merge(_context, _value, val); } _onBeforeDeserialize?.Invoke(val, _context); _value = val; return val; static T Merge(ISerializationContext context, object value, T typed) { using MemoryStream memoryStream = new MemoryStream(); context.Model.Serialize(memoryStream, value, context.UserState); memoryStream.Position = 0L; return context.Model.Deserialize(memoryStream, typed, context.UserState); } } public void ReadSubType(ref ProtoReader.State state, ISubTypeSerializer serializer = null) where TSubType : class, T { SubItemToken token = state.StartSubItem(); _value = (serializer ?? TypeModel.GetSubTypeSerializer(_context.Model)).ReadSubType(ref state, new SubTypeState(_context, _ctor, _value, _onBeforeDeserialize)); state.EndSubItem(token); } public void OnBeforeDeserialize(Action callback) { if (callback != null) { if (_value is T arg) { callback(arg, _context); } else if (_onBeforeDeserialize != null) { ThrowHelper.ThrowInvalidOperationException("Only one pending OnBeforeDeserialize callback is supported"); } else { _onBeforeDeserialize = callback; } } } } public interface IFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> { T Create(ISerializationContext context); } public static class MapSerializer { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer CreateConcurrentDictionary() where TCollection : ConcurrentDictionary { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer, TKey, TValue> CreateDictionary<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TValue>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer CreateDictionary() where TCollection : IDictionary { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer, TKey, TValue> CreateIReadOnlyDictionary<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TValue>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer, TKey, TValue> CreateImmutableDictionary<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TValue>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer, TKey, TValue> CreateImmutableSortedDictionary<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TValue>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MapSerializer, TKey, TValue> CreateIImmutableDictionary<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TValue>() { return SerializerCache>.InstanceField; } } internal sealed class ConcurrentDictionarySerializer : MapSerializer where TCollection : ConcurrentDictionary { protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override TCollection Initialize(TCollection values, ISerializationContext context) { return values ?? TypeModel.ActivatorCreate(); } protected override TCollection AddRange(TCollection values, ref ArraySegment> newValues, ISerializationContext context) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; if (!values.TryAdd(keyValuePair.Key, keyValuePair.Value)) { ThrowHelper.ThrowArgumentException("duplicate key"); } } return values; } protected override TCollection SetValues(TCollection values, ref ArraySegment> newValues, ISerializationContext context) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; values[keyValuePair.Key] = keyValuePair.Value; } return values; } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, TCollection values, in KeyValuePairSerializer pairSerializer) { IEnumerator> enumerator = values.GetEnumerator(); try { MapSerializer.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } finally { enumerator?.Dispose(); } } } public abstract class MapSerializer : IRepeatedSerializer, ISerializer, IFactory { SerializerFeatures ISerializer.Features => SerializerFeatures.CategoryRepeated; TCollection IFactory.Create(ISerializationContext context) { return Initialize(default(TCollection), context); } TCollection ISerializer.Read(ref ProtoReader.State state, TCollection value) { ThrowHelper.ThrowInvalidOperationException("Should have used ReadRepeated"); return default(TCollection); } void ISerializer.Write(ref ProtoWriter.State state, TCollection value) { ThrowHelper.ThrowInvalidOperationException("Should have used WriteRepeated"); } void IRepeatedSerializer.WriteRepeated(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures features, TCollection values) { WriteMap(ref state, fieldNumber, features, values, SerializerFeatures.CategoryRepeated, SerializerFeatures.CategoryRepeated); } TCollection IRepeatedSerializer.ReadRepeated(ref ProtoReader.State state, SerializerFeatures features, TCollection values) { return ReadMap(ref state, features, values, SerializerFeatures.CategoryRepeated, SerializerFeatures.CategoryRepeated); } private static KeyValuePairSerializer GetSerializer(TypeModel model, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { if (keySerializer == null) { keySerializer = TypeModel.GetSerializer(model); } if (valueSerializer == null) { valueSerializer = TypeModel.GetSerializer(model); } keyFeatures.InheritFrom(keySerializer.Features); valueFeatures.InheritFrom(valueSerializer.Features); return new KeyValuePairSerializer(keySerializer, keyFeatures, valueSerializer, valueFeatures); } public void WriteMap(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures features, TCollection values, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer = null, ISerializer valueSerializer = null) { if (features.HasAny(SerializerFeatures.OptionWrappedCollection)) { WriteNullWrapped(ref state, features, fieldNumber, values, keyFeatures, valueFeatures, keySerializer, valueSerializer); return; } KeyValuePairSerializer pairSerializer = GetSerializer(state.Model, keyFeatures, valueFeatures, keySerializer, valueSerializer); features.InheritFrom(pairSerializer.Features); WireType wireType = features.GetWireType(); Write(ref state, fieldNumber, wireType, values, in pairSerializer); } private void WriteNullWrapped(ref ProtoWriter.State state, SerializerFeatures features, int fieldNumber, TCollection values, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { state.WriteFieldHeader(fieldNumber, ProtoWriter.State.AssertWrappedAndGetWireType(ref features, out var _)); state.GetWriter().WriteWrappedMap(ref state, features, values, this, keyFeatures, valueFeatures, keySerializer, valueSerializer); } internal abstract void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, TCollection values, in KeyValuePairSerializer pairSerializer); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, ref TEnumerator enumerator, in KeyValuePairSerializer pairSerializer) where TEnumerator : IEnumerator> { if (enumerator.MoveNext()) { ISerializer> serializer = pairSerializer; do { state.WriteFieldHeader(fieldNumber, wireType); state.GetWriter().WriteMessage(ref state, enumerator.Current, serializer, PrefixStyle.Base128, recursionCheck: false); } while (enumerator.MoveNext()); } } protected virtual TCollection Initialize(TCollection values, ISerializationContext context) { return values; } protected abstract TCollection Clear(TCollection values, ISerializationContext context); protected abstract TCollection AddRange(TCollection values, ref ArraySegment> newValues, ISerializationContext context); protected abstract TCollection SetValues(TCollection values, ref ArraySegment> newValues, ISerializationContext context); public TCollection ReadMap(ref ProtoReader.State state, SerializerFeatures features, TCollection values, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer = null, ISerializer valueSerializer = null) { if (features.HasAny(SerializerFeatures.OptionWrappedCollection)) { return ReadNullWrapped(ref state, features, values, keyFeatures, valueFeatures, keySerializer, valueSerializer); } ISerializationContext context = state.Context; KeyValuePairSerializer serializer = GetSerializer(state.Model, keyFeatures, valueFeatures, keySerializer, valueSerializer); features.InheritFrom(serializer.Features); values = Initialize(values, context); using ReadBuffer> readBuffer = state.FillBuffer(features, in serializer, new KeyValuePair(TypeHelper.Default, features.DefaultFor())); if ((features & SerializerFeatures.OptionClearCollection) != SerializerFeatures.CategoryRepeated) { values = Clear(values, context); } if (!readBuffer.IsEmpty) { ArraySegment> newValues = readBuffer.Segment; values = (((features & SerializerFeatures.OptionFailOnDuplicateKey) == 0) ? SetValues(values, ref newValues, context) : AddRange(values, ref newValues, context)); } return values; } private TCollection ReadNullWrapped(ref ProtoReader.State state, SerializerFeatures features, TCollection values, SerializerFeatures keyFeatures, SerializerFeatures valueFeatures, ISerializer keySerializer, ISerializer valueSerializer) { features &= ~(SerializerFeatures.OptionWrappedCollection | SerializerFeatures.OptionWrappedCollectionGroup); SubItemToken token = state.StartSubItem(); bool flag = true; int num; while ((num = state.ReadFieldHeader()) > 0) { if (num == 1) { values = ReadMap(ref state, features, values, keyFeatures, valueFeatures, keySerializer, valueSerializer); flag = false; } else { state.SkipField(); } } state.EndSubItem(token); if (flag) { values = Initialize(values, state.Context); } return values; } } internal sealed class DictionarySerializer : MapSerializer, TKey, TValue> { protected override Dictionary Initialize(Dictionary values, ISerializationContext context) { return values ?? new Dictionary(); } protected override Dictionary Clear(Dictionary values, ISerializationContext context) { values.Clear(); return values; } protected override Dictionary AddRange(Dictionary values, ref ArraySegment> newValues, ISerializationContext context) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; values.Add(keyValuePair.Key, keyValuePair.Value); } return values; } protected override Dictionary SetValues(Dictionary values, ref ArraySegment> newValues, ISerializationContext context) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; values[keyValuePair.Key] = keyValuePair.Value; } return values; } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, Dictionary values, in KeyValuePairSerializer pairSerializer) { Dictionary.Enumerator enumerator = values.GetEnumerator(); MapSerializer, TKey, TValue>.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } } internal class DictionarySerializer : MapSerializer where TCollection : IDictionary { protected override TCollection Initialize(TCollection values, ISerializationContext context) { if (values != null) { return values; } if (!typeof(TCollection).IsInterface) { return TypeModel.ActivatorCreate(); } return (TCollection)(object)new Dictionary(); } protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override TCollection AddRange(TCollection values, ref ArraySegment> newValues, ISerializationContext context) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; values.Add(keyValuePair.Key, keyValuePair.Value); } return values; } protected override TCollection SetValues(TCollection values, ref ArraySegment> newValues, ISerializationContext context) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; values[keyValuePair.Key] = keyValuePair.Value; } return values; } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, TCollection values, in KeyValuePairSerializer pairSerializer) { IEnumerator> enumerator = values.GetEnumerator(); try { MapSerializer.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } finally { enumerator?.Dispose(); } } } internal sealed class DictionaryOfIReadOnlyDictionarySerializer : MapSerializer, TKey, TValue> { protected override IReadOnlyDictionary Initialize(IReadOnlyDictionary values, ISerializationContext context) { return values ?? new Dictionary(); } protected override IReadOnlyDictionary Clear(IReadOnlyDictionary values, ISerializationContext context) { if (values is IDictionary { IsReadOnly: false } dictionary) { dictionary.Clear(); return values; } return new Dictionary(); } protected override IReadOnlyDictionary AddRange(IReadOnlyDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (values is IDictionary { IsReadOnly: false } dictionary) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; dictionary.Add(keyValuePair.Key, keyValuePair.Value); } return values; } Dictionary dictionary2 = new Dictionary(values.Count + newValues.Count); foreach (KeyValuePair value in values) { dictionary2.Add(value.Key, value.Value); } Span> span2 = newValues.AsSpan(); for (int j = 0; j < span2.Length; j++) { KeyValuePair keyValuePair2 = span2[j]; dictionary2.Add(keyValuePair2.Key, keyValuePair2.Value); } return dictionary2; } protected override IReadOnlyDictionary SetValues(IReadOnlyDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (values is IDictionary { IsReadOnly: false } dictionary) { Span> span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { KeyValuePair keyValuePair = span[i]; dictionary[keyValuePair.Key] = keyValuePair.Value; } return values; } Dictionary dictionary2 = new Dictionary(values.Count); foreach (KeyValuePair value in values) { dictionary2.Add(value.Key, value.Value); } Span> span2 = newValues.AsSpan(); for (int j = 0; j < span2.Length; j++) { KeyValuePair keyValuePair2 = span2[j]; dictionary2[keyValuePair2.Key] = keyValuePair2.Value; } return values; } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, IReadOnlyDictionary values, in KeyValuePairSerializer pairSerializer) { IEnumerator> enumerator = values.GetEnumerator(); MapSerializer, TKey, TValue>.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } } public abstract class ExternalMapSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TCollection, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TValue> : MapSerializer where TCollection : IEnumerable> { internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, TCollection values, in KeyValuePairSerializer pairSerializer) { IEnumerator> enumerator = values.GetEnumerator(); MapSerializer.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } } internal sealed class ImmutableDictionarySerializer : MapSerializer, TKey, TValue> { protected override ImmutableDictionary Clear(ImmutableDictionary values, ISerializationContext context) { return values.Clear(); } protected override ImmutableDictionary Initialize(ImmutableDictionary values, ISerializationContext context) { return values ?? ImmutableDictionary.Empty; } protected override ImmutableDictionary AddRange(ImmutableDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (newValues.Count == 1) { KeyValuePair keyValuePair = RepeatedSerializer.Singleton(ref newValues); return values.Add(keyValuePair.Key, keyValuePair.Value); } return values.AddRange(newValues); } protected override ImmutableDictionary SetValues(ImmutableDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (newValues.Count == 1) { KeyValuePair keyValuePair = RepeatedSerializer.Singleton(ref newValues); return values.SetItem(keyValuePair.Key, keyValuePair.Value); } return values.SetItems(newValues); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, ImmutableDictionary values, in KeyValuePairSerializer pairSerializer) { ImmutableDictionary.Enumerator enumerator = values.GetEnumerator(); MapSerializer, TKey, TValue>.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } } internal sealed class ImmutableSortedDictionarySerializer : MapSerializer, TKey, TValue> { protected override ImmutableSortedDictionary Clear(ImmutableSortedDictionary values, ISerializationContext context) { return values.Clear(); } protected override ImmutableSortedDictionary Initialize(ImmutableSortedDictionary values, ISerializationContext context) { return values ?? ImmutableSortedDictionary.Empty; } protected override ImmutableSortedDictionary AddRange(ImmutableSortedDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (newValues.Count == 1) { KeyValuePair keyValuePair = RepeatedSerializer.Singleton(ref newValues); return values.Add(keyValuePair.Key, keyValuePair.Value); } return values.AddRange(newValues); } protected override ImmutableSortedDictionary SetValues(ImmutableSortedDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (newValues.Count == 1) { KeyValuePair keyValuePair = RepeatedSerializer.Singleton(ref newValues); return values.SetItem(keyValuePair.Key, keyValuePair.Value); } return values.SetItems(newValues); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, ImmutableSortedDictionary values, in KeyValuePairSerializer pairSerializer) { ImmutableSortedDictionary.Enumerator enumerator = values.GetEnumerator(); MapSerializer, TKey, TValue>.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } } internal sealed class ImmutableIDictionarySerializer : MapSerializer, TKey, TValue> { protected override IImmutableDictionary Clear(IImmutableDictionary values, ISerializationContext context) { return values.Clear(); } protected override IImmutableDictionary Initialize(IImmutableDictionary values, ISerializationContext context) { return values ?? ImmutableDictionary.Empty; } protected override IImmutableDictionary AddRange(IImmutableDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (newValues.Count == 1) { KeyValuePair keyValuePair = RepeatedSerializer.Singleton(ref newValues); return values.Add(keyValuePair.Key, keyValuePair.Value); } return values.AddRange(newValues); } protected override IImmutableDictionary SetValues(IImmutableDictionary values, ref ArraySegment> newValues, ISerializationContext context) { if (newValues.Count == 1) { KeyValuePair keyValuePair = RepeatedSerializer.Singleton(ref newValues); return values.SetItem(keyValuePair.Key, keyValuePair.Value); } return values.SetItems(newValues); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, WireType wireType, IImmutableDictionary values, in KeyValuePairSerializer pairSerializer) { IEnumerator> enumerator = values.GetEnumerator(); try { MapSerializer, TKey, TValue>.Write(ref state, fieldNumber, wireType, ref enumerator, in pairSerializer); } finally { enumerator?.Dispose(); } } } public static class RepeatedSerializer { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateConcurrentBag() where TCollection : ConcurrentBag { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateConcurrentStack() where TCollection : ConcurrentStack { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateConcurrentQueue() where TCollection : ConcurrentQueue { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateIProducerConsumerCollection() where TCollection : class, IProducerConsumerCollection { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.NoInlining)] [Obsolete("Since this isn't supported, you probably shouldn't be doing it...", false)] public static RepeatedSerializer CreateNestedDataNotSupported() { ThrowHelper.ThrowNestedDataNotSupported(typeof(TCollection)); return null; } [MethodImpl(MethodImplOptions.NoInlining)] [Obsolete("Since this isn't supported, you probably shouldn't be doing it...", false)] public static RepeatedSerializer CreateNotSupported() { ThrowHelper.ThrowNotSupportedException($"Repeated data of type {typeof(TCollection)} is not supported"); return null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateList() where TList : List { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateEnumerable() where TCollection : class, IEnumerable { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateEnumerable() where TCollection : class, IEnumerable where TCreate : TCollection { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateVector<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateQueue() where TCollection : Queue { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateStack() where TCollection : Stack { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer CreateSet() where TCollection : ISet { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ReverseInPlace(this ref ArraySegment values) { Array.Reverse(values.Array, values.Offset, values.Count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static ref T Singleton(this ref ArraySegment values) { return ref values.Array[values.Offset]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableArray<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableIList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableQueue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableIQueue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableStack<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableIStack<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableHashSet<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableSortedSet<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RepeatedSerializer, T> CreateImmutableISet<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache>.InstanceField; } } internal class ProducerConsumerSerializer : RepeatedSerializer where TCollection : class, IProducerConsumerCollection { protected override TCollection Clear(TCollection values, ISerializationContext context) { if (values.Count != 0) { if (values is ICollection collection) { collection.Clear(); } else { ThrowHelper.ThrowInvalidOperationException("Unable to clear the collection: " + values.GetType().NormalizeName()); } } return values; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T item = span[i]; if (!values.TryAdd(item)) { ThrowHelper.ThrowInvalidOperationException("Unable to add to the collection: " + values.GetType().NormalizeName()); } } return values; } protected override TCollection Initialize(TCollection values, ISerializationContext context) { return values ?? TypeModel.ActivatorCreate(); } protected override int TryGetCount(TCollection values) { return TryGetCountDefault(values); } internal override long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } } internal sealed class ConcurrentBagSerializer : ProducerConsumerSerializer where TCollection : ConcurrentBag { protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T item = span[i]; values.Add(item); } return values; } } internal sealed class ConcurrentQueueSerializer : ProducerConsumerSerializer where TCollection : ConcurrentQueue { protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T item = span[i]; values.Enqueue(item); } return values; } } internal sealed class ConcurrentStackSerializer : ProducerConsumerSerializer where TCollection : ConcurrentStack { protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { RepeatedSerializer.ReverseInPlace(ref newValues); values.PushRange(newValues.Array, newValues.Offset, newValues.Count); return values; } } public abstract class RepeatedSerializer : IRepeatedSerializer, ISerializer, IFactory { SerializerFeatures ISerializer.Features => SerializerFeatures.CategoryRepeated; TCollection IFactory.Create(ISerializationContext context) { return Initialize(default(TCollection), context); } void IRepeatedSerializer.WriteRepeated(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures features, TCollection values) { WriteRepeated(ref state, fieldNumber, features, values); } TCollection IRepeatedSerializer.ReadRepeated(ref ProtoReader.State state, SerializerFeatures features, TCollection values) { return ReadRepeated(ref state, features, values); } TCollection ISerializer.Read(ref ProtoReader.State state, TCollection value) { ThrowHelper.ThrowInvalidOperationException("Should have used ReadRepeated"); return default(TCollection); } void ISerializer.Write(ref ProtoWriter.State state, TCollection value) { ThrowHelper.ThrowInvalidOperationException("Should have used WriteRepeated"); } private void WriteNullWrapped(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures features, TCollection values, ISerializer serializer) { if (!TypeHelper.CanBeNull || !TypeHelper.ValueChecker.IsNull(values)) { state.WriteFieldHeader(fieldNumber, ProtoWriter.State.AssertWrappedAndGetWireType(ref features, out var _)); state.GetWriter().WriteWrappedCollection(ref state, features, values, this, serializer); } } public void WriteRepeated(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures features, TCollection values, ISerializer serializer = null) { if (features.HasAny(SerializerFeatures.OptionWrappedCollection)) { WriteNullWrapped(ref state, fieldNumber, features, values, serializer); return; } if (serializer == null) { serializer = TypeModel.GetSerializer(state.Model); } SerializerFeatures features2 = serializer.Features; if (features2.IsRepeated()) { TypeModel.ThrowNestedListsNotSupported(typeof(TItem)); } features.InheritFrom(features2); int num = TryGetCount(values); SerializerFeatures category = features2.GetCategory(); WireType wireType = features.GetWireType(); if (TypeHelper.CanBePacked && !features.IsPackedDisabled() && (num == 0 || num > 1) && serializer is IMeasuringSerializer serializer2) { if (category != SerializerFeatures.CategoryScalar) { features2.ThrowInvalidCategory(); } if (num == 0) { WriteZeroLengthPackedHeader(ref state, fieldNumber); } else { WritePacked(ref state, fieldNumber, wireType, values, num, serializer2); } } else if (num != 0) { Write(ref state, fieldNumber, category, wireType, values, serializer, features); } } private static void WriteZeroLengthPackedHeader(ref ProtoWriter.State state, int fieldNumber) { if (state.Model.OmitsOption(TypeModel.TypeModelOptions.SkipZeroLengthPackedArrays)) { state.WriteFieldHeader(fieldNumber, WireType.String); ProtoWriter writer = state.GetWriter(); writer.AdvanceAndReset(writer.ImplWriteVarint64(ref state, 0uL)); } } internal abstract void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ref TEnumerator values, ISerializer serializer, SerializerFeatures features) where TEnumerator : IEnumerator { ProtoWriter writer = state.GetWriter(); bool flag = features.HasAny(SerializerFeatures.OptionWrappedValue); if (flag) { features |= SerializerFeatures.OptionWrappedValueFieldPresence; } while (values.MoveNext()) { TItem current = values.Current; if (flag) { state.WriteWrapped(fieldNumber, features, current, serializer); continue; } if (TypeHelper.CanBeNull && TypeHelper.ValueChecker.IsNull(current)) { ThrowHelper.ThrowNullRepeatedContents(); } state.WriteFieldHeader(fieldNumber, wireType); switch (category) { case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: writer.WriteMessage(ref state, current, serializer, PrefixStyle.Base128, recursionCheck: true); break; case SerializerFeatures.CategoryScalar: serializer.Write(ref state, current); break; default: category.ThrowInvalidCategory(); break; } } } internal abstract long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long Measure(ref TEnumerator values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) where TEnumerator : IEnumerator { long num = 0L; while (values.MoveNext()) { num += serializer.Measure(context, wireType, values.Current); } return num; } internal abstract void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void WritePacked(ref ProtoWriter.State state, ref TEnumerator values, IMeasuringSerializer serializer, WireType wireType) where TEnumerator : IEnumerator { while (values.MoveNext()) { TItem current = values.Current; state.WireType = wireType; serializer.Write(ref state, current); } } private void WritePacked(ref ProtoWriter.State state, int fieldNumber, WireType wireType, TCollection values, int count, IMeasuringSerializer serializer) { long num; switch (wireType) { case WireType.Fixed32: num = count * 4; break; case WireType.Fixed64: num = count * 8; break; case WireType.Variant: case WireType.SignedVariant: num = Measure(values, serializer, state.Context, wireType); break; default: ThrowHelper.ThrowInvalidPackedOperationException(wireType, typeof(TItem)); num = 0L; break; } state.WriteFieldHeader(fieldNumber, WireType.String); ProtoWriter writer = state.GetWriter(); writer.AdvanceAndReset(writer.ImplWriteVarint64(ref state, (ulong)num)); long position = state.GetPosition(); WritePacked(ref state, values, serializer, wireType); long num2 = state.GetPosition() - position; if (num2 != num) { ThrowHelper.ThrowInvalidOperationException($"packed encoding length miscalculation for {typeof(TItem).NormalizeName()}, {wireType}; expected {num}, got {num2}"); } } protected abstract int TryGetCount(TCollection values); protected int TryGetCountDefault(TCollection values) { try { return (values is IReadOnlyCollection readOnlyCollection) ? readOnlyCollection.Count : ((values is ICollection collection) ? collection.Count : ((values is ICollection collection2) ? collection2.Count : ((values != null) ? (-1) : 0))); } catch { return -1; } } private TCollection ReadNullWrapped(ref ProtoReader.State state, SerializerFeatures features, TCollection values, ISerializer serializer) { features &= ~(SerializerFeatures.OptionWrappedCollection | SerializerFeatures.OptionWrappedCollectionGroup); SubItemToken token = state.StartSubItem(); bool flag = true; int num; while ((num = state.ReadFieldHeader()) > 0) { if (num == 1) { values = ReadRepeated(ref state, features, values, serializer); flag = false; } else { state.SkipField(); } } state.EndSubItem(token); if (flag) { values = Initialize(values, state.Context); } return values; } public TCollection ReadRepeated(ref ProtoReader.State state, SerializerFeatures features, TCollection values, ISerializer serializer = null) { if (features.HasAny(SerializerFeatures.OptionWrappedCollection)) { return ReadNullWrapped(ref state, features, values, serializer); } if (serializer == null) { serializer = TypeModel.GetSerializer(state.Model); } SerializerFeatures features2 = serializer.Features; if (features2.IsRepeated()) { TypeModel.ThrowNestedListsNotSupported(typeof(TItem)); } features.InheritFrom(features2); if (features.HasAny(SerializerFeatures.OptionWrappedValue)) { features |= SerializerFeatures.OptionWrappedValueFieldPresence; } ISerializationContext context = state.Context; values = Initialize(values, context); using ReadBuffer readBuffer = state.FillBuffer(features, in serializer, features.DefaultFor()); if ((features & SerializerFeatures.OptionClearCollection) != SerializerFeatures.CategoryRepeated) { values = Clear(values, context); } if (readBuffer.IsEmpty) { return values; } ArraySegment newValues = readBuffer.Segment; return AddRange(values, ref newValues, context); } protected virtual TCollection Initialize(TCollection values, ISerializationContext context) { return values; } protected abstract TCollection Clear(TCollection values, ISerializationContext context); protected abstract TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context); } internal sealed class StackSerializer : RepeatedSerializer where TCollection : Stack { protected override TCollection Initialize(TCollection values, ISerializationContext context) { return values ?? TypeModel.ActivatorCreate(); } protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override int TryGetCount(TCollection values) { return values?.Count ?? 0; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { RepeatedSerializer.ReverseInPlace(ref newValues); Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T item = span[i]; values.Push(item); } return values; } internal override long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { Stack.Enumerator values2 = values.GetEnumerator(); return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } internal override void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType) { Stack.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features) { Stack.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } } internal sealed class ListSerializer : ListSerializer, T> { protected override List Initialize(List values, ISerializationContext context) { return values ?? new List(); } } internal class ListSerializer : RepeatedSerializer where TList : List { protected override TList Initialize(TList values, ISerializationContext context) { return values ?? TypeModel.ActivatorCreate(); } protected override TList Clear(TList values, ISerializationContext context) { values.Clear(); return values; } protected override TList AddRange(TList values, ref ArraySegment newValues, ISerializationContext context) { values.AddRange(newValues); return values; } protected override int TryGetCount(TList values) { return values?.Count ?? 0; } internal override long Measure(TList values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { List.Enumerator values2 = values.GetEnumerator(); return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } internal override void WritePacked(ref ProtoWriter.State state, TList values, IMeasuringSerializer serializer, WireType wireType) { List.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TList values, ISerializer serializer, SerializerFeatures features) { List.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } } internal class EnumerableSerializer : RepeatedSerializer where TCollection : class, IEnumerable where TCreate : TCollection { protected override TCollection Initialize(TCollection values, ISerializationContext context) { object obj = values; if (obj == null) { if (!typeof(TCreate).IsInterface) { return (TCollection)(object)TypeModel.ActivatorCreate(); } obj = (TCollection)(object)new List(); } return (TCollection)obj; } protected override int TryGetCount(TCollection values) { return TryGetCountDefault(values); } internal override long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } private static void ThrowInvalidCollectionType(object collection) { ThrowHelper.ThrowInvalidOperationException("For repeated data declared as " + typeof(TCollection).NormalizeName() + ", the *underlying* collection (" + collection?.GetType().NormalizeName() + ") must implement ICollection and must not declare itself read-only; alternative (more exotic) collections can be used, but must be declared using their well-known form (for example, a member could be declared as ImmutableHashSet)"); } protected override TCollection Clear(TCollection values, ISerializationContext context) { if (values is ICollection { IsReadOnly: false } collection) { collection.Clear(); } else if (typeof(TCollection) == typeof(IEnumerable)) { values = Initialize(null, context); } else { ThrowInvalidCollectionType(values); } return values; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { if (!(values is List list)) { if (values is ICollection { IsReadOnly: false } collection) { Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T item = span[i]; collection.Add(item); } } else { ThrowInvalidCollectionType(values); } } else { list.AddRange(newValues); } return values; } } internal sealed class VectorSerializer : RepeatedSerializer { [StructLayout(LayoutKind.Auto)] private struct Enumerator : IEnumerator, IEnumerator, IDisposable { private readonly T[] _array; private int _index; public readonly T Current => _array[_index]; readonly object IEnumerator.Current => _array[_index]; public readonly void Reset() { ThrowHelper.ThrowNotSupportedException(); } public Enumerator(T[] array) { _array = array; _index = -1; } public bool MoveNext() { return ++_index < _array.Length; } public readonly void Dispose() { } } protected override T[] Initialize(T[] values, ISerializationContext context) { return values ?? Array.Empty(); } protected override T[] Clear(T[] values, ISerializationContext context) { return Array.Empty(); } protected override T[] AddRange(T[] values, ref ArraySegment newValues, ISerializationContext context) { T[] array = new T[values.Length + newValues.Count]; Array.Copy(values, 0, array, 0, values.Length); Array.Copy(newValues.Array, newValues.Offset, array, values.Length, newValues.Count); return array; } protected override int TryGetCount(T[] values) { if (values != null) { return values.Length; } return 0; } internal override long Measure(T[] values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { Enumerator values2 = new Enumerator(values); return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } internal override void WritePacked(ref ProtoWriter.State state, T[] values, IMeasuringSerializer serializer, WireType wireType) { Enumerator values2 = new Enumerator(values); RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, T[] values, ISerializer serializer, SerializerFeatures features) { Enumerator values2 = new Enumerator(values); RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } } internal sealed class QueueSerializer : RepeatedSerializer where TCollection : Queue { protected override TCollection Initialize(TCollection values, ISerializationContext context) { return values ?? TypeModel.ActivatorCreate(); } protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override int TryGetCount(TCollection values) { return values?.Count ?? 0; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T item = span[i]; values.Enqueue(item); } return values; } internal override long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { Queue.Enumerator values2 = values.GetEnumerator(); return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } internal override void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType) { Queue.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features) { Queue.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } } internal sealed class SetSerializer : RepeatedSerializer where TCollection : ISet { protected override TCollection Initialize(TCollection values, ISerializationContext context) { if (values != null) { return values; } if (!typeof(TCollection).IsInterface) { return TypeModel.ActivatorCreate(); } return (TCollection)(object)new HashSet(); } protected override TCollection Clear(TCollection values, ISerializationContext context) { values.Clear(); return values; } protected override int TryGetCount(TCollection values) { return values?.Count ?? 0; } protected override TCollection AddRange(TCollection values, ref ArraySegment newValues, ISerializationContext context) { values.UnionWith(newValues); return values; } internal override long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } internal override void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } } public abstract class ExternalSerializer : RepeatedSerializer where TCollection : IEnumerable { internal override long Measure(TCollection values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = null; try { values2 = values.GetEnumerator(); return RepeatedSerializer.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, TCollection values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = null; try { values2 = values.GetEnumerator(); RepeatedSerializer.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = null; try { values2 = values.GetEnumerator(); RepeatedSerializer.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } } internal sealed class ImmutableArraySerializer : RepeatedSerializer, T> { [StructLayout(LayoutKind.Auto)] private struct Enumerator : IEnumerator, IEnumerator, IDisposable { private ImmutableArray.Enumerator _iter; public T Current => _iter.Current; object IEnumerator.Current => _iter.Current; public readonly void Reset() { ThrowHelper.ThrowNotSupportedException(); } public Enumerator(ImmutableArray array) { _iter = array.GetEnumerator(); } public bool MoveNext() { return _iter.MoveNext(); } public readonly void Dispose() { } } protected override ImmutableArray Initialize(ImmutableArray values, ISerializationContext context) { if (!values.IsDefault) { return values; } return ImmutableArray.Empty; } protected override ImmutableArray Clear(ImmutableArray values, ISerializationContext context) { return values.Clear(); } protected override ImmutableArray AddRange(ImmutableArray values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count != 1) { return values.AddRange(new ReadOnlySpan(newValues.Array, newValues.Offset, newValues.Count)); } return values.Add(RepeatedSerializer.Singleton(ref newValues)); } protected override int TryGetCount(ImmutableArray values) { if (!values.IsDefaultOrEmpty) { return values.Length; } return 0; } internal override long Measure(ImmutableArray values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { Enumerator values2 = new Enumerator(values); return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } internal override void WritePacked(ref ProtoWriter.State state, ImmutableArray values, IMeasuringSerializer serializer, WireType wireType) { Enumerator values2 = new Enumerator(values); RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableArray values, ISerializer serializer, SerializerFeatures features) { Enumerator values2 = new Enumerator(values); RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } } internal sealed class ImmutableListSerializer : RepeatedSerializer, T> { protected override ImmutableList Initialize(ImmutableList values, ISerializationContext context) { return values ?? ImmutableList.Empty; } protected override ImmutableList AddRange(ImmutableList values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count != 1) { return values.AddRange(newValues); } return values.Add(RepeatedSerializer.Singleton(ref newValues)); } protected override ImmutableList Clear(ImmutableList values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(ImmutableList values) { return values?.Count ?? 0; } internal override long Measure(ImmutableList values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { ImmutableList.Enumerator values2 = values.GetEnumerator(); return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableList values, ISerializer serializer, SerializerFeatures features) { ImmutableList.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } internal override void WritePacked(ref ProtoWriter.State state, ImmutableList values, IMeasuringSerializer serializer, WireType wireType) { ImmutableList.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } } internal sealed class ImmutableIListSerializer : RepeatedSerializer, T> { protected override IImmutableList Initialize(IImmutableList values, ISerializationContext context) { return values ?? ImmutableList.Empty; } protected override IImmutableList AddRange(IImmutableList values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count != 1) { return values.AddRange(newValues); } return values.Add(RepeatedSerializer.Singleton(ref newValues)); } protected override IImmutableList Clear(IImmutableList values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(IImmutableList values) { return TryGetCountDefault(values); } internal override long Measure(IImmutableList values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, IImmutableList values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, IImmutableList values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } } internal sealed class ImmutableHashSetSerializer : RepeatedSerializer, T> { protected override ImmutableHashSet Initialize(ImmutableHashSet values, ISerializationContext context) { return values ?? ImmutableHashSet.Empty; } protected override ImmutableHashSet AddRange(ImmutableHashSet values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count != 1) { return values.Union(newValues); } return values.Add(RepeatedSerializer.Singleton(ref newValues)); } protected override ImmutableHashSet Clear(ImmutableHashSet values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(ImmutableHashSet values) { return values?.Count ?? 0; } internal override long Measure(ImmutableHashSet values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { ImmutableHashSet.Enumerator values2 = values.GetEnumerator(); return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableHashSet values, ISerializer serializer, SerializerFeatures features) { ImmutableHashSet.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } internal override void WritePacked(ref ProtoWriter.State state, ImmutableHashSet values, IMeasuringSerializer serializer, WireType wireType) { ImmutableHashSet.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } } internal sealed class ImmutableSortedSetSerializer : RepeatedSerializer, T> { protected override ImmutableSortedSet Initialize(ImmutableSortedSet values, ISerializationContext context) { return values ?? ImmutableSortedSet.Empty; } protected override ImmutableSortedSet AddRange(ImmutableSortedSet values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count != 1) { return values.Union(newValues); } return values.Add(RepeatedSerializer.Singleton(ref newValues)); } protected override ImmutableSortedSet Clear(ImmutableSortedSet values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(ImmutableSortedSet values) { return values?.Count ?? 0; } internal override long Measure(ImmutableSortedSet values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { ImmutableSortedSet.Enumerator values2 = values.GetEnumerator(); return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableSortedSet values, ISerializer serializer, SerializerFeatures features) { ImmutableSortedSet.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } internal override void WritePacked(ref ProtoWriter.State state, ImmutableSortedSet values, IMeasuringSerializer serializer, WireType wireType) { ImmutableSortedSet.Enumerator values2 = values.GetEnumerator(); RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } } internal sealed class ImmutableISetSerializer : RepeatedSerializer, T> { protected override IImmutableSet Initialize(IImmutableSet values, ISerializationContext context) { return values ?? ImmutableHashSet.Empty; } protected override IImmutableSet AddRange(IImmutableSet values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count != 1) { return values.Union(newValues); } return values.Add(RepeatedSerializer.Singleton(ref newValues)); } protected override IImmutableSet Clear(IImmutableSet values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(IImmutableSet values) { return TryGetCountDefault(values); } internal override long Measure(IImmutableSet values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, IImmutableSet values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, IImmutableSet values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } } internal sealed class ImmutableStackSerializer : RepeatedSerializer, T> { [StructLayout(LayoutKind.Auto)] private struct Enumerator : IEnumerator, IEnumerator, IDisposable { private ImmutableStack.Enumerator _iter; T IEnumerator.Current => _iter.Current; object IEnumerator.Current => _iter.Current; public Enumerator(ImmutableStack stack) { _iter = stack.GetEnumerator(); } readonly void IDisposable.Dispose() { } bool IEnumerator.MoveNext() { return _iter.MoveNext(); } readonly void IEnumerator.Reset() { ThrowHelper.ThrowNotImplementedException("Reset"); } } protected override ImmutableStack Initialize(ImmutableStack values, ISerializationContext context) { return values ?? ImmutableStack.Empty; } protected override ImmutableStack AddRange(ImmutableStack values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count == 1) { return values.Push(RepeatedSerializer.Singleton(ref newValues)); } RepeatedSerializer.ReverseInPlace(ref newValues); Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T value = span[i]; values = values.Push(value); } return values; } protected override ImmutableStack Clear(ImmutableStack values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(ImmutableStack values) { if (values != null && !values.IsEmpty) { return -1; } return 0; } internal override long Measure(ImmutableStack values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { Enumerator values2 = new Enumerator(values); return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableStack values, ISerializer serializer, SerializerFeatures features) { Enumerator values2 = new Enumerator(values); RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } internal override void WritePacked(ref ProtoWriter.State state, ImmutableStack values, IMeasuringSerializer serializer, WireType wireType) { Enumerator values2 = new Enumerator(values); RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } } internal sealed class ImmutableIStackSerializer : RepeatedSerializer, T> { protected override IImmutableStack Initialize(IImmutableStack values, ISerializationContext context) { return values ?? ImmutableStack.Empty; } protected override IImmutableStack AddRange(IImmutableStack values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count == 1) { return values.Push(RepeatedSerializer.Singleton(ref newValues)); } RepeatedSerializer.ReverseInPlace(ref newValues); Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T value = span[i]; values = values.Push(value); } return values; } protected override IImmutableStack Clear(IImmutableStack values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(IImmutableStack values) { try { return (values != null && !values.IsEmpty) ? (-1) : 0; } catch { return -1; } } internal override long Measure(IImmutableStack values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, IImmutableStack values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, IImmutableStack values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } } internal sealed class ImmutableQueueSerializer : RepeatedSerializer, T> { [StructLayout(LayoutKind.Auto)] private struct Enumerator : IEnumerator, IEnumerator, IDisposable { private ImmutableQueue.Enumerator _iter; T IEnumerator.Current => _iter.Current; object IEnumerator.Current => _iter.Current; public Enumerator(ImmutableQueue queue) { _iter = queue.GetEnumerator(); } readonly void IDisposable.Dispose() { } bool IEnumerator.MoveNext() { return _iter.MoveNext(); } readonly void IEnumerator.Reset() { ThrowHelper.ThrowNotImplementedException("Reset"); } } protected override ImmutableQueue Initialize(ImmutableQueue values, ISerializationContext context) { return values ?? ImmutableQueue.Empty; } protected override ImmutableQueue AddRange(ImmutableQueue values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count == 1) { return values.Enqueue(RepeatedSerializer.Singleton(ref newValues)); } Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T value = span[i]; values = values.Enqueue(value); } return values; } protected override ImmutableQueue Clear(ImmutableQueue values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(ImmutableQueue values) { if (values != null && !values.IsEmpty) { return -1; } return 0; } internal override long Measure(ImmutableQueue values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { Enumerator values2 = new Enumerator(values); return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableQueue values, ISerializer serializer, SerializerFeatures features) { Enumerator values2 = new Enumerator(values); RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } internal override void WritePacked(ref ProtoWriter.State state, ImmutableQueue values, IMeasuringSerializer serializer, WireType wireType) { Enumerator values2 = new Enumerator(values); RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } } internal sealed class ImmutableIQueueSerializer : RepeatedSerializer, T> { protected override IImmutableQueue Initialize(IImmutableQueue values, ISerializationContext context) { return values ?? ImmutableQueue.Empty; } protected override IImmutableQueue AddRange(IImmutableQueue values, ref ArraySegment newValues, ISerializationContext context) { if (newValues.Count == 1) { return values.Enqueue(RepeatedSerializer.Singleton(ref newValues)); } Span span = newValues.AsSpan(); for (int i = 0; i < span.Length; i++) { T value = span[i]; values = values.Enqueue(value); } return values; } protected override IImmutableQueue Clear(IImmutableQueue values, ISerializationContext context) { return values.Clear(); } protected override int TryGetCount(IImmutableQueue values) { try { return (values != null && !values.IsEmpty) ? (-1) : 0; } catch { return -1; } } internal override long Measure(IImmutableQueue values, IMeasuringSerializer serializer, ISerializationContext context, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { return RepeatedSerializer, T>.Measure(ref values2, serializer, context, wireType); } finally { values2?.Dispose(); } } internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, IImmutableQueue values, ISerializer serializer, SerializerFeatures features) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.Write(ref state, fieldNumber, category, wireType, ref values2, serializer, features); } finally { values2?.Dispose(); } } internal override void WritePacked(ref ProtoWriter.State state, IImmutableQueue values, IMeasuringSerializer serializer, WireType wireType) { IEnumerator values2 = values.GetEnumerator(); try { RepeatedSerializer, T>.WritePacked(ref state, ref values2, serializer, wireType); } finally { values2?.Dispose(); } } } internal static class SerializerCache<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)] TProvider> where TProvider : class { internal static readonly TProvider InstanceField = (TProvider)Activator.CreateInstance(typeof(TProvider), nonPublic: true); public static ISerializer GetSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return SerializerCache.InstanceField; } } internal static class SerializerCache<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)] TProvider, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> where TProvider : class { internal static readonly ISerializer InstanceField = SerializerCache.Verify((SerializerCache.InstanceField as ISerializer) ?? (SerializerCache.InstanceField as ISerializerProxy)?.Serializer); public static ISerializer Instance { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return InstanceField; } } } public static class SerializerCache { [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowInvalidSerializer(ISerializer serializer, string message, Exception innerException = null) { string text = typeof(T).NormalizeName(); string text2 = serializer.GetType().NormalizeName(); string text3 = serializer.Features.ToString(); try { ThrowHelper.ThrowInvalidOperationException("The serializer " + text2 + " for type " + text + " has invalid features: " + message + " (" + text3 + ")", innerException); } catch (InvalidOperationException ex) { ex.Data.Add("type", text); ex.Data.Add("serializer", text2); ex.Data.Add("features", text3); throw; } } internal static ISerializer Verify(ISerializer serializer) { if (serializer == null) { return null; } try { SerializerFeatures features = serializer.Features; if (serializer is IRepeatedSerializer) { if ((features & (SerializerFeatures)(-1)) != SerializerFeatures.CategoryRepeated) { ThrowInvalidSerializer(serializer, $"repeated serializers may only specify {SerializerFeatures.CategoryRepeated}"); } return serializer; } WireType wireType = features.GetWireType(); switch (wireType) { default: ThrowInvalidSerializer(serializer, $"invalid wire-type {wireType}"); break; case WireType.Variant: case WireType.Fixed64: case WireType.String: case WireType.StartGroup: case WireType.Fixed32: case WireType.SignedVariant: break; } switch (features.GetCategory()) { case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: if (TypeHelper.CanBePacked) { ThrowInvalidSerializer(serializer, "message serializer specified for a type that can be 'packed'"); } break; case SerializerFeatures.CategoryScalar: if (TypeHelper.CanBePacked && (uint)wireType > 1u && wireType != WireType.Fixed32 && wireType != WireType.SignedVariant) { ThrowInvalidSerializer(serializer, "invalid wire-type for a type that can be 'packed'"); } break; default: features.ThrowInvalidCategory(); break; } if ((features & (SerializerFeatures.OptionPackedDisabled | SerializerFeatures.OptionClearCollection)) != SerializerFeatures.CategoryRepeated) { ThrowInvalidSerializer(serializer, $"serializers should not specify {SerializerFeatures.OptionPackedDisabled | SerializerFeatures.OptionClearCollection}"); } return serializer; } catch (InvalidOperationException ex) when (!ex.Data.Contains("serializer")) { ThrowInvalidSerializer(serializer, ex.Message, ex); throw; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ISerializer Get() where TProvider : class { return SerializerCache.InstanceField; } [MethodImpl(MethodImplOptions.NoInlining)] internal static object GetInstance(Type providerType, Type type) { return typeof(SerializerCache<, >).MakeGenericType(providerType, type).GetField("InstanceField", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); } } } namespace ProtoBuf.Meta { public enum ProtoSyntax { Default = -1, Proto2, Proto3 } public sealed class SchemaGenerationOptions { internal static readonly SchemaGenerationOptions Default = new SchemaGenerationOptions(); private List _services; private List _types; public ProtoSyntax Syntax { get; set; } = ProtoSyntax.Default; public SchemaGenerationFlags Flags { get; set; } public string Package { get; set; } public List Services => _services ?? (_services = new List()); public List Types => _types ?? (_types = new List()); internal bool HasServices => (_services?.Count ?? 0) != 0; internal bool HasTypes => (_types?.Count ?? 0) != 0; public string Origin { get; set; } } [Flags] public enum SchemaGenerationFlags { None = 0, MultipleNamespaceSupport = 1, PreserveSubType = 2, IncludeEnumNamePrefix = 4 } public sealed class Service { public string Name { get; set; } public List Methods { get; } = new List(); } public sealed class ServiceMethod { public string Name { get; set; } public Type InputType { get; set; } = typeof(Empty); public Type OutputType { get; set; } = typeof(Empty); public bool ServerStreaming { get; set; } public bool ClientStreaming { get; set; } } public class TypeFormatEventArgs : EventArgs { private Type type; private string formattedName; private readonly bool typeFixed; public Type Type { get { return type; } set { if (type != value) { if (typeFixed) { ThrowHelper.ThrowInvalidOperationException("The type is fixed and cannot be changed"); } type = value; } } } public string FormattedName { get { return formattedName; } set { if (formattedName != value) { if (!typeFixed) { ThrowHelper.ThrowInvalidOperationException("The formatted-name is fixed and cannot be changed"); } formattedName = value; } } } internal TypeFormatEventArgs(string formattedName) { if (string.IsNullOrEmpty(formattedName)) { ThrowHelper.ThrowArgumentNullException("formattedName"); } this.formattedName = formattedName; } internal TypeFormatEventArgs(Type type) { if ((object)type == null) { ThrowHelper.ThrowArgumentNullException("type"); } this.type = type; typeFixed = true; } } public delegate void TypeFormatEventHandler(object sender, TypeFormatEventArgs args); internal static class TypeModelExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool HasOption(this TypeModel model, TypeModel.TypeModelOptions options) { TypeModel.TypeModelOptions typeModelOptions = model?.Options ?? TypeModel.TypeModelOptions.None; return (typeModelOptions & options) != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool OmitsOption(this TypeModel model, TypeModel.TypeModelOptions options) { TypeModel.TypeModelOptions typeModelOptions = model?.Options ?? TypeModel.TypeModelOptions.None; return (typeModelOptions & options) == 0; } } public abstract class TypeModel : IProtoInput, IProtoInput>, IProtoInput, IProtoInput>, IProtoInput>, IProtoOutput, IProtoOutput>, IMeasuredProtoOutput, IMeasuredProtoOutput> { [Flags] public enum TypeModelOptions { None = 0, InternStrings = 1, IncludeDateTimeKind = 2, SkipZeroLengthPackedArrays = 4, AllowPackedEncodingAtRoot = 8 } private sealed class DeserializeItemsIterator : DeserializeItemsIterator, IEnumerator, IEnumerator, IDisposable, IEnumerable, IEnumerable { public new T Current => (T)base.Current; IEnumerator IEnumerable.GetEnumerator() { return this; } void IDisposable.Dispose() { } public DeserializeItemsIterator(TypeModel model, Stream source, PrefixStyle style, int expectedField, SerializationContext context) : base(model, source, typeof(T), style, expectedField, null, context) { } } private class DeserializeItemsIterator : IEnumerator, IEnumerable { private bool haveObject; private object current; private readonly Stream source; private readonly Type type; private readonly PrefixStyle style; private readonly int expectedField; private readonly TypeResolver resolver; private readonly TypeModel model; private readonly SerializationContext context; public object Current => current; IEnumerator IEnumerable.GetEnumerator() { return this; } public bool MoveNext() { if (haveObject) { current = model.DeserializeWithLengthPrefix(source, null, type, style, expectedField, resolver, out var _, out haveObject, context); } return haveObject; } void IEnumerator.Reset() { ThrowHelper.ThrowNotSupportedException(); } public DeserializeItemsIterator(TypeModel model, Stream source, Type type, PrefixStyle style, int expectedField, TypeResolver resolver, SerializationContext context) { haveObject = true; this.source = source; this.type = type; this.style = style; this.expectedField = expectedField; this.resolver = resolver; this.model = model; this.context = context; } } internal sealed class NullModel : TypeModel { private static readonly NullModel s_Singleton = new NullModel(); public static TypeModel Singleton { [MethodImpl(MethodImplOptions.NoInlining)] get { return s_Singleton; } } private NullModel() { } protected override ISerializer GetSerializer() { return null; } } protected internal enum CallbackType { BeforeSerialize, AfterSerialize, BeforeDeserialize, AfterDeserialize } internal sealed class Formatter : IFormatter { private readonly TypeModel model; private readonly Type type; public SerializationBinder Binder { get; set; } public StreamingContext Context { get; set; } public ISurrogateSelector SurrogateSelector { get; set; } internal Formatter(TypeModel model, Type type) { if (model == null) { ThrowHelper.ThrowArgumentNullException("model"); } if ((object)type == null) { ThrowHelper.ThrowArgumentNullException("model"); } this.model = model; this.type = type; } public object Deserialize(Stream serializationStream) { using ProtoReader.State state = ProtoReader.State.Create(serializationStream, model, Context, -1L); return state.DeserializeRootFallback(null, type); } public void Serialize(Stream serializationStream, object graph) { ProtoWriter.State state = ProtoWriter.State.Create(serializationStream, model, Context); try { model.SerializeRootFallback(ref state, graph); } finally { state.Dispose(); } } } private int _bufferSize = 1024; private int _maxDepth = 512; internal const int DefaultMaxDepth = 512; internal const TypeModelOptions DefaultOptions = TypeModelOptions.None; internal const SerializerFeatures FromAux = (SerializerFeatures)1073741824; private static TypeModel s_defaultModel; public const int ListItemTag = 1; public int BufferSize { get { return _bufferSize; } set { _bufferSize = ((value <= 0) ? 1024 : value); } } public int MaxDepth { get { return _maxDepth; } set { _maxDepth = ((value <= 0) ? 512 : value); } } public virtual TypeModelOptions Options => TypeModelOptions.None; internal static TypeModel DefaultModel => s_defaultModel ?? SetDefaultModel(null); public event TypeFormatEventHandler DynamicTypeFormatting; [MethodImpl(MethodImplOptions.AggressiveInlining)] protected static ISerializer GetSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)] TProvider, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() where TProvider : class { return SerializerCache.InstanceField; } [Obsolete("This API is no longer required and may be removed in a future release")] protected internal Type MapType(Type type) { return type; } [Obsolete("This API is no longer required and may be removed in a future release")] protected internal Type MapType(Type type, bool demand) { return type; } internal static WireType GetWireType(TypeModel model, DataFormat format, Type type) { if (type.IsEnum) { return WireType.Variant; } if (model != null && model.CanSerializeContractType(type)) { if (format != DataFormat.Group) { return WireType.String; } return WireType.StartGroup; } switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: if (format != DataFormat.FixedSize) { return WireType.Variant; } return WireType.Fixed64; case ProtoTypeCode.Boolean: case ProtoTypeCode.Char: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: if (format != DataFormat.FixedSize) { return WireType.Variant; } return WireType.Fixed32; case ProtoTypeCode.Double: return WireType.Fixed64; case ProtoTypeCode.Single: return WireType.Fixed32; case ProtoTypeCode.Decimal: case ProtoTypeCode.DateTime: case ProtoTypeCode.String: case ProtoTypeCode.TimeSpan: case ProtoTypeCode.ByteArray: case ProtoTypeCode.Guid: case ProtoTypeCode.Uri: case ProtoTypeCode.ByteArraySegment: case ProtoTypeCode.ByteMemory: case ProtoTypeCode.ByteReadOnlyMemory: return WireType.String; default: return WireType.None; } } internal virtual bool IsKnownType(CompatibilityLevel ambient) { if (TypeHelper.IsReferenceType | !TypeHelper.CanBeNull) { return GetSerializerCore(ambient) != null; } return false; } internal bool TrySerializeAuxiliaryType(ref ProtoWriter.State state, Type type, DataFormat format, int tag, object value, bool isInsideList, object parentList, bool isRoot) { PrepareDeserialize(value, ref type); WireType wireType = GetWireType(this, format, type); if (DynamicStub.CanSerialize(type, this, out var features)) { ObjectScope objectScope = NormalizeAuxScope(features, isInsideList, type, isRoot); try { if (!DynamicStub.TrySerializeAny(tag, wireType.AsFeatures() | (SerializerFeatures)1073741824, type, this, ref state, value)) { ThrowUnexpectedType(type, this); } } catch (Exception ex) { ThrowHelper.ThrowProtoException(ex.Message + $"; scope: {objectScope}, features: {features}; type: {type.NormalizeName()}", ex); } return true; } if (value is IEnumerable enumerable) { if (isInsideList) { ThrowNestedListsNotSupported(parentList?.GetType()); } foreach (object item in enumerable) { if (item == null) { ThrowHelper.ThrowNullReferenceException(); } if (!TrySerializeAuxiliaryType(ref state, null, format, tag, item, isInsideList: true, enumerable, isRoot)) { ThrowUnexpectedType(item.GetType(), this); } } return true; } return false; } private static ObjectScope NormalizeAuxScope(SerializerFeatures features, bool isInsideList, Type type, bool isRoot) { switch (features.GetCategory()) { case SerializerFeatures.CategoryRepeated: if (isInsideList) { ThrowNestedListsNotSupported(type); } ThrowHelper.ThrowNotSupportedException("A repeated type was not expected as an aux type: " + type.NormalizeName()); return ObjectScope.NakedMessage; case SerializerFeatures.CategoryMessage: return ObjectScope.WrappedMessage; case SerializerFeatures.CategoryMessageWrappedAtRoot: if (!(isInsideList || isRoot)) { return ObjectScope.LikeRoot; } return ObjectScope.WrappedMessage; case SerializerFeatures.CategoryScalar: return ObjectScope.Scalar; default: features.ThrowInvalidCategory(); return ObjectScope.Invalid; } } public void Serialize(Stream dest, object value) { ProtoWriter.State state = ProtoWriter.State.Create(dest, this); try { SerializeRootFallback(ref state, value); } finally { state.Dispose(); } } public void Serialize(Stream dest, object value, SerializationContext context) { ProtoWriter.State state = ProtoWriter.State.Create(dest, this, context); try { SerializeRootFallback(ref state, value); } finally { state.Dispose(); } } public void Serialize(IBufferWriter dest, object value, object userState = null) { ProtoWriter.State state = ProtoWriter.State.Create(dest, this, userState); try { SerializeRootFallback(ref state, value); } finally { state.Dispose(); } } internal void SerializeRootFallback(ref ProtoWriter.State state, object value) { Type type = value.GetType(); try { if (!DynamicStub.TrySerializeRoot(type, this, ref state, value)) { if (!TrySerializeAuxiliaryType(ref state, type, DataFormat.Default, 1, value, isInsideList: false, null, isRoot: true)) { ThrowUnexpectedType(type, this); } state.Close(); } } catch { state.Abandon(); throw; } } public long Serialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(Stream dest, T value, object userState = null) { ProtoWriter.State state = ProtoWriter.State.Create(dest, this, userState); try { return SerializeImpl(ref state, value); } finally { state.Dispose(); } } public long Serialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(IBufferWriter dest, T value, object userState = null) { ProtoWriter.State state = ProtoWriter.State.Create(dest, this, userState); try { return SerializeImpl(ref state, value); } finally { state.Dispose(); } } public MeasureState Measure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value, object userState = null, long abortAfter = -1L) { return new MeasureState(this, in value, userState, abortAfter); } [Obsolete("If possible, please use the State API; a transitionary implementation is provided, but this API may be removed in a future version", false)] public void Serialize(ProtoWriter dest, object value) { ProtoWriter.State state = dest.DefaultState(); SerializeRootFallback(ref state, value); } internal static long SerializeImpl(ref ProtoWriter.State state, T value) { if (TypeHelper.CanBeNull && TypeHelper.ValueChecker.IsNull(value)) { return 0L; } ISerializer serializer = TryGetSerializer(state.Model); if (serializer == null) { long position = state.GetPosition(); state.Model.SerializeRootFallback(ref state, value); return state.GetPosition() - position; } return state.SerializeRoot(value, serializer); } public object DeserializeWithLengthPrefix(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int fieldNumber) { long bytesRead; return DeserializeWithLengthPrefix(source, value, type, style, fieldNumber, (TypeResolver)null, out bytesRead); } public object DeserializeWithLengthPrefix(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int expectedField, TypeResolver resolver) { long bytesRead; return DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead); } public object DeserializeWithLengthPrefix(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int expectedField, TypeResolver resolver, out int bytesRead) { long bytesRead2; bool haveObject; object result = DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead2, out haveObject, null); bytesRead = checked((int)bytesRead2); return result; } public object DeserializeWithLengthPrefix(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int expectedField, TypeResolver resolver, out long bytesRead) { bool haveObject; return DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead, out haveObject, null); } private object DeserializeWithLengthPrefix(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int expectedField, TypeResolver resolver, out long bytesRead, out bool haveObject, SerializationContext context) { haveObject = false; bytesRead = 0L; if ((object)type == null && (style != PrefixStyle.Base128 || resolver == null)) { ThrowHelper.ThrowInvalidOperationException("A type must be provided unless base-128 prefixing is being used in combination with a resolver"); } long num; bool flag2; do { bool flag = expectedField > 0 || resolver != null; num = ProtoReader.ReadLongLengthPrefix(source, flag, style, out var fieldNumber, out var bytesRead2); if (bytesRead2 == 0) { return value; } bytesRead += bytesRead2; if (num < 0) { return value; } if (style == PrefixStyle.Base128) { if (flag && expectedField == 0 && (object)type == null && resolver != null) { type = resolver(fieldNumber); flag2 = (object)type == null; } else { flag2 = expectedField != fieldNumber; } } else { flag2 = false; } if (flag2) { if (num == long.MaxValue) { ThrowHelper.ThrowInvalidOperationException(); } ProtoReader.Seek(source, num, null); bytesRead += num; } } while (flag2); ProtoReader.State state = ProtoReader.State.Create(source, this, context, num); try { if (IsDefined(type) && !type.IsEnum) { value = Deserialize(ObjectScope.LikeRoot, ref state, type, value); } else if (!TryDeserializeAuxiliaryType(ref state, DataFormat.Default, 1, type, ref value, skipOtherFields: true, asListItem: false, autoCreate: true, insideList: false, null, isRoot: true) && num != 0L) { ThrowUnexpectedType(type, this); } bytesRead += state.GetPosition(); } finally { state.Dispose(); } haveObject = true; return value; } public IEnumerable DeserializeItems(Stream source, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int expectedField, TypeResolver resolver) { return DeserializeItems(source, type, style, expectedField, resolver, null); } public IEnumerable DeserializeItems(Stream source, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int expectedField, TypeResolver resolver, SerializationContext context) { return new DeserializeItemsIterator(this, source, type, style, expectedField, resolver, context); } public IEnumerable DeserializeItems<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(Stream source, PrefixStyle style, int expectedField) { return DeserializeItems(source, style, expectedField, null); } public IEnumerable DeserializeItems<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(Stream source, PrefixStyle style, int expectedField, SerializationContext context) { return new DeserializeItemsIterator(this, source, style, expectedField, context); } public void SerializeWithLengthPrefix(Stream dest, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int fieldNumber) { SerializeWithLengthPrefix(dest, value, type, style, fieldNumber, null); } public void SerializeWithLengthPrefix(Stream dest, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, PrefixStyle style, int fieldNumber, SerializationContext context) { if ((object)type == null) { if (value == null) { ThrowHelper.ThrowArgumentNullException("value"); } type = value.GetType(); } ProtoWriter.State state = ProtoWriter.State.Create(dest, this, context); try { switch (style) { case PrefixStyle.None: if (!DynamicStub.TrySerializeRoot(type, this, ref state, value)) { ThrowUnexpectedType(type, this); } break; case PrefixStyle.Base128: case PrefixStyle.Fixed32: case PrefixStyle.Fixed32BigEndian: state.WriteObject(value, type, style, fieldNumber); break; default: ThrowHelper.ThrowArgumentOutOfRangeException("style"); break; } state.Flush(); state.Close(); } catch { state.Abandon(); throw; } finally { state.Dispose(); } } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public object Deserialize(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) { using ProtoReader.State state = ProtoReader.State.Create(source, this, null, -1L); return state.DeserializeRootFallback(value, type); } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public object Deserialize(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, SerializationContext context) { using ProtoReader.State state = ProtoReader.State.Create(source, this, context, -1L); return state.DeserializeRootFallback(value, type); } public T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(Stream source, T value = default(T), object userState = null) { using ProtoReader.State state = ProtoReader.State.Create(source, this, userState, -1L); return state.DeserializeRootImpl(value); } public T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(ReadOnlyMemory source, T value = default(T), object userState = null) { using ProtoReader.State state = ProtoReader.State.Create(source, this, userState); return state.DeserializeRootImpl(value); } public unsafe T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(ReadOnlySpan source, T value = default(T), object userState = null) { fixed (byte* pointer = source) { FixedMemoryManager fixedMemoryManager = null; ProtoReader.State state = default(ProtoReader.State); try { fixedMemoryManager = Pool.TryGet() ?? new FixedMemoryManager(); state = ProtoReader.State.Create(fixedMemoryManager.Init(pointer, source.Length), this, userState); return state.DeserializeRootImpl(value); } finally { state.Dispose(); Pool.Put(fixedMemoryManager); } } } public T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(ReadOnlySequence source, T value = default(T), object userState = null) { using ProtoReader.State state = ProtoReader.State.Create(source, this, userState); return state.DeserializeRootImpl(value); } public object Deserialize([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, Stream source, object value = null, object userState = null, long length = -1L) { using ProtoReader.State state = ProtoReader.State.Create(source, this, userState, length); return state.DeserializeRootFallback(value, type); } public object Deserialize([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, ReadOnlyMemory source, object value = null, object userState = null) { using ProtoReader.State state = ProtoReader.State.Create(source, this, userState); return state.DeserializeRootFallback(value, type); } public unsafe object Deserialize([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, ReadOnlySpan source, object value = null, object userState = null) { fixed (byte* pointer = source) { FixedMemoryManager fixedMemoryManager = null; ProtoReader.State state = default(ProtoReader.State); try { fixedMemoryManager = Pool.TryGet() ?? new FixedMemoryManager(); state = ProtoReader.State.Create(fixedMemoryManager.Init(pointer, source.Length), this, userState); return state.DeserializeRootFallback(value, type); } finally { state.Dispose(); Pool.Put(fixedMemoryManager); } } } public object Deserialize([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, ReadOnlySequence source, object value = null, object userState = null) { using ProtoReader.State state = ProtoReader.State.Create(source, this, userState); return state.DeserializeRootFallback(value, type); } internal static bool PrepareDeserialize(object value, ref Type type) { if ((object)type == null || type == typeof(object)) { if (value == null) { ThrowHelper.ThrowArgumentNullException("type"); } type = value.GetType(); } bool result = true; Type underlyingType = Nullable.GetUnderlyingType(type); if ((object)underlyingType == null) { type = DynamicStub.GetEffectiveType(type); } else { type = underlyingType; result = false; } return result; } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public object Deserialize(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, int length) { return Deserialize(source, value, type, length, null); } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public object Deserialize(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, long length) { return Deserialize(source, value, type, length, null); } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public object Deserialize(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, int length, SerializationContext context) { return Deserialize(source, value, type, (length == int.MaxValue) ? long.MaxValue : length, context); } [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public object Deserialize(Stream source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, long length, SerializationContext context) { ProtoReader.State state = ProtoReader.State.Create(source, this, context, length); try { bool autoCreate = PrepareDeserialize(value, ref type); if (!DynamicStub.TryDeserializeRoot(type, this, ref state, ref value, autoCreate)) { value = state.DeserializeRootFallback(value, type); } return value; } finally { state.Dispose(); } } public object Deserialize(ReadOnlyMemory source, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, object value = null, object userState = null) { ProtoReader.State state = ProtoReader.State.Create(source, this, userState); try { bool autoCreate = PrepareDeserialize(value, ref type); if (!DynamicStub.TryDeserializeRoot(type, this, ref state, ref value, autoCreate)) { value = state.DeserializeRootFallback(value, type); } return value; } finally { state.Dispose(); } } public object Deserialize(ReadOnlySequence source, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, object value = null, object userState = null) { ProtoReader.State state = ProtoReader.State.Create(source, this, userState); try { bool autoCreate = PrepareDeserialize(value, ref type); if (!DynamicStub.TryDeserializeRoot(type, this, ref state, ref value, autoCreate)) { value = state.DeserializeRootFallback(value, type); } return value; } finally { state.Dispose(); } } [Obsolete("If possible, please use the State API; a transitionary implementation is provided, but this API may be removed in a future version", false)] public object Deserialize(ProtoReader source, object value, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) { return source.DefaultState().DeserializeRootFallbackWithModel(value, type, this); } internal object DeserializeRootAny(ref ProtoReader.State state, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, object value, bool autoCreate) { if (!DynamicStub.TryDeserializeRoot(type, this, ref state, ref value, autoCreate)) { TryDeserializeAuxiliaryType(ref state, DataFormat.Default, 1, type, ref value, skipOtherFields: true, asListItem: false, autoCreate, insideList: false, null, isRoot: true); } return value; } private bool TryDeserializeList(ref ProtoReader.State state, DataFormat format, int tag, Type listType, Type itemType, ref object value, bool isRoot) { bool result = false; object value2 = null; IList list = value as IList; IList list2 = ((list == null) ? ((IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(itemType), nonPublic: true)) : null); while (TryDeserializeAuxiliaryType(ref state, format, tag, itemType, ref value2, skipOtherFields: true, asListItem: true, autoCreate: true, insideList: true, value ?? listType, isRoot)) { result = true; if (value == null && list2 == null) { value = CreateListInstance(listType, itemType); list = value as IList; } if (list != null) { list.Add(value2); } else { list2.Add(value2); } value2 = null; } if (list2 != null) { if (value != null) { if (list2.Count != 0) { Array array = (Array)value; Array array2 = Array.CreateInstance(itemType, array.Length + list2.Count); Array.Copy(array, array2, array.Length); list2.CopyTo(array2, array.Length); value = array2; } } else { Array array2 = Array.CreateInstance(itemType, list2.Count); list2.CopyTo(array2, 0); value = array2; } } return result; } private static object CreateListInstance(Type listType, Type itemType) { Type type = listType; if (listType.IsArray) { return Array.CreateInstance(itemType, 0); } if (!listType.IsClass || listType.IsAbstract || (object)Helpers.GetConstructor(listType, Type.EmptyTypes, nonPublic: true) == null) { bool flag = false; string fullName; if (listType.IsInterface && (fullName = listType.FullName) != null && fullName.Contains("Dictionary")) { if (listType.IsGenericType && listType.GetGenericTypeDefinition() == typeof(IDictionary<, >)) { Type[] genericArguments = listType.GetGenericArguments(); type = typeof(Dictionary<, >).MakeGenericType(genericArguments); flag = true; } if (!flag && listType == typeof(IDictionary)) { type = typeof(Hashtable); flag = true; } } if (!flag) { type = typeof(List<>).MakeGenericType(itemType); flag = true; } if (!flag) { type = typeof(ArrayList); flag = true; } } return Activator.CreateInstance(type, nonPublic: true); } internal bool TryDeserializeAuxiliaryType(ref ProtoReader.SolidState state, DataFormat format, int tag, Type type, ref object value, bool skipOtherFields, bool asListItem, bool autoCreate, bool insideList, object parentListOrType, bool isRoot) { ProtoReader.State state2 = state.Liquify(); bool result = TryDeserializeAuxiliaryType(ref state2, format, tag, type, ref value, skipOtherFields, asListItem, autoCreate, insideList, parentListOrType, isRoot); state = state2.Solidify(); return result; } internal bool TryDeserializeAuxiliaryType(ref ProtoReader.State state, DataFormat format, int tag, Type type, ref object value, bool skipOtherFields, bool asListItem, bool autoCreate, bool insideList, object parentListOrType, bool isRoot) { if ((object)type == null) { ThrowHelper.ThrowArgumentNullException("type"); } WireType wireType = GetWireType(this, format, type); bool flag = false; if (wireType == WireType.None) { if (!TypeHelper.ResolveUniqueEnumerableT(type, out var t)) { t = null; } if ((object)t == null && type.IsArray && type.GetArrayRank() == 1 && type != typeof(byte[])) { t = type.GetElementType(); } if ((object)t != null) { if (insideList) { ThrowNestedListsNotSupported((parentListOrType as Type) ?? parentListOrType?.GetType()); } flag = TryDeserializeList(ref state, format, tag, type, t, ref value, isRoot); if (!flag && autoCreate) { value = CreateListInstance(type, t); } return flag; } ThrowUnexpectedType(type, this); } if (!DynamicStub.CanSerialize(type, this, out var features)) { ThrowHelper.ThrowInvalidOperationException("Unable to deserialize aux type: " + type.NormalizeName()); } while (!(flag && asListItem)) { int num = state.ReadFieldHeader(); if (num <= 0) { break; } if (num != tag) { if (skipOtherFields) { state.SkipField(); continue; } state.ThrowInvalidOperationException($"Expected field {tag}, but found {num}"); } flag = true; state.Hint(wireType); ObjectScope scope = NormalizeAuxScope(features, insideList, type, isRoot); value = Deserialize(scope, ref state, type, value); } if (!flag && !asListItem && autoCreate && type != typeof(string)) { value = Activator.CreateInstance(type, nonPublic: true); } return flag; } [MethodImpl(MethodImplOptions.NoInlining)] internal static TypeModel SetDefaultModel(TypeModel newValue) { if (newValue == null || newValue is NullModel) { Interlocked.CompareExchange(ref s_defaultModel, NullModel.Singleton, null); } else { Interlocked.Exchange(ref s_defaultModel, newValue); } return Volatile.Read(in s_defaultModel); } internal static void ResetDefaultModel() { Volatile.Write(ref s_defaultModel, null); } [Obsolete("Use RuntimeTypeModel.Create", true)] public static TypeModel Create() { ThrowHelper.ThrowNotSupportedException(); return null; } [Obsolete("Use RuntimeTypeModel.CreateForAssembly", true)] public static TypeModel CreateForAssembly() { ThrowHelper.ThrowNotSupportedException(); return null; } [Obsolete("Use RuntimeTypeModel.CreateForAssembly", true)] public static TypeModel CreateForAssembly(Type type) { ThrowHelper.ThrowNotSupportedException(); return null; } [Obsolete("Use RuntimeTypeModel.CreateForAssembly", true)] public static TypeModel CreateForAssembly(Assembly assembly) { ThrowHelper.ThrowNotSupportedException(); return null; } public bool IsDefined(Type type) { return IsDefined(type, CompatibilityLevel.NotSpecified); } internal bool IsDefined(Type type, CompatibilityLevel ambient) { if ((object)type != null) { return DynamicStub.IsKnownType(type, this, ambient); } return false; } protected virtual ISerializer GetSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>() { return this as ISerializer; } internal virtual ISerializer GetSerializerCore(CompatibilityLevel ambient) { return GetSerializer(); } [MethodImpl(MethodImplOptions.NoInlining)] private static ISerializer NoSerializer(TypeModel model) { string text = null; if (model is NullModel) { text = "; you may need to ensure that RuntimeTypeModel.Initialize has been invoked"; } ThrowHelper.ThrowInvalidOperationException("No serializer for type " + typeof(T).NormalizeName() + " is available for model " + (model?.ToString() ?? "(none)") + text); return null; } [MethodImpl(MethodImplOptions.NoInlining)] private static ISubTypeSerializer NoSubTypeSerializer(TypeModel model) where T : class { ThrowHelper.ThrowInvalidOperationException("No sub-type serializer for type " + typeof(T).NormalizeName() + " is available for model " + (model?.ToString() ?? "(none)")); return null; } internal static T CreateInstance(ISerializationContext context, ISerializer serializer = null) { if (TypeHelper.IsReferenceType) { if (serializer == null) { serializer = TryGetSerializer(context?.Model); } T val = default(T); if (serializer is IFactory factory) { val = factory.Create(context); } T val2 = val; if (val2 == null) { val = ActivatorCreate(); } return val; } return default(T); } [MethodImpl(MethodImplOptions.NoInlining)] internal static T ActivatorCreate() { try { return (T)Activator.CreateInstance(typeof(T), nonPublic: true); } catch (MissingMethodException inner) { ThrowCannotCreateInstance(typeof(T), inner); return default(T); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static ISerializer GetSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(TypeModel model, CompatibilityLevel ambient = CompatibilityLevel.NotSpecified) { return SerializerCache.InstanceField ?? model?.GetSerializerCore(ambient) ?? NoSerializer(model); } public static ISerializer GetInbuiltSerializer(CompatibilityLevel compatibilityLevel = CompatibilityLevel.NotSpecified, DataFormat dataFormat = DataFormat.Default) { if (compatibilityLevel >= CompatibilityLevel.Level300) { ISerializer instanceField; if (dataFormat == DataFormat.FixedSize) { instanceField = SerializerCache.InstanceField; if (instanceField != null) { return instanceField; } } instanceField = SerializerCache.InstanceField; if (instanceField != null) { return instanceField; } } else if (compatibilityLevel >= CompatibilityLevel.Level240 || dataFormat == DataFormat.WellKnown) { ISerializer instanceField = SerializerCache.InstanceField; if (instanceField != null) { return instanceField; } } return SerializerCache.InstanceField; } [MethodImpl(MethodImplOptions.NoInlining)] internal static IRepeatedSerializer GetRepeatedSerializer(TypeModel model) { if (model?.GetSerializer() is IRepeatedSerializer result) { return result; } NoSerializer(model); return null; } [MethodImpl(MethodImplOptions.NoInlining)] internal static ISerializer TryGetSerializer(TypeModel model) { ISerializer serializer = SerializerCache.InstanceField; if (serializer == null) { if (model == null) { return null; } serializer = model.GetSerializer(); } return serializer; } [MethodImpl(MethodImplOptions.NoInlining)] internal static ISubTypeSerializer GetSubTypeSerializer(TypeModel model) where T : class { return (model?.GetSerializer() as ISubTypeSerializer) ?? NoSubTypeSerializer(model); } internal object Deserialize(ObjectScope scope, ref ProtoReader.State state, Type type, object value) { if (!DynamicStub.TryDeserialize(scope, type, this, ref state, ref value)) { ThrowHelper.ThrowNotSupportedException(string.Format("{0} is not supported for {1} by {2}", "Deserialize", type.NormalizeName(), this)); } return value; } public T DeepClone<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value, object userState = null) { if (!RuntimeHelpers.IsReferenceOrContainsReferences()) { return value; } if (TypeHelper.CanBeNull && TypeHelper.ValueChecker.IsNull(value)) { return value; } ISerializer serializer = TryGetSerializer(this); if (serializer == null) { return (T)DeepCloneFallback(typeof(T), value); } if ((serializer.Features & SerializerFeatures.CategoryScalar) != SerializerFeatures.CategoryRepeated) { return value; } using MemoryStream memoryStream = new MemoryStream(); Serialize(memoryStream, value, userState); memoryStream.Position = 0L; return Deserialize(memoryStream, default(T), userState); } public object DeepClone(object value) { if (value == null) { return null; } Type type = value.GetType(); if (!DynamicStub.TryDeepClone(type, this, ref value)) { return DeepCloneFallback(type, value); } return value; } private object DeepCloneFallback(Type type, object value) { using MemoryStream memoryStream = new MemoryStream(); ProtoWriter.State state = ProtoWriter.State.Create(memoryStream, this); PrepareDeserialize(value, ref type); try { if (!TrySerializeAuxiliaryType(ref state, type, DataFormat.Default, 1, value, isInsideList: false, null, isRoot: true)) { ThrowUnexpectedType(type, this); } state.Close(); } catch { state.Abandon(); throw; } finally { state.Dispose(); } memoryStream.Position = 0L; ProtoReader.State state2 = ProtoReader.State.Create(memoryStream, this, null, -1L); try { value = null; TryDeserializeAuxiliaryType(ref state2, DataFormat.Default, 1, type, ref value, skipOtherFields: true, asListItem: false, autoCreate: true, insideList: false, null, isRoot: true); } finally { state2.Dispose(); } return value; } protected internal static void ThrowUnexpectedSubtype(Type expected, Type actual) { if (!DynamicStub.IsTypeEquivalent(expected, actual)) { ThrowHelper.ThrowInvalidOperationException("Unexpected sub-type: " + actual.FullName); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ThrowUnexpectedSubtype<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T>(T value) where T : class { if (IsSubType(value)) { ThrowUnexpectedSubtype(typeof(T), value.GetType()); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ThrowUnexpectedSubtype(T value) where T : class where TConstruct : class, T { if (IsSubType(value) && value.GetType() != typeof(TConstruct)) { ThrowUnexpectedSubtype(typeof(T), value.GetType()); } } public static bool IsSubType(T value) where T : class { if (value != null) { return typeof(T) != value.GetType(); } return false; } protected internal static void ThrowUnexpectedType(Type type, TypeModel model) { string text = (((object)type == null) ? "(unknown)" : type.FullName); if ((object)type != null) { Type baseType = type.BaseType; if ((object)baseType != null && baseType.IsGenericType && baseType.GetGenericTypeDefinition().Name == "GeneratedMessage`2") { ThrowHelper.ThrowInvalidOperationException("Are you mixing protobuf-net and protobuf-csharp-port? See https://stackoverflow.com/q/11564914/23354; type: " + text); } } try { ThrowHelper.ThrowInvalidOperationException("Type is not expected, and no contract can be inferred: " + text); } catch (Exception ex) when (model != null) { ex.Data["TypeModel"] = model.ToString(); throw; } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNestedListsNotSupported(Type type) { ThrowHelper.ThrowNestedDataNotSupported(type); } public static void ThrowCannotCreateInstance(Type type, Exception inner = null) { ThrowHelper.ThrowProtoException("No parameterless constructor found for " + (type?.FullName ?? "(null)"), inner); } internal static string SerializeType(TypeModel model, Type type) { if (model != null) { TypeFormatEventHandler typeFormatEventHandler = model.DynamicTypeFormatting; if (typeFormatEventHandler != null) { TypeFormatEventArgs e = new TypeFormatEventArgs(type); typeFormatEventHandler(model, e); if (!string.IsNullOrEmpty(e.FormattedName)) { return e.FormattedName; } } } return type.AssemblyQualifiedName; } internal static Type DeserializeType(TypeModel model, string value) { if (model != null) { TypeFormatEventHandler typeFormatEventHandler = model.DynamicTypeFormatting; if (typeFormatEventHandler != null) { TypeFormatEventArgs e = new TypeFormatEventArgs(value); typeFormatEventHandler(model, e); if ((object)e.Type != null) { return e.Type; } } } return Type.GetType(value); } public bool CanSerializeContractType(Type type) { SerializerFeatures category; return CanSerialize(type, allowBasic: false, allowContract: true, allowLists: true, out category); } public bool CanSerialize(Type type) { SerializerFeatures category; return CanSerialize(type, allowBasic: true, allowContract: true, allowLists: true, out category); } public bool CanSerializeBasicType(Type type) { SerializerFeatures category; return CanSerialize(type, allowBasic: true, allowContract: false, allowLists: true, out category); } internal bool CanSerialize(Type type, bool allowBasic, bool allowContract, bool allowLists, out SerializerFeatures category) { if ((object)type == null) { ThrowHelper.ThrowArgumentNullException("type"); } do { if (!DynamicStub.CanSerialize(type, this, out var features)) { continue; } category = features.GetCategory(); switch (category) { case SerializerFeatures.CategoryRepeated: if (allowLists) { return DoCheckLists(type, this, allowBasic, allowContract); } return false; case SerializerFeatures.CategoryMessage: return allowContract; case SerializerFeatures.CategoryScalar: case SerializerFeatures.CategoryMessageWrappedAtRoot: return allowBasic; } } while (CheckIfNullableT(ref type)); category = SerializerFeatures.CategoryRepeated; return false; static bool CheckIfNullableT(ref Type reference) { Type underlyingType = Nullable.GetUnderlyingType(reference); if ((object)underlyingType != null) { reference = underlyingType; return true; } return false; } static bool DoCheckLists(Type type2, TypeModel model, bool allowBasic2, bool allowContract2) { SerializerFeatures category2; if (TypeHelper.ResolveUniqueEnumerableT(type2, out var t)) { return model.CanSerialize(t, allowBasic2, allowContract2, allowLists: false, out category2); } return false; } } public string GetSchema([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) { return GetSchema(type, ProtoSyntax.Default); } public string GetSchema([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, ProtoSyntax syntax) { SchemaGenerationOptions schemaGenerationOptions; if ((object)type == null && syntax == ProtoSyntax.Default) { schemaGenerationOptions = SchemaGenerationOptions.Default; } else { schemaGenerationOptions = new SchemaGenerationOptions { Syntax = syntax }; if ((object)type != null) { schemaGenerationOptions.Types.Add(type); } } return GetSchema(schemaGenerationOptions); } public virtual string GetSchema(SchemaGenerationOptions options) { ThrowHelper.ThrowNotSupportedException(); return null; } public IFormatter CreateFormatter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) { return new Formatter(this, type); } [MethodImpl(MethodImplOptions.NoInlining)] internal static Type ResolveKnownType(string name, Assembly assembly) { if (string.IsNullOrEmpty(name)) { return null; } try { Type type = Type.GetType(name); if ((object)type != null) { return type; } } catch { } try { int num = name.IndexOf(','); string name2 = ((num > 0) ? name.Substring(0, num) : name).Trim(); if ((object)assembly == null) { assembly = Assembly.GetCallingAssembly(); } Type type2 = assembly?.GetType(name2); if ((object)type2 != null) { return type2; } } catch { } return null; } T IProtoInput.Deserialize(Stream source, T value, object userState) { return Deserialize(source, value, userState); } T IProtoInput>.Deserialize(ArraySegment source, T value, object userState) { return Deserialize(new ReadOnlyMemory(source.Array, source.Offset, source.Count), value, userState); } T IProtoInput.Deserialize(byte[] source, T value, object userState) { return Deserialize(new ReadOnlyMemory(source), value, userState); } void IProtoOutput.Serialize(Stream destination, T value, object userState) { Serialize(destination, value, userState); } void IProtoOutput>.Serialize(IBufferWriter destination, T value, object userState) { Serialize(destination, value, userState); } void IMeasuredProtoOutput.Serialize(MeasureState measured, Stream destination) { measured.Serialize(destination); } void IMeasuredProtoOutput>.Serialize(MeasureState measured, IBufferWriter destination) { measured.Serialize(destination); } MeasureState IMeasuredProtoOutput.Measure(T value, object userState) { return Measure(value, userState, -1L); } MeasureState IMeasuredProtoOutput>.Measure(T value, object userState) { return Measure(value, userState, -1L); } } } namespace ProtoBuf.Internal { internal sealed class DynamicAccess { internal const DynamicallyAccessedMemberTypes ContractType = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties; internal const DynamicallyAccessedMemberTypes Serializer = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods; } internal enum ObjectScope { Invalid, NakedMessage, LikeRoot, WrappedMessage, Scalar } internal abstract class DynamicStub { private class NilStub : DynamicStub { public static readonly NilStub Instance = new NilStub(); protected NilStub() { } protected override bool TryDeserializeRoot(TypeModel model, ref ProtoReader.State state, ref object value, bool autoCreate) { return false; } protected override bool TryDeserialize(ObjectScope scope, TypeModel model, ref ProtoReader.State state, ref object value) { return false; } protected override bool TrySerializeRoot(TypeModel model, ref ProtoWriter.State state, object value) { return false; } protected override bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value) { return false; } protected override bool TryDeepClone(TypeModel model, ref object value) { return false; } protected override bool IsKnownType(TypeModel model, CompatibilityLevel ambient) { return false; } protected override bool CanSerialize(TypeModel model, out SerializerFeatures features) { features = SerializerFeatures.CategoryRepeated; return false; } protected override Type GetEffectiveType() { return null; } } private sealed class ConcreteStub : DynamicStub { protected override Type GetEffectiveType() { return typeof(T); } protected override bool TryDeserializeRoot(TypeModel model, ref ProtoReader.State state, ref object value, bool autoCreate) { ISerializer serializer = TypeModel.TryGetSerializer(model); if (serializer == null) { return false; } bool flag = !autoCreate && value == null; long position = state.GetPosition(); value = state.DeserializeRoot(TypeHelper.FromObject(value), serializer); if (flag && position == state.GetPosition()) { value = null; } return true; } protected override bool TryDeserialize(ObjectScope scope, TypeModel model, ref ProtoReader.State state, ref object value) { ISerializer serializer = TypeModel.TryGetSerializer(model); if (serializer == null) { return false; } T value2 = TypeHelper.FromObject(value); switch (scope) { case ObjectScope.LikeRoot: value2 = state.ReadAsRoot(value2, serializer); break; case ObjectScope.NakedMessage: case ObjectScope.Scalar: value2 = serializer.Read(ref state, value2); break; case ObjectScope.WrappedMessage: value2 = state.ReadMessage(SerializerFeatures.CategoryRepeated, value2, serializer); break; default: return false; } value = value2; return true; } protected override bool IsKnownType(TypeModel model, CompatibilityLevel ambient) { return model?.IsKnownType(ambient) ?? false; } protected override bool CanSerialize(TypeModel model, out SerializerFeatures features) { ISerializer serializer; try { serializer = TypeModel.TryGetSerializer(model); } catch { features = SerializerFeatures.CategoryRepeated; return false; } if (serializer == null) { features = SerializerFeatures.CategoryRepeated; return false; } features = serializer.Features; return true; } protected override bool TrySerializeRoot(TypeModel model, ref ProtoWriter.State state, object value) { ISerializer serializer = TypeModel.TryGetSerializer(model); if (serializer == null) { return false; } state.SerializeRoot(TypeHelper.FromObject(value), serializer); return true; } protected override bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value) { ISerializer serializer = TypeModel.TryGetSerializer(model); if (serializer == null) { return false; } T value2 = TypeHelper.FromObject(value); CheckAnyAuxFlow(features, serializer); if ((features & SerializerFeatures.CategoryMessageWrappedAtRoot) == SerializerFeatures.CategoryMessageWrappedAtRoot) { if (fieldNumber != 1) { ThrowHelper.ThrowInvalidOperationException($"Special root-like wrapping is limited to field {1}"); } state.WriteAsRoot(value2, serializer); } else { state.WriteAny(fieldNumber, features, value2, serializer); } return true; } private static void CheckAnyAuxFlow(SerializerFeatures features, ISerializer serializer) { if ((features & (SerializerFeatures)1073741824) != SerializerFeatures.CategoryRepeated && serializer.Features.GetCategory() == SerializerFeatures.CategoryMessageWrappedAtRoot) { ThrowHelper.ThrowNotImplementedException("Tell Marc: ambiguous category in an any/aux flow for " + typeof(T).NormalizeName()); } } protected override bool TryDeepClone(TypeModel model, ref object value) { if (TypeModel.TryGetSerializer(model) == null) { return false; } value = model.DeepClone(TypeHelper.FromObject(value)); return true; } } private static readonly Hashtable s_byType = new Hashtable { { typeof(object), NilStub.Instance } }; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TryDeserializeRoot(Type type, TypeModel model, ref ProtoReader.State state, ref object value, bool autoCreate) { return Get(type).TryDeserializeRoot(model, ref state, ref value, autoCreate); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TrySerializeRoot(Type type, TypeModel model, ref ProtoWriter.State state, object value) { do { if (Get(type).TrySerializeRoot(model, ref state, value)) { return true; } type = type.BaseType; } while ((object)type != null && type != typeof(object)); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TryDeserialize(ObjectScope scope, Type type, TypeModel model, ref ProtoReader.State state, ref object value) { return Get(type).TryDeserialize(scope, model, ref state, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TrySerializeAny(int fieldNumber, SerializerFeatures features, Type type, TypeModel model, ref ProtoWriter.State state, object value) { do { if (Get(type).TrySerializeAny(fieldNumber, features, model, ref state, value)) { return true; } type = type.BaseType; } while ((object)type != null && type != typeof(object)); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TryDeepClone(Type type, TypeModel model, ref object value) { do { if (Get(type).TryDeepClone(model, ref value)) { return true; } type = type.BaseType; } while ((object)type != null && type != typeof(object)); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool IsKnownType(Type type, TypeModel model, CompatibilityLevel ambient) { return Get(type).IsKnownType(model, ambient); } internal static bool CanSerialize(Type type, TypeModel model, out SerializerFeatures features) { return Get(type).CanSerialize(model, out features); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static DynamicStub Get(Type type) { return ((DynamicStub)s_byType[type]) ?? SlowGet(type); } [MethodImpl(MethodImplOptions.NoInlining)] private static DynamicStub SlowGet(Type type) { if ((object)type == null) { return NilStub.Instance; } DynamicStub dynamicStub = null; Type type2 = null; if (!type.IsGenericParameter) { type2 = ((!type.IsValueType) ? ResolveProxies(type) : Nullable.GetUnderlyingType(type)); } else { dynamicStub = NilStub.Instance; } if (dynamicStub == null) { if ((object)type2 != null && type2 != type) { dynamicStub = Get(type2); } if (dynamicStub == null) { dynamicStub = TryCreateConcrete(typeof(ConcreteStub<>), new Type[1] { type }); } } lock (s_byType) { s_byType[type] = dynamicStub; return dynamicStub; } static Type ResolveProxies(Type type3) { if ((object)type3 == null) { return null; } if (type3.IsGenericParameter) { return null; } string fullName = type3.FullName; if (fullName != null && fullName.StartsWith("System.Data.Entity.DynamicProxies.")) { return type3.BaseType; } Type[] interfaces = type3.GetInterfaces(); Type[] array = interfaces; foreach (Type type4 in array) { switch (type4.FullName) { case "NHibernate.Proxy.INHibernateProxy": case "NHibernate.Proxy.DynamicProxy.IProxy": case "NHibernate.Intercept.IFieldInterceptorAccessor": return type3.BaseType; } } return null; } static DynamicStub TryCreateConcrete(Type typeDef, Type[] args) { try { return (DynamicStub)Activator.CreateInstance(typeDef.MakeGenericType(args), nonPublic: true); } catch { return NilStub.Instance; } } } protected abstract bool TryDeserializeRoot(TypeModel model, ref ProtoReader.State state, ref object value, bool autoCreate); protected abstract bool TryDeserialize(ObjectScope scope, TypeModel model, ref ProtoReader.State state, ref object value); protected abstract bool TrySerializeRoot(TypeModel model, ref ProtoWriter.State state, object value); protected abstract bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value); protected abstract bool TryDeepClone(TypeModel model, ref object value); protected abstract bool IsKnownType(TypeModel model, CompatibilityLevel ambient); protected abstract bool CanSerialize(TypeModel model, out SerializerFeatures features); internal static bool IsTypeEquivalent(Type expected, Type actual) { if ((object)expected != actual) { return Get(expected) == Get(actual); } return true; } internal static Type GetEffectiveType(Type type) { object obj; if ((object)type != null) { obj = Get(type).GetEffectiveType(); if (obj == null) { return type; } } else { obj = null; } return (Type)obj; } protected abstract Type GetEffectiveType(); } internal sealed class FixedMemoryManager : MemoryManager { private unsafe byte* _pointer; private int _length; internal unsafe Memory Init(byte* pointer, int length) { _pointer = pointer; _length = length; return Memory; } public unsafe override Span GetSpan() { return new Span(_pointer, _length); } public override MemoryHandle Pin(int elementIndex = 0) { throw new NotSupportedException(); } public override void Unpin() { throw new NotSupportedException(); } protected override void Dispose(bool disposing) { } } internal static class GuidHelper { internal const int WRITE_BYTES_LENGTH = 16; internal const int WRITE_STRING_LENGTH = 36; internal const int MAX_LENGTH = 40; internal unsafe static Guid Read(ref ProtoReader.State state) { byte* ptr = stackalloc byte[40]; Span span = state.ReadBytes(new Span(ptr, 40)); char standardFormat; switch (span.Length) { case 0: return Guid.Empty; case 16: { int num = 32; for (int num2 = 15; num2 >= 0; num2--) { byte b = ptr[num2]; ptr[--num] = ToHex(b & 0xF); ptr[--num] = ToHex((b >> 4) & 0xF); } span = new Span(ptr, 32); standardFormat = 'N'; break; } case 32: standardFormat = 'N'; break; case 36: standardFormat = 'D'; break; default: ThrowHelper.Format($"Unexpected Guid length: {span.Length}"); return default(Guid); } if (!Utf8Parser.TryParse((ReadOnlySpan)span, out Guid value, out int bytesConsumed, standardFormat) || bytesConsumed != span.Length) { ThrowHelper.Format("Failed to read Guid: '" + Encoding.UTF8.GetString(ptr, span.Length) + "'"); } return value; static byte ToHex(int index) { return (byte)"0123456789abcdef"[index]; } } internal static void Write(ref ProtoWriter.State state, in Guid value, bool asBytes) { Guid guid = value; if (guid.Equals(Guid.Empty)) { state.WriteBytes(default(ReadOnlyMemory)); return; } byte[] array = ArrayPool.Shared.Rent(40); try { if (!Utf8Formatter.TryFormat(value, array, out var bytesWritten, asBytes ? 'N' : 'D')) { ThrowHelper.Format($"Failed to write Guid: '{value}'"); } if (asBytes) { int num = 0; for (int i = 0; i < 16; i++) { array[i] = (byte)((FromHex(array[num++]) << 4) | FromHex(array[num++])); } bytesWritten = 16; } state.WriteBytes(new ReadOnlyMemory(array, 0, bytesWritten)); } finally { ArrayPool.Shared.Return(array); } static int FromHex(int num2) { if (num2 >= 48 && num2 <= 57) { return num2 - 48; } if (num2 >= 97 && num2 <= 102) { return 10 + num2 - 97; } if (num2 >= 65 && num2 <= 70) { return 10 + num2 - 65; } Throw(num2); return 0; } static void Throw(int num2) { ThrowHelper.ThrowArgumentOutOfRangeException("value", $"Unexpected hex character: '{(char)num2}'"); } } } [StructLayout(LayoutKind.Auto)] internal readonly struct KeyValuePairSerializer : ISerializer> { private readonly ISerializer _keySerializer; private readonly ISerializer _valueSerializer; private readonly SerializerFeatures _keyFeatures; private readonly SerializerFeatures _valueFeatures; public SerializerFeatures Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; internal KeyValuePairSerializer(ISerializer keySerializer, SerializerFeatures keyFeatures, ISerializer valueSerializer, SerializerFeatures valueFeatures) { _keySerializer = keySerializer; _valueSerializer = valueSerializer; _keyFeatures = keyFeatures; _valueFeatures = valueFeatures; } public KeyValuePair Read(ref ProtoReader.State state, KeyValuePair pair) { TKey val = pair.Key; TValue value = pair.Value; int num; while ((num = state.ReadFieldHeader()) > 0) { switch (num) { case 1: val = state.ReadAny(_keyFeatures, val, _keySerializer); break; case 2: value = state.ReadAny(_valueFeatures, value, _valueSerializer); break; default: state.SkipField(); break; } } if (TypeHelper.IsReferenceType && TypeHelper.ValueChecker.IsNull(val)) { val = CreateDefault(state.Context, _keySerializer, _keyFeatures); } if (TypeHelper.IsReferenceType && TypeHelper.ValueChecker.IsNull(value)) { value = CreateDefault(state.Context, _valueSerializer, _valueFeatures); } return new KeyValuePair(val, value); } private static T CreateDefault(ISerializationContext context, ISerializer serializer, SerializerFeatures features) { if (features.HasAny(SerializerFeatures.OptionWrappedValue)) { return default(T); } if (serializer != null && serializer.Features.GetCategory() == SerializerFeatures.CategoryMessage) { ProtoReader.State state = ProtoReader.State.Create(default(ReadOnlyMemory), context?.Model, context?.UserState); try { return serializer.Read(ref state, default(T)); } finally { state.Dispose(); } } return TypeModel.CreateInstance(context, serializer); } public void Write(ref ProtoWriter.State state, KeyValuePair value) { if (TypeHelper.ValueChecker.HasNonTrivialValue(value.Key)) { state.WriteAny(1, _keyFeatures, value.Key, _keySerializer); } if (TypeHelper.ValueChecker.HasNonTrivialValue(value.Value)) { state.WriteAny(2, _valueFeatures, value.Value, _valueSerializer); } } } internal class Level240DefaultSerializer : ISerializer, ISerializer, ISerializer, ISerializer { SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; DateTime? ISerializer.Read(ref ProtoReader.State state, DateTime? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, DateTime? value) { ((ISerializer)this).Write(ref state, value.Value); } TimeSpan? ISerializer.Read(ref ProtoReader.State state, TimeSpan? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, TimeSpan? value) { ((ISerializer)this).Write(ref state, value.Value); } DateTime ISerializer.Read(ref ProtoReader.State state, DateTime value) { return PrimaryTypeProvider.ReadTimestamp(ref state, value); } void ISerializer.Write(ref ProtoWriter.State state, DateTime value) { PrimaryTypeProvider.WriteTimestamp(ref state, value); } TimeSpan ISerializer.Read(ref ProtoReader.State state, TimeSpan value) { return PrimaryTypeProvider.ReadDuration(ref state, value); } void ISerializer.Write(ref ProtoWriter.State state, TimeSpan value) { PrimaryTypeProvider.WriteDuration(ref state, value); } } internal class Level300DefaultSerializer : Level240DefaultSerializer, ISerializer, ISerializer, IValueChecker, ISerializer, ISerializer, IValueChecker { SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; bool IValueChecker.HasNonTrivialValue(decimal value) { return !value.Equals(0m); } bool IValueChecker.IsNull(decimal value) { return false; } bool IValueChecker.HasNonTrivialValue(Guid value) { return !value.Equals(Guid.Empty); } bool IValueChecker.IsNull(Guid value) { return false; } Guid ISerializer.Read(ref ProtoReader.State state, Guid value) { return GuidHelper.Read(ref state); } void ISerializer.Write(ref ProtoWriter.State state, Guid value) { GuidHelper.Write(ref state, in value, asBytes: false); } decimal ISerializer.Read(ref ProtoReader.State state, decimal value) { return BclHelpers.ReadDecimalString(ref state); } void ISerializer.Write(ref ProtoWriter.State state, decimal value) { BclHelpers.WriteDecimalString(ref state, value); } decimal? ISerializer.Read(ref ProtoReader.State state, decimal? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, decimal? value) { ((ISerializer)this).Write(ref state, value.Value); } Guid? ISerializer.Read(ref ProtoReader.State state, Guid? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, Guid? value) { ((ISerializer)this).Write(ref state, value.Value); } } internal sealed class Level300FixedSerializer : ISerializer, ISerializer, IValueChecker { SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; Guid ISerializer.Read(ref ProtoReader.State state, Guid value) { return GuidHelper.Read(ref state); } void ISerializer.Write(ref ProtoWriter.State state, Guid value) { GuidHelper.Write(ref state, in value, asBytes: true); } Guid? ISerializer.Read(ref ProtoReader.State state, Guid? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, Guid? value) { ((ISerializer)this).Write(ref state, value.Value); } bool IValueChecker.HasNonTrivialValue(Guid value) { return !value.Equals(Guid.Empty); } bool IValueChecker.IsNull(Guid value) { return false; } } internal static class Pool where T : class { [ThreadStatic] private static T ts_local; private const int POOL_SIZE = 20; private static readonly Queue s_pool = new Queue(20); internal static T TryGet() { T val = ts_local; if (val != null) { ts_local = null; return val; } return GetShared(); } internal static void Put(T obj) { if (obj != null) { if (ts_local == null) { ts_local = obj; } else { PutShared(obj); } } } private static T GetShared() { Queue queue = s_pool; lock (queue) { return (queue.Count == 0) ? null : queue.Dequeue(); } } private static void PutShared(T obj) { Queue queue = s_pool; lock (queue) { if (queue.Count < 20) { queue.Enqueue(obj); } } } } internal class PrimaryTypeProvider : ISerializer, ISerializer, ISerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer>, ISerializer>, IMeasuringSerializer>, ISerializer>, IMeasuringSerializer>, ISerializer>, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IFactory, IFactory, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IMeasuringSerializer, ISerializer, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, IValueChecker, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer, ISerializer { [StructLayout(LayoutKind.Explicit)] private readonly struct DecimalAccessor { [FieldOffset(0)] public readonly int Flags; [FieldOffset(4)] public readonly int Hi; [FieldOffset(8)] public readonly int Lo; [FieldOffset(12)] public readonly int Mid; [FieldOffset(0)] public readonly decimal Decimal; public DecimalAccessor(decimal value) { this = default(DecimalAccessor); Decimal = value; } } [StructLayout(LayoutKind.Explicit)] private readonly struct GuidAccessor { [FieldOffset(0)] public readonly Guid Guid; [FieldOffset(0)] public readonly ulong Low; [FieldOffset(8)] public readonly ulong High; public GuidAccessor(Guid value) { Low = (High = 0uL); Guid = value; } public GuidAccessor(ulong low, ulong high) { Guid = default(Guid); Low = low; High = high; } } [StructLayout(LayoutKind.Auto)] [ProtoContract(Name = ".bcl.TimeSpan")] internal readonly struct ScaledTicks { internal const int FieldTimeSpanValue = 1; internal const int FieldTimeSpanScale = 2; internal const int FieldTimeSpanKind = 3; [ProtoMember(1, DataFormat = DataFormat.ZigZag, Name = "value")] public long Value { get; } [ProtoMember(2, Name = "scale")] public TimeSpanScale Scale { get; } [ProtoMember(3, Name = "kind")] public DateTimeKind Kind { get; } public ScaledTicks(long value, TimeSpanScale scale, DateTimeKind kind) { Value = value; Scale = scale; Kind = kind; } public static ScaledTicks Create(DateTime value, bool includeKind) { if (value == DateTime.MinValue) { return new ScaledTicks(-1L, TimeSpanScale.MinMax, DateTimeKind.Unspecified); } if (value == DateTime.MaxValue) { return new ScaledTicks(1L, TimeSpanScale.MinMax, DateTimeKind.Unspecified); } DateTimeKind dateTimeKind = (includeKind ? value.Kind : DateTimeKind.Unspecified); return new ScaledTicks(value - BclHelpers.EpochOrigin[(int)dateTimeKind], dateTimeKind); } public DateTime ToDateTime() { long value; switch (Scale) { case TimeSpanScale.Days: value = Value * 864000000000L; break; case TimeSpanScale.Hours: value = Value * 36000000000L; break; case TimeSpanScale.Minutes: value = Value * 600000000; break; case TimeSpanScale.Seconds: value = Value * 10000000; break; case TimeSpanScale.Milliseconds: value = Value * 10000; break; case TimeSpanScale.Ticks: value = Value; break; case TimeSpanScale.MinMax: switch (Value) { case 1L: return DateTime.MaxValue; case -1L: return DateTime.MinValue; default: ThrowHelper.ThrowProtoException("Unknown min/max value: " + Value); return default(DateTime); } default: ThrowHelper.ThrowProtoException("Unknown timescale: " + Scale); return default(DateTime); } return BclHelpers.EpochOrigin[(int)Kind].AddTicks(value); } internal ScaledTicks(TimeSpan timeSpan, DateTimeKind kind) { long num = timeSpan.Ticks; TimeSpanScale timeSpanScale; if (timeSpan == TimeSpan.MaxValue) { num = 1L; timeSpanScale = TimeSpanScale.MinMax; } else if (timeSpan == TimeSpan.MinValue) { num = -1L; timeSpanScale = TimeSpanScale.MinMax; } else if (num % 864000000000L == 0L) { timeSpanScale = TimeSpanScale.Days; num /= 864000000000L; } else if (num % 36000000000L == 0L) { timeSpanScale = TimeSpanScale.Hours; num /= 36000000000L; } else if (num % 600000000 == 0L) { timeSpanScale = TimeSpanScale.Minutes; num /= 600000000; } else if (num % 10000000 == 0L) { timeSpanScale = TimeSpanScale.Seconds; num /= 10000000; } else if (num % 10000 == 0L) { timeSpanScale = TimeSpanScale.Milliseconds; num /= 10000; } else { timeSpanScale = TimeSpanScale.Ticks; } Kind = kind; Value = num; Scale = timeSpanScale; } public TimeSpan ToTimeSpan() { switch (Scale) { case TimeSpanScale.Days: return TimeSpan.FromDays(Value); case TimeSpanScale.Hours: return TimeSpan.FromHours(Value); case TimeSpanScale.Minutes: return TimeSpan.FromMinutes(Value); case TimeSpanScale.Seconds: return TimeSpan.FromSeconds(Value); case TimeSpanScale.Milliseconds: return TimeSpan.FromMilliseconds(Value); case TimeSpanScale.Ticks: return TimeSpan.FromTicks(Value); case TimeSpanScale.MinMax: switch (Value) { case 1L: return TimeSpan.MaxValue; case -1L: return TimeSpan.MinValue; default: ThrowHelper.ThrowProtoException("Unknown min/max value: " + Value); return default(TimeSpan); } default: ThrowHelper.ThrowProtoException("Unknown timescale: " + Scale); return default(TimeSpan); } } } private const int FieldDecimalLow = 1; private const int FieldDecimalHigh = 2; private const int FieldDecimalSignScale = 3; private static readonly bool s_decimalOptimized = VerifyDecimalLayout(); private static readonly bool s_guidOptimized = VerifyGuidLayout(); private const int FieldGuidLow = 1; private const int FieldGuidHigh = 2; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; internal static bool DecimalOptimized => s_decimalOptimized; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; internal static bool GuidOptimized => s_guidOptimized; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeFixed32 | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeFixed64 | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => ((ISerializer)this).Features; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessageWrappedAtRoot; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; SerializerFeatures ISerializer.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage; decimal? ISerializer.Read(ref ProtoReader.State state, decimal? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, decimal? value) { ((ISerializer)this).Write(ref state, value.Value); } decimal ISerializer.Read(ref ProtoReader.State state, decimal value) { ulong num = 0uL; uint num2 = 0u; uint num3 = 0u; int num4; while ((num4 = state.ReadFieldHeader()) > 0) { switch (num4) { case 1: num = state.ReadUInt64(); break; case 2: num2 = state.ReadUInt32(); break; case 3: num3 = state.ReadUInt32(); break; default: state.SkipField(); break; } } int lo = (int)(num & 0xFFFFFFFFu); int mid = (int)((num >> 32) & 0xFFFFFFFFu); int hi = (int)num2; bool isNegative = (num3 & 1) == 1; byte scale = (byte)((num3 & 0x1FE) >> 1); return new decimal(lo, mid, hi, isNegative, scale); } void ISerializer.Write(ref ProtoWriter.State state, decimal value) { ulong num3; uint num4; uint num5; if (s_decimalOptimized) { DecimalAccessor decimalAccessor = new DecimalAccessor(value); ulong num = (ulong)((long)decimalAccessor.Mid << 32); ulong num2 = (ulong)(decimalAccessor.Lo & 0xFFFFFFFFu); num3 = num | num2; num4 = (uint)decimalAccessor.Hi; num5 = (uint)(((decimalAccessor.Flags >> 15) & 0x1FE) | ((decimalAccessor.Flags >> 31) & 1)); } else { int[] bits = decimal.GetBits(value); ulong num6 = (ulong)((long)bits[1] << 32); ulong num7 = (ulong)(bits[0] & 0xFFFFFFFFu); num3 = num6 | num7; num4 = (uint)bits[2]; num5 = (uint)(((bits[3] >> 15) & 0x1FE) | ((bits[3] >> 31) & 1)); } if (num3 != 0L) { state.WriteFieldHeader(1, WireType.Variant); state.WriteUInt64(num3); } if (num4 != 0) { state.WriteFieldHeader(2, WireType.Variant); state.WriteUInt32(num4); } if (num5 != 0) { state.WriteFieldHeader(3, WireType.Variant); state.WriteUInt32(num5); } } private static bool VerifyDecimalLayout() { try { decimal num = 1.0000000000000000000000000000m; DecimalAccessor decimalAccessor = new DecimalAccessor(num); if ((decimalAccessor.Lo == 268435456) & (decimalAccessor.Mid == 1042612833) & (decimalAccessor.Hi == 542101086) & (decimalAccessor.Flags == 1835008)) { int[] bits = decimal.GetBits(num); if (bits.Length == 4) { return (decimalAccessor.Lo == bits[0]) & (decimalAccessor.Mid == bits[1]) & (decimalAccessor.Hi == bits[2]) & (decimalAccessor.Flags == bits[3]); } } } catch { } return false; } Guid? ISerializer.Read(ref ProtoReader.State state, Guid? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, Guid? value) { ((ISerializer)this).Write(ref state, value.Value); } Guid ISerializer.Read(ref ProtoReader.State state, Guid value) { ulong num = 0uL; ulong num2 = 0uL; int num3; while ((num3 = state.ReadFieldHeader()) > 0) { switch (num3) { case 1: num = state.ReadUInt64(); break; case 2: num2 = state.ReadUInt64(); break; default: state.SkipField(); break; } } if (num == 0 && num2 == 0) { return default(Guid); } if (s_guidOptimized) { return new GuidAccessor(num, num2).Guid; } uint num4 = (uint)(num >> 32); uint a = (uint)num; uint num5 = (uint)(num2 >> 32); uint num6 = (uint)num2; return new Guid((int)a, (short)num4, (short)(num4 >> 16), (byte)num6, (byte)(num6 >> 8), (byte)(num6 >> 16), (byte)(num6 >> 24), (byte)num5, (byte)(num5 >> 8), (byte)(num5 >> 16), (byte)(num5 >> 24)); } void ISerializer.Write(ref ProtoWriter.State state, Guid value) { if (!(value == Guid.Empty)) { if (s_guidOptimized) { GuidAccessor guidAccessor = new GuidAccessor(value); state.WriteFieldHeader(1, WireType.Fixed64); state.WriteUInt64(guidAccessor.Low); state.WriteFieldHeader(2, WireType.Fixed64); state.WriteUInt64(guidAccessor.High); } else { byte[] array = value.ToByteArray(); state.WriteFieldHeader(1, WireType.Fixed64); state.WriteBytes(new ReadOnlyMemory(array, 0, 8)); state.WriteFieldHeader(2, WireType.Fixed64); state.WriteBytes(new ReadOnlyMemory(array, 8, 8)); } } } private static bool VerifyGuidLayout() { try { if (!Guid.TryParse("12345678-2345-3456-4567-56789a6789ab", out var result)) { return false; } GuidAccessor guidAccessor = new GuidAccessor(result); ulong low = guidAccessor.Low; ulong high = guidAccessor.High; if (low != 3771240517534504568L || high != 12360524565436589893uL) { return false; } byte[] array = result.ToByteArray(); for (int i = 0; i < 8; i++) { if (array[i] != (byte)(low >> 8 * i)) { return false; } } for (int j = 0; j < 8; j++) { if (array[j + 8] != (byte)(high >> 8 * j)) { return false; } } return true; } catch { } return false; } string ISerializer.Read(ref ProtoReader.State state, string value) { return state.ReadString(); } void ISerializer.Write(ref ProtoWriter.State state, string value) { state.WriteString(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, string value) { if (wireType == WireType.String) { return ProtoWriter.UTF8.GetByteCount(value); } return -1; } int ISerializer.Read(ref ProtoReader.State state, int value) { return state.ReadInt32(); } void ISerializer.Write(ref ProtoWriter.State state, int value) { state.WriteInt32(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, int value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureInt32(value), WireType.SignedVariant => ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value)), _ => -1, }; } byte[] ISerializer.Read(ref ProtoReader.State state, byte[] value) { return state.AppendBytes(value); } void ISerializer.Write(ref ProtoWriter.State state, byte[] value) { state.WriteBytes(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, byte[] value) { if (wireType == WireType.String) { return value.Length; } return -1; } ArraySegment ISerializer>.Read(ref ProtoReader.State state, ArraySegment value) { return state.AppendBytes(value); } void ISerializer>.Write(ref ProtoWriter.State state, ArraySegment value) { state.WriteBytes(value); } int IMeasuringSerializer>.Measure(ISerializationContext context, WireType wireType, ArraySegment value) { if (wireType == WireType.String) { return value.Count; } return -1; } Memory ISerializer>.Read(ref ProtoReader.State state, Memory value) { return state.AppendBytes(value); } void ISerializer>.Write(ref ProtoWriter.State state, Memory value) { state.WriteBytes(value); } int IMeasuringSerializer>.Measure(ISerializationContext context, WireType wireType, Memory value) { if (wireType == WireType.String) { return value.Length; } return -1; } ReadOnlyMemory ISerializer>.Read(ref ProtoReader.State state, ReadOnlyMemory value) { return state.AppendBytes(value); } void ISerializer>.Write(ref ProtoWriter.State state, ReadOnlyMemory value) { state.WriteBytes(value); } int IMeasuringSerializer>.Measure(ISerializationContext context, WireType wireType, ReadOnlyMemory value) { if (wireType == WireType.String) { return value.Length; } return -1; } byte ISerializer.Read(ref ProtoReader.State state, byte value) { return state.ReadByte(); } void ISerializer.Write(ref ProtoWriter.State state, byte value) { state.WriteByte(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, byte value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureUInt32(value), _ => -1, }; } ushort ISerializer.Read(ref ProtoReader.State state, ushort value) { return state.ReadUInt16(); } void ISerializer.Write(ref ProtoWriter.State state, ushort value) { state.WriteUInt16(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, ushort value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureUInt32(value), _ => -1, }; } uint ISerializer.Read(ref ProtoReader.State state, uint value) { return state.ReadUInt32(); } void ISerializer.Write(ref ProtoWriter.State state, uint value) { state.WriteUInt32(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, uint value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureUInt32(value), _ => -1, }; } ulong ISerializer.Read(ref ProtoReader.State state, ulong value) { return state.ReadUInt64(); } void ISerializer.Write(ref ProtoWriter.State state, ulong value) { state.WriteUInt64(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, ulong value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureUInt64(value), _ => -1, }; } long ISerializer.Read(ref ProtoReader.State state, long value) { return state.ReadInt64(); } void ISerializer.Write(ref ProtoWriter.State state, long value) { state.WriteInt64(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, long value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureUInt64((ulong)value), WireType.SignedVariant => ProtoWriter.MeasureUInt64(ProtoWriter.Zig(value)), _ => -1, }; } bool ISerializer.Read(ref ProtoReader.State state, bool value) { return state.ReadBoolean(); } void ISerializer.Write(ref ProtoWriter.State state, bool value) { state.WriteBoolean(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, bool value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => 1, _ => -1, }; } float ISerializer.Read(ref ProtoReader.State state, float value) { return state.ReadSingle(); } void ISerializer.Write(ref ProtoWriter.State state, float value) { state.WriteSingle(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, float value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, _ => -1, }; } double ISerializer.Read(ref ProtoReader.State state, double value) { return state.ReadDouble(); } void ISerializer.Write(ref ProtoWriter.State state, double value) { state.WriteDouble(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, double value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, _ => -1, }; } sbyte ISerializer.Read(ref ProtoReader.State state, sbyte value) { return state.ReadSByte(); } void ISerializer.Write(ref ProtoWriter.State state, sbyte value) { state.WriteSByte(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, sbyte value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureInt32(value), WireType.SignedVariant => ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value)), _ => -1, }; } short ISerializer.Read(ref ProtoReader.State state, short value) { return state.ReadInt16(); } void ISerializer.Write(ref ProtoWriter.State state, short value) { state.WriteInt16(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, short value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureInt32(value), WireType.SignedVariant => ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value)), _ => -1, }; } Uri ISerializer.Read(ref ProtoReader.State state, Uri value) { string text = state.ReadString(); if (!string.IsNullOrEmpty(text)) { return new Uri(text, UriKind.RelativeOrAbsolute); } return null; } void ISerializer.Write(ref ProtoWriter.State state, Uri value) { state.WriteString(value.OriginalString); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, Uri value) { if (wireType == WireType.String) { return ProtoWriter.UTF8.GetByteCount(value.OriginalString); } return -1; } char ISerializer.Read(ref ProtoReader.State state, char value) { return (char)state.ReadUInt16(); } void ISerializer.Write(ref ProtoWriter.State state, char value) { state.WriteUInt16(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, char value) { return wireType switch { WireType.Fixed32 => 4, WireType.Fixed64 => 8, WireType.Variant => ProtoWriter.MeasureUInt32(value), _ => -1, }; } string IFactory.Create(ISerializationContext context) { return ""; } byte[] IFactory.Create(ISerializationContext context) { return Array.Empty(); } void ISerializer.Write(ref ProtoWriter.State state, int? value) { ((ISerializer)this).Write(ref state, value.Value); } int? ISerializer.Read(ref ProtoReader.State state, int? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, short? value) { ((ISerializer)this).Write(ref state, value.Value); } short? ISerializer.Read(ref ProtoReader.State state, short? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, long? value) { ((ISerializer)this).Write(ref state, value.Value); } long? ISerializer.Read(ref ProtoReader.State state, long? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, sbyte? value) { ((ISerializer)this).Write(ref state, value.Value); } sbyte? ISerializer.Read(ref ProtoReader.State state, sbyte? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, uint? value) { ((ISerializer)this).Write(ref state, value.Value); } uint? ISerializer.Read(ref ProtoReader.State state, uint? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, ushort? value) { ((ISerializer)this).Write(ref state, value.Value); } ushort? ISerializer.Read(ref ProtoReader.State state, ushort? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, ulong? value) { ((ISerializer)this).Write(ref state, value.Value); } ulong? ISerializer.Read(ref ProtoReader.State state, ulong? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, byte? value) { ((ISerializer)this).Write(ref state, value.Value); } byte? ISerializer.Read(ref ProtoReader.State state, byte? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, char? value) { ((ISerializer)this).Write(ref state, value.Value); } char? ISerializer.Read(ref ProtoReader.State state, char? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, bool? value) { ((ISerializer)this).Write(ref state, value.Value); } bool? ISerializer.Read(ref ProtoReader.State state, bool? value) { return ((ISerializer)this).Read(ref state, value == true); } void ISerializer.Write(ref ProtoWriter.State state, float? value) { ((ISerializer)this).Write(ref state, value.Value); } float? ISerializer.Read(ref ProtoReader.State state, float? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, double? value) { ((ISerializer)this).Write(ref state, value.Value); } double? ISerializer.Read(ref ProtoReader.State state, double? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } Type ISerializer.Read(ref ProtoReader.State state, Type value) { return state.ReadType(); } void ISerializer.Write(ref ProtoWriter.State state, Type value) { state.WriteType(value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, Type value) { if (wireType == WireType.String) { return Encoding.UTF8.GetByteCount(TypeModel.SerializeType(context?.Model, value)); } return -1; } bool IValueChecker.HasNonTrivialValue(string value) { return value != null; } bool IValueChecker.HasNonTrivialValue(Uri value) { return value?.OriginalString != null; } bool IValueChecker.HasNonTrivialValue(Type value) { return (object)value != null; } bool IValueChecker.HasNonTrivialValue(byte[] value) { return value != null; } bool IValueChecker.HasNonTrivialValue(sbyte value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(short value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(int value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(long value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(byte value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(ushort value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(uint value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(ulong value) { return value != 0; } bool IValueChecker.HasNonTrivialValue(char value) { return value != '\0'; } bool IValueChecker.HasNonTrivialValue(bool value) { return value; } bool IValueChecker.HasNonTrivialValue(float value) { return value != 0f; } bool IValueChecker.HasNonTrivialValue(double value) { return value != 0.0; } bool IValueChecker.IsNull(sbyte value) { return false; } bool IValueChecker.IsNull(short value) { return false; } bool IValueChecker.IsNull(int value) { return false; } bool IValueChecker.IsNull(long value) { return false; } bool IValueChecker.IsNull(byte value) { return false; } bool IValueChecker.IsNull(ushort value) { return false; } bool IValueChecker.IsNull(uint value) { return false; } bool IValueChecker.IsNull(ulong value) { return false; } bool IValueChecker.IsNull(char value) { return false; } bool IValueChecker.IsNull(bool value) { return false; } bool IValueChecker.IsNull(float value) { return false; } bool IValueChecker.IsNull(double value) { return false; } bool IValueChecker.IsNull(string value) { return value == null; } bool IValueChecker.IsNull(byte[] value) { return value == null; } bool IValueChecker.IsNull(Uri value) { return (object)value == null; } bool IValueChecker.IsNull(Type value) { return (object)value == null; } bool IValueChecker.HasNonTrivialValue(int? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(int? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(uint? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(uint? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(short? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(short? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(ushort? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(ushort? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(long? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(long? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(ulong? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(ulong? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(float? value) { return value.GetValueOrDefault() != 0f; } bool IValueChecker.IsNull(float? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(double? value) { return value.GetValueOrDefault() != 0.0; } bool IValueChecker.IsNull(double? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(byte? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(byte? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(sbyte? value) { return value.GetValueOrDefault() != 0; } bool IValueChecker.IsNull(sbyte? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(bool? value) { return value == true; } bool IValueChecker.IsNull(bool? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(char? value) { return value.GetValueOrDefault() != '\0'; } bool IValueChecker.IsNull(char? value) { return !value.HasValue; } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, int? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, long? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, float? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, double? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, byte? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, ushort? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, uint? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, ulong? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, sbyte? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, short? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, char? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, bool? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value); } void ISerializer.Write(ref ProtoWriter.State state, IntPtr? value) { ((ISerializer)this).Write(ref state, value.Value); } IntPtr? ISerializer.Read(ref ProtoReader.State state, IntPtr? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, UIntPtr? value) { ((ISerializer)this).Write(ref state, value.Value); } UIntPtr? ISerializer.Read(ref ProtoReader.State state, UIntPtr? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, IntPtr value) { state.WriteIntPtr(value); } IntPtr ISerializer.Read(ref ProtoReader.State state, IntPtr value) { return state.ReadIntPtr(); } void ISerializer.Write(ref ProtoWriter.State state, UIntPtr value) { state.WriteUIntPtr(value); } UIntPtr ISerializer.Read(ref ProtoReader.State state, UIntPtr value) { return state.ReadUIntPtr(); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, IntPtr value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.ToInt64()); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, UIntPtr value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.ToUInt64()); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, IntPtr? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value.ToInt64()); } int IMeasuringSerializer.Measure(ISerializationContext context, WireType wireType, UIntPtr? value) { return ((IMeasuringSerializer)this).Measure(context, wireType, value.Value.ToUInt64()); } bool IValueChecker.HasNonTrivialValue(IntPtr value) { return value != IntPtr.Zero; } bool IValueChecker.IsNull(IntPtr value) { return false; } bool IValueChecker.HasNonTrivialValue(UIntPtr value) { return value != UIntPtr.Zero; } bool IValueChecker.IsNull(UIntPtr value) { return false; } bool IValueChecker.HasNonTrivialValue(IntPtr? value) { return value.GetValueOrDefault() != IntPtr.Zero; } bool IValueChecker.IsNull(IntPtr? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(UIntPtr? value) { return value.GetValueOrDefault() != UIntPtr.Zero; } bool IValueChecker.IsNull(UIntPtr? value) { return !value.HasValue; } TimeSpan? ISerializer.Read(ref ProtoReader.State state, TimeSpan? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, TimeSpan? value) { ((ISerializer)this).Write(ref state, value.Value); } DateTime? ISerializer.Read(ref ProtoReader.State state, DateTime? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, DateTime? value) { ((ISerializer)this).Write(ref state, value.Value); } TimeSpan ISerializer.Read(ref ProtoReader.State state, TimeSpan value) { return ((ISerializer)this).Read(ref state, default(ScaledTicks)).ToTimeSpan(); } void ISerializer.Write(ref ProtoWriter.State state, TimeSpan value) { ((ISerializer)this).Write(ref state, new ScaledTicks(value, DateTimeKind.Unspecified)); } DateTime ISerializer.Read(ref ProtoReader.State state, DateTime value) { return ((ISerializer)this).Read(ref state, default(ScaledTicks)).ToDateTime(); } void ISerializer.Write(ref ProtoWriter.State state, DateTime value) { bool includeKind = state.Model.HasOption(TypeModel.TypeModelOptions.IncludeDateTimeKind); ((ISerializer)this).Write(ref state, ScaledTicks.Create(value, includeKind)); } void ISerializer.Write(ref ProtoWriter.State state, ScaledTicks value) { if (value.Value != 0L) { state.WriteFieldHeader(1, WireType.SignedVariant); state.WriteInt64(value.Value); } if (value.Scale != TimeSpanScale.Days) { state.WriteFieldHeader(2, WireType.Variant); state.WriteInt32((int)value.Scale); } if (value.Kind != DateTimeKind.Unspecified) { state.WriteFieldHeader(3, WireType.Variant); state.WriteInt32((int)value.Kind); } } ScaledTicks ISerializer.Read(ref ProtoReader.State state, ScaledTicks _) { TimeSpanScale scale = TimeSpanScale.Days; long value = 0L; DateTimeKind dateTimeKind = DateTimeKind.Unspecified; int num; while ((num = state.ReadFieldHeader()) > 0) { switch (num) { case 2: scale = (TimeSpanScale)state.ReadInt32(); break; case 1: state.Assert(WireType.SignedVariant); value = state.ReadInt64(); break; case 3: dateTimeKind = (DateTimeKind)state.ReadInt32(); if ((uint)dateTimeKind > 2u) { ThrowHelper.ThrowProtoException("Invalid date/time kind: " + dateTimeKind); } break; default: state.SkipField(); break; } } return new ScaledTicks(value, scale, dateTimeKind); } Duration? ISerializer.Read(ref ProtoReader.State state, Duration? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, Duration? value) { ((ISerializer)this).Write(ref state, value.Value); } Duration ISerializer.Read(ref ProtoReader.State state, Duration value) { return ReadDuration(ref state, value); } internal static Duration ReadDuration(ref ProtoReader.State state, Duration value) { if (state.WireType == WireType.String && state.RemainingInCurrent >= 20 && TryReadDurationFast(ref state, ref value)) { return value; } return ReadDurationFallback(ref state, value); } private static bool TryReadDurationFast(ref ProtoReader.State state, ref Duration value) { int offsetInCurrent = state.OffsetInCurrent; ReadOnlySpan span = state.Span; uint value2; int num = state.ParseVarintUInt32(span, offsetInCurrent, out value2); offsetInCurrent += num; if (value2 == 0) { return true; } if (num + value2 > state.RemainingInCurrent) { return false; } if (span[offsetInCurrent] != 8) { return false; } ulong value3; int num2 = 1 + ProtoReader.State.TryParseUInt64Varint(span, 1 + offsetInCurrent, out value3); int nanoseconds = value.Nanoseconds; if (num2 < value2) { if (span[num2++ + offsetInCurrent] != 16) { return false; } num2 += ProtoReader.State.TryParseUInt64Varint(span, num2 + offsetInCurrent, out var value4); nanoseconds = (int)value4; } if (num2 != value2) { return false; } state.Skip(num + (int)value2); state.Advance(num + value2); value = new Duration((long)value3, nanoseconds); return true; } private static Duration ReadDurationFallback(ref ProtoReader.State state, Duration value) { long seconds = value.Seconds; int nanoseconds = value.Nanoseconds; int num; while ((num = state.ReadFieldHeader()) > 0) { switch (num) { case 1: seconds = state.ReadInt64(); break; case 2: nanoseconds = state.ReadInt32(); break; default: state.SkipField(); break; } } return new Duration(seconds, nanoseconds); } void ISerializer.Write(ref ProtoWriter.State state, Duration value) { WriteSecondsNanos(ref state, value.Seconds, value.Nanoseconds, isTimestamp: false); } internal static void WriteDuration(ref ProtoWriter.State state, Duration value) { WriteSecondsNanos(ref state, value.Seconds, value.Nanoseconds, isTimestamp: false); } internal static long ToDurationSeconds(long ticks, out int nanos, bool isTimestamp) { nanos = (int)(ticks % 10000000 * 1000000 / 10000); long seconds = ticks / 10000000; NormalizeSecondsNanoseconds(ref seconds, ref nanos, isTimestamp); return seconds; } internal static long ToTicks(long seconds, int nanos) { checked { return seconds * 10000000 + unchecked(checked(unchecked((long)nanos) * 10000L) / 1000000); } } internal static void NormalizeSecondsNanoseconds(ref long seconds, ref int nanos, bool isTimestamp) { seconds += nanos / 1000000000; nanos %= 1000000000; if (isTimestamp) { if (nanos < 0) { seconds--; nanos += 1000000000; } return; } if (nanos < 0 && seconds >= 0) { seconds--; nanos += 1000000000; } if (nanos > 0 && seconds < 0) { nanos -= 1000000000; seconds++; } } private static void WriteSecondsNanos(ref ProtoWriter.State state, long seconds, int nanos, bool isTimestamp) { NormalizeSecondsNanoseconds(ref seconds, ref nanos, isTimestamp); if (seconds != 0L) { state.WriteFieldHeader(1, WireType.Variant); state.WriteInt64(seconds); } if (nanos != 0) { state.WriteFieldHeader(2, WireType.Variant); state.WriteInt32(nanos); } } Empty ISerializer.Read(ref ProtoReader.State state, Empty value) { state.SkipAllFields(); return value; } void ISerializer.Write(ref ProtoWriter.State state, Empty value) { } Empty? ISerializer.Read(ref ProtoReader.State state, Empty? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, Empty? value) { ((ISerializer)this).Write(ref state, value.Value); } Timestamp ISerializer.Read(ref ProtoReader.State state, Timestamp value) { Duration value2 = new Duration(value.Seconds, value.Nanoseconds); value2 = ReadDuration(ref state, value2); return new Timestamp(value2.Seconds, value2.Nanoseconds); } internal static Timestamp ReadTimestamp(ref ProtoReader.State state, Timestamp value) { Duration value2 = new Duration(value.Seconds, value.Nanoseconds); value2 = ReadDuration(ref state, value2); return new Timestamp(value2.Seconds, value2.Nanoseconds); } void ISerializer.Write(ref ProtoWriter.State state, Timestamp value) { WriteSecondsNanos(ref state, value.Seconds, value.Nanoseconds, isTimestamp: true); } internal static void WriteTimestamp(ref ProtoWriter.State state, Timestamp value) { WriteSecondsNanos(ref state, value.Seconds, value.Nanoseconds, isTimestamp: true); } Timestamp? ISerializer.Read(ref ProtoReader.State state, Timestamp? value) { return ((ISerializer)this).Read(ref state, value.GetValueOrDefault()); } void ISerializer.Write(ref ProtoWriter.State state, Timestamp? value) { ((ISerializer)this).Write(ref state, value.Value); } } [StructLayout(LayoutKind.Auto)] internal struct ReadBuffer : IDisposable, ICollection, IEnumerable, IEnumerable, IReadOnlyCollection, ICollection { private T[] _arr; private int _count; readonly bool ICollection.IsReadOnly => false; readonly bool ICollection.IsSynchronized => false; readonly object ICollection.SyncRoot => _arr; public readonly bool IsEmpty => _count == 0; public readonly int Count => _count; public readonly ArraySegment Segment => new ArraySegment(_arr, 0, _count); public readonly Span Span => new Span(_arr, 0, _count); public void Clear() { _count = 0; } public readonly void CopyTo(T[] array, int arrayIndex = 0) { Array.Copy(_arr, 0, array, arrayIndex, _count); } readonly void ICollection.CopyTo(Array array, int index) { Array.Copy(_arr, 0, array, index, _count); } public T[] ToArray() { if (_count == 0) { return Array.Empty(); } T[] array = new T[_count]; CopyTo(array); return array; } public T[] ToArray(T[] prepend) { int num = ((prepend != null) ? prepend.Length : 0); if (num == 0) { return ToArray(); } if (_count == 0) { return prepend ?? Array.Empty(); } T[] array = new T[num + _count]; Array.Copy(prepend, 0, array, 0, num); Array.Copy(_arr, 0, array, num, _count); return array; } readonly bool ICollection.Contains(T item) { return Array.IndexOf(_arr, item, 0, _count) >= 0; } bool ICollection.Remove(T item) { int num = Array.IndexOf(_arr, item, 0, _count); if (num < 0) { return false; } _count--; Array.Copy(_arr, num + 1, _arr, num, _count - num); return true; } public readonly IEnumerator GetEnumerator() { return _arr.Take(_count).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private ReadBuffer(int minimumLength) { _arr = ArrayPool.Shared.Rent(minimumLength); _count = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadBuffer Create(int minimumLength = 16) { return new ReadBuffer(minimumLength); } private static void Recyle(ref T[] array) { if (array != null) { bool clearArray = RuntimeHelpers.IsReferenceOrContainsReferences(); ArrayPool.Shared.Return(array, clearArray); array = null; } } public void Dispose() { _count = 0; Recyle(ref _arr); } [MethodImpl(MethodImplOptions.NoInlining)] private void Grow() { uint num = (uint)_arr.Length; uint num2 = Math.Min(num * 2, 2146435071u); if (num == num2) { ThrowHelper.ThrowInvalidOperationException("maximum array size exceeded"); } T[] array = ArrayPool.Shared.Rent((int)num2); Array.Copy(_arr, 0, array, 0, _arr.Length); Recyle(ref _arr); _arr = array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Add(T value) { int num = _count++; if (num == _arr.Length) { Grow(); } _arr[num] = value; } } internal static class ThrowHelper { [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowArgumentOutOfRangeException(string paramName) { throw new ArgumentOutOfRangeException(paramName); } [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowArgumentOutOfRangeException(string paramName, string message) { throw new ArgumentOutOfRangeException(paramName, message); } [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowArgumentNullException(string paramName) { throw new ArgumentNullException(paramName); } [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowArgumentNullException(string paramName, string message) { throw new ArgumentNullException(paramName, message); } [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowIndexOutOfRangeException() { throw new IndexOutOfRangeException(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException(string message, string paramName) { throw new ArgumentException(message, paramName); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void Format(string message) { throw new FormatException(message); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException(string message) { throw new ArgumentException(message); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion() { throw new InvalidOperationException("Collection was modified; enumeration operation may not execute."); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException(string message = null, Exception innerException = null) { if (string.IsNullOrWhiteSpace(message)) { if (innerException == null) { throw new InvalidOperationException(); } throw new InvalidOperationException(innerException.Message, innerException); } if (innerException == null) { throw new InvalidOperationException(message); } throw new InvalidOperationException(message, innerException); } internal static void NoSerializerDefined(Type type) { InvalidOperationException ex = new InvalidOperationException("No serializer defined for type: " + type.NormalizeName()); if ((object)type != null && type.FindInterfaces((Type i, object _) => i.FullName == "Google.Protobuf.IMessage", null).Length != 0) { try { throw ex; } catch (Exception innerException) { ex = new InvalidOperationException("Type '" + type.NormalizeName() + "' looks like a Google.Protobuf type; it cannot be used directly with protobuf-net without manual configuration; it may be possible to generate a protobuf-net type instead; see https://protobuf-net.github.io/protobuf-net/contract_first", innerException); } } throw ex; } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNotSupportedException() { throw new NotSupportedException(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNotSupportedException(string message) { throw new NotSupportedException(message); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowProtoException(string message, Exception inner = null) { throw (inner == null) ? new ProtoException(message) : new ProtoException(message, inner); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowOverflowException() { throw new OverflowException(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNotImplementedException([CallerMemberName] string message = null) { throw new NotImplementedException(message); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNullReferenceException() { throw new NullReferenceException(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNullRepeatedContents() { throw new NullReferenceException("An element of type " + typeof(T).NormalizeName() + " was null; this might be as contents in a list/array"); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowTrackedObjects(object obj) { throw new NotSupportedException("tracked objects and featured related to stream rewriting are not supported on " + obj.GetType().Name); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowNestedDataNotSupported(Type declaringType) { throw new NotSupportedException("Nested or jagged lists, arrays and maps are not supported: " + declaringType.NormalizeName()); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidPackedOperationException(WireType wireType, Type type) { throw new ProtoException($"Invalid wire-type for packed encoding: {wireType}; processing {type.NormalizeName()}"); } } internal static class TypeHelper { internal static string NormalizeName(this Type type) { return type?.ToString() ?? "(null)"; } internal static bool CanBePacked(Type type) { type = Nullable.GetUnderlyingType(type) ?? type; if (type.IsEnum) { return true; } TypeCode typeCode = Type.GetTypeCode(type); if ((uint)(typeCode - 3) <= 11u) { return true; } return false; } internal static bool IsBytesLike(Type type) { if (type == typeof(byte[])) { return true; } if (type == typeof(Memory)) { return true; } if (type == typeof(ReadOnlyMemory)) { return true; } if (type == typeof(ArraySegment)) { return true; } return false; } [Obsolete("Prefer list provider")] internal static bool ResolveUniqueEnumerableT(Type type, out Type t) { if ((object)type == null || type == typeof(string) || IsBytesLike(type) || type == typeof(object)) { t = null; return false; } if (type.IsArray) { t = type.GetElementType(); return type == t.MakeArrayType(); } bool flag = false; t = null; try { if (IsEnumerableT(type, out t)) { return true; } Type[] interfaces = type.GetInterfaces(); foreach (Type type2 in interfaces) { if (IsEnumerableT(type2, out var t2)) { if (flag && t2 != t) { flag = false; break; } flag = true; t = t2; } } } catch { } if (flag) { return true; } t = null; return false; static bool IsEnumerableT(Type type3, out Type reference) { if (type3.IsInterface && type3.IsGenericType && type3.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { reference = type3.GetGenericArguments()[0]; return true; } reference = null; return false; } } internal static object GetValueTypeChecker(Type type) { Type type2 = Nullable.GetUnderlyingType(type) ?? type; return typeof(StructValueChecker<>).MakeGenericType(type2).GetField("Instance").GetValue(null); } internal static object CreateNonTrivialDefault(Type type) { if (type.IsValueType) { return Activator.CreateInstance(Nullable.GetUnderlyingType(type) ?? type); } if (type == typeof(string)) { return ""; } if (type == typeof(byte[])) { return Array.Empty(); } return null; } } internal static class TypeHelper { public static readonly bool IsReferenceType = !typeof(T).IsValueType; public static readonly bool CanBeNull = default(T) == null; public static readonly IValueChecker ValueChecker = (SerializerCache.InstanceField as IValueChecker) ?? (ReferenceValueChecker.Instance as IValueChecker) ?? ((IValueChecker)TypeHelper.GetValueTypeChecker(typeof(T))); public static readonly bool CanBePacked = !IsReferenceType && TypeHelper.CanBePacked(typeof(T)); public static readonly T Default = ((typeof(T) == typeof(string)) ? ((T)(object)"") : default(T)); public static readonly T NonTrivialDefault; public static readonly Func Factory; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T FromObject(object value) { if (value != null) { return (T)value; } return default(T); } static TypeHelper() { T val = Default; NonTrivialDefault = ((val != null) ? val : ((T)TypeHelper.CreateNonTrivialDefault(typeof(T)))); Factory = (ISerializationContext ctx) => TypeModel.CreateInstance(ctx); } } internal interface IValueChecker { bool HasNonTrivialValue(T value); bool IsNull(T value); } internal sealed class ReferenceValueChecker : IValueChecker { public static readonly ReferenceValueChecker Instance = new ReferenceValueChecker(); private ReferenceValueChecker() { } bool IValueChecker.HasNonTrivialValue(object value) { return value != null; } bool IValueChecker.IsNull(object value) { return value == null; } } internal sealed class StructValueChecker : IValueChecker, IValueChecker where T : struct { public static readonly StructValueChecker Instance = new StructValueChecker(); private StructValueChecker() { } bool IValueChecker.HasNonTrivialValue(T? value) { return value.HasValue; } bool IValueChecker.IsNull(T? value) { return !value.HasValue; } bool IValueChecker.HasNonTrivialValue(T value) { return true; } bool IValueChecker.IsNull(T value) { return false; } } }