<|start_filename|>src/Examples/Issues/SO11871726.cs<|end_filename|>
﻿using Xunit;
using ProtoBuf.Meta;
using System;
using System.Runtime.Serialization;

namespace Examples.Issues
{
    
    public class SO11871726
    {
        [Fact]
        public void ExecuteWithoutAutoAddProtoContractTypesOnlyShouldWork()
        {
            var model = RuntimeTypeModel.Create();
            Assert.IsType<Foo>(model.DeepClone(new Foo()));
        }
        [Fact]
        public void ExecuteWithAutoAddProtoContractTypesOnlyShouldFail()
        {
            Program.ExpectFailure<InvalidOperationException>(() =>
            {
                var model = RuntimeTypeModel.Create();
                model.AutoAddProtoContractTypesOnly = true;
                Assert.IsType<Foo>(model.DeepClone(new Foo()));
            }, "Type is not expected, and no contract can be inferred: Examples.Issues.SO11871726+Foo");
        }

        [DataContract]
        public class Foo { }
    }
}


<|start_filename|>src/protobuf-net.Core/ProtoReservedAttribute.cs<|end_filename|>
﻿using System;

namespace ProtoBuf
{
    /// <summary>
    /// Indicates a reserved field or range
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true, Inherited = false)]
    public sealed class ProtoReservedAttribute : Attribute
    {
        /// <summary>
        /// The start of a numeric field range
        /// </summary>
        public int From { get; }
        /// <summary>
        /// The end of a numeric field range
        /// </summary>
        public int To { get; }
        /// <summary>
        /// A named field reservation
        /// </summary>
        public string Name { get; }
        /// <summary>
        /// Creates a new instance of a single number field reservation
        /// </summary>
        public ProtoReservedAttribute(int field, string comment = null) : this(field, field, comment) { }
        /// <summary>
        /// Creates a new instance of a range number field reservation
        /// </summary>
        public ProtoReservedAttribute(int from, int to, string comment = null)
        {
            From = from;
            To = to;
            Comment = comment;
        }
        /// <summary>
        /// Records a comment explaining this reservation
        /// </summary>
        public string Comment { get; }
        /// <summary>
        /// Creates a new instance of a named field reservation
        /// </summary>
        public ProtoReservedAttribute(string field, string comment = null)
        {
            Name = field;
            Comment = comment;
        }

        internal void Verify()
        {
            const string Message = "Invalid reservation definition";
            if (string.IsNullOrWhiteSpace(Name))
            {
                if (From <= 0) throw new ArgumentOutOfRangeException(nameof(From), Message);
                if (To < From) throw new ArgumentOutOfRangeException(nameof(To), Message);
            }
        }
    }
}


<|start_filename|>src/protobuf-net.Core/MeasureState.cs<|end_filename|>
﻿using ProtoBuf.Internal;
using ProtoBuf.Meta;
using System;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.IO;

namespace ProtoBuf
{
    /// <summary>
    /// Represents the outcome of computing the length of an object; since this may have required computing lengths
    /// for multiple objects, some metadata is retained so that a subsequent serialize operation using
    /// this instance can re-use the previously calculated lengths. If the object state changes between the
    /// measure and serialize operations, the behavior is undefined.
    /// </summary>
    public struct MeasureState<[DynamicallyAccessedMembers(DynamicAccess.ContractType)] T> : IDisposable
    {
        private readonly TypeModel _model;
        private readonly T _value;
        private readonly object _userState;
        private ProtoWriter _writer;

        internal MeasureState(TypeModel model, in T value, object userState, long abortAfter)
        {
            _model = model;
            _value = value;
            _userState = userState;
            var nullState = ProtoWriter.NullProtoWriter.CreateNullProtoWriter(_model, userState, abortAfter);
            try
            {
                Length = TypeModel.SerializeImpl<T>(ref nullState, _value);
                ProtoWriter.NullProtoWriter.CheckOversized(abortAfter, Length);
                _writer = nullState.GetWriter();
            }
            catch
            {
                nullState.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Releases all resources associated with this value
        /// </summary>
        public void Dispose()
        {
            var writer = _writer;
            _writer = null;
            writer?.Dispose();
        }

        /// <summary>
        /// Gets the calculated length of this serialize operation, in bytes
        /// </summary>
        public long Length { get; }

        /// <summary>
        /// Returns the calculated length, disposing the value as a side-effect
        /// </summary>
        public long LengthOnly()
        {
            var len = Length;
            Dispose();
            return len;
        }

        private void SerializeCore(ProtoWriter.State state)
        {
            try
            {
                var writer = _writer;
                if (writer is null) throw new ObjectDisposedException(nameof(MeasureState<T>));

                var targetWriter = state.GetWriter();
                targetWriter.InitializeFrom(writer);
                long actual = TypeModel.SerializeImpl<T>(ref state, _value);
                targetWriter.CopyBack(writer);

                if (actual != Length) ThrowHelper.ThrowInvalidOperationException($"Invalid length; expected {Length}, actual: {actual}");
            }
            catch (Exception ex)
            {
                ex.Data?.Add("ProtoBuf.MeasuredLength", Length);
                throw;
            }
            finally
            {
                state.Dispose();
            }
        }

        internal int GetLengthHits(out int misses) => _writer.GetLengthHits(out misses);

        /// <summary>
        /// Perform the calculated serialization operation against the provided target stream. If the object state changes between the
        /// measure and serialize operations, the behavior is undefined.
        /// </summary>
        public void Serialize(Stream stream) => SerializeCore(ProtoWriter.State.Create(stream, _model, _userState));

        /// <summary>
        /// Perform the calculated serialization operation against the provided target writer. If the object state changes between the
        /// measure and serialize operations, the behavior is undefined.
        /// </summary>
        public void Serialize(IBufferWriter<byte> writer) => SerializeCore(ProtoWriter.State.Create(writer, _model, _userState));
    }
}


<|start_filename|>src/protobuf-net.Core/ProtoWriter.Null.cs<|end_filename|>
using ProtoBuf.Internal;
using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using System;
using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;

namespace ProtoBuf
{
    public partial class ProtoWriter
    {
        internal static State CreateNull(TypeModel model, object userState, long abortAfter)
            => NullProtoWriter.CreateNullProtoWriter(model, userState, abortAfter);

        internal sealed class NullProtoWriter : ProtoWriter
        {
            protected internal override State DefaultState() => new State(this);

            internal static State CreateNullProtoWriter(TypeModel model, object userState, long abortAfter)
            {
                var obj = Pool<NullProtoWriter>.TryGet() ?? new NullProtoWriter();
                obj.Init(model, userState, true);
                obj._abortAfter = abortAfter < 0 ? long.MaxValue : abortAfter;
                return new State(obj);
            }

            private long _abortAfter;

            private NullProtoWriter() { } // gets own object cache

            // this is for use as a sub-component of the buffer-writer
            internal NullProtoWriter(NetObjectCache knownObjects)
                : base(knownObjects)
            {
                _abortAfter = long.MaxValue;
            }

            internal override void Dispose()
            {
                base.Dispose();
                Pool<NullProtoWriter>.Put(this);
            }

            private protected override bool ImplDemandFlushOnDispose => false;

            private protected override void ImplCopyRawFromStream(ref State state, Stream source)
            {
                var buffer = ArrayPool<byte>.Shared.Rent(8 * 1024);
                try
                {
                    while (true)
                    {
                        int bytes = source.Read(buffer, 0, buffer.Length);
                        if (bytes <= 0) break;
                        Advance(bytes);
                        CheckOversized(ref state);
                    }
                }
                finally
                {
                    ArrayPool<byte>.Shared.Return(buffer);
                }
            }

            [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(ProtoReader.HotPath)]
            private void CheckOversized(ref State state)
            {
                var position = state.GetPosition();
                if (position > _abortAfter) CheckOversized(_abortAfter, position);
            }

            protected internal override void WriteMessage<T>(ref State state, T value, ISerializer<T> serializer, PrefixStyle style, bool recursionCheck)
            {
                if (serializer is null) serializer = TypeModel.GetSerializer<T>(Model);
                var len = Measure<T>(this, value, serializer);
                AdvanceSubMessage(ref state, len, style);
            }
            private void AdvanceSubMessage(ref State state, long length, PrefixStyle style)
            {
                long preamble;
                switch (WireType)
                {
                    case WireType.String:
                    case WireType.Fixed32:
                        switch (style)
                        {
                            case PrefixStyle.None:
                                preamble = 0;
                                break;
                            case PrefixStyle.Fixed32:
                            case PrefixStyle.Fixed32BigEndian:
                                preamble = 4;
                                break;
                            case PrefixStyle.Base128:
                                preamble = ImplWriteVarint64(ref state, (ulong)length);
                                break;
                            default:
                                state.ThrowInvalidSerializationOperation();
                                preamble = default;
                                break;
                        }
                        break;
                    case WireType.StartGroup:
                        // the start group is already written, so w just need to leave the end group
                        preamble = ImplWriteVarint32(ref state, (uint)(fieldNumber << 3));
                        break;
                    default:
                        state.ThrowInvalidSerializationOperation();
                        preamble = default;
                        break;
                }
                Advance(preamble + length);
                CheckOversized(ref state);
                WireType = WireType.None;
            }
            protected internal override void WriteSubType<T>(ref State state, T value, ISubTypeSerializer<T> serializer)
            {
                if (serializer is null) serializer = TypeModel.GetSubTypeSerializer<T>(Model);
                var len = Measure<T>(this, value, serializer);
                AdvanceSubMessage(ref state, len, PrefixStyle.Base128);
            }

            private protected override SubItemToken ImplStartLengthPrefixedSubItem(ref State state, object instance, PrefixStyle style)
            {
                WireType = WireType.None;
                return new SubItemToken(_position64);
            }

            private protected override void ImplEndLengthPrefixedSubItem(ref State state, SubItemToken token, PrefixStyle style)
            {
                var len = _position64 - token.value64;
                int bytes;
                switch(style)
                {
                    case PrefixStyle.Fixed32BigEndian:
                    case PrefixStyle.Fixed32:
                        bytes = 4;
                        break;
                    case PrefixStyle.Base128:
                        bytes = ImplWriteVarint64(ref state, (ulong)len);
                        break;
                    default:
                        state.ThrowInvalidSerializationOperation();
                        goto case PrefixStyle.None;
                    case PrefixStyle.None:
                        bytes = 0;
                        break;
                }
                Advance(bytes);
                CheckOversized(ref state);
            }

            private protected override void ImplWriteBytes(ref State state, ReadOnlyMemory<byte> data) { }

            private protected override void ImplWriteBytes(ref State state, ReadOnlySequence<byte> 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(ProtoReader.HotPath)]
            private protected override int ImplWriteVarint32(ref State state, uint value) => MeasureUInt32(value);

            [MethodImpl(ProtoReader.HotPath)]
            internal override int ImplWriteVarint64(ref State state, ulong value) => MeasureUInt64(value);

            private protected override bool TryFlush(ref State state) => true;
        }

        [MethodImpl(ProtoReader.HotPath)]
        internal static int MeasureUInt32(uint value)
        {
#if PLAT_INTRINSICS
            return ((31 - System.Numerics.BitOperations.LeadingZeroCount(value | 1)) / 7) + 1;
#else
            int count = 1;
            while ((value >>= 7) != 0)
            {
                count++;
            }
            return count;
#endif
        }

        [MethodImpl(ProtoReader.HotPath)]
        internal static int MeasureUInt64(ulong value)
        {
#if PLAT_INTRINSICS
            return ((63 - System.Numerics.BitOperations.LeadingZeroCount(value | 1)) / 7) + 1;
#else
            int count = 1;
            while ((value >>= 7) != 0)
            {
                count++;
            }
            return count;
#endif
        }
    }
}

<|start_filename|>src/NativeGoogleTests/NodaTimeTests.cs<|end_filename|>
using Google.Protobuf;
using NodaTime.Serialization.Protobuf;
using ProtoBuf.Test;
using System;
using Xunit;
using Xunit.Abstractions;

namespace NativeGoogleTests
{
    public class NodaTimeTests
    {
        private readonly ITestOutputHelper _log;
        public NodaTimeTests(ITestOutputHelper log) => _log = log;
        private string Log(string message)
        {
            _log?.WriteLine(message);
            return message;
        }

        [Fact]
        public void TestExpectedBinaryOutputDuration()
        {
            var duration = NodaTime.Duration.FromTimeSpan(new TimeSpan(42, 1, 10, 12, 451));
            var obj = new HazNodaTimeDuration { Id = 42, Name = "abc", Time = duration.ToProtobufDuration() };
            var hex = Log(BitConverter.ToString(obj.ToByteArray()));

            // this is the same output as noted in AssertBytesFromTimeSpanModel
            Assert.Equal("08-2A-12-0B-08-F4-DE-DD-01-10-C0-ED-86-D7-01-1A-03-61-62-63", hex);
        }
        
        [Fact]
        public void TestExpectedBinaryOutputInterval()
        {
            var when = NodaTime.Instant.FromDateTimeUtc(new DateTime(2020, 8, 23, 8, 51, 12, 451, DateTimeKind.Utc));
            var obj = new HazNodaTimeInstant() { Id = 42, Name = "abc", Time = when.ToTimestamp() };
            var hex = Log(BitConverter.ToString(obj.ToByteArray()));

            // this is the same output as noted in AssertBytesFromDateTimeModel
            Assert.Equal("08-2A-12-0C-08-80-DC-88-FA-05-10-C0-ED-86-D7-01-1A-03-61-62-63", hex);
        }

        [Fact]
        public void AllCommonTypesSupported()
        {
            var duration = NodaTime.Duration.FromTimeSpan(new TimeSpan(42, 1, 10, 12, 451));
            var when = NodaTime.Instant.FromDateTimeUtc(new DateTime(2020, 8, 23, 8, 51, 12, 451, DateTimeKind.Utc));
            var ld = new NodaTime.LocalDate(2020, 8, 25);
            var lt = new NodaTime.LocalTime(11, 15, 43).PlusNanoseconds(43256);
            var dow = NodaTime.IsoDayOfWeek.Thursday;

            var obj = new MakeMeOneWithEverything
            {
                Duration = duration.ToProtobufDuration(),
                Instant = when.ToTimestamp(),
                LocalDate = ld.ToDate(),
                LocalTime = lt.ToTimeOfDay(),
                IsoDayOfWeek = dow.ToProtobufDayOfWeek(),
            };

            var bytes = obj.ToByteArray();
            var hex = Log(BitConverter.ToString(bytes));
            Assert.Equal("0A-0B-08-F4-DE-DD-01-10-C0-ED-86-D7-01-12-0C-08-80-DC-88-FA-05-10-C0-ED-86-D7-01-1A-07-08-E4-0F-10-08-18-19-22-0A-08-0B-10-0F-18-2B-20-F8-D1-02-28-04", hex);
            var clone = MakeMeOneWithEverything.Parser.ParseFrom(bytes);
            Assert.NotSame(obj, clone);

            Assert.Equal(duration, clone.Duration.ToNodaDuration());
            Assert.Equal(when, clone.Instant.ToInstant());
            Assert.Equal(ld, clone.LocalDate.ToLocalDate());
            Assert.Equal(lt, clone.LocalTime.ToLocalTime());
            Assert.Equal(dow, clone.IsoDayOfWeek.ToIsoDayOfWeek());
        }
    }
}


<|start_filename|>src/protobuf-net.Test/Meta/Lists.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xunit;
using Xunit.Abstractions;

namespace ProtoBuf.unittest.Meta
{

    public class PocoListTests
    {
        public class TypeWithLists
        {
            public List<string> ListString { get; set; }
            public IList<string> IListStringTyped { get; set; }

            public List<int> ListInt32 { get; set; }
            public IList<int> IListInt32Typed { get; set; }
        }

        

        [Fact]
        public void EmitModelWithEverything()
        {
            var model = RuntimeTypeModel.Create();
            MetaType meta = model.Add(typeof(TypeWithLists), false);
            meta.Add(1, "ListString");
            meta.Add(2, "ListInt32");
            meta.Add(3, "IListStringTyped");
            meta.Add(4, "IListInt32Typed");


            model.CompileInPlace();

            model.Compile("EmitModelWithEverything", "EmitModelWithEverything.dll");
            PEVerify.Verify("EmitModelWithEverything.dll");


        }

        [Fact]
        public void AddOnTypedListShouldResolveCorrectly_String()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(1, "ListString");
            Assert.Equal(typeof(TypeWithLists), model[typeof(TypeWithLists)][1].ParentType); //, "ParentType");
            Assert.Equal(typeof(string), model[typeof(TypeWithLists)][1].ItemType); //, "ItemType");
            Assert.Equal(typeof(List<string>), model[typeof(TypeWithLists)][1].MemberType); //, "MemberType");
            Assert.Equal(typeof(List<string>), model[typeof(TypeWithLists)][1].DefaultType); //, "DefaultType");
        }

        [Fact]
        public void AddOnTypedListShouldResolveCorrectly_Int32()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(1, "ListInt32");
            Assert.Equal(typeof(TypeWithLists), model[typeof(TypeWithLists)][1].ParentType); //, "ParentType");
            Assert.Equal(typeof(int), model[typeof(TypeWithLists)][1].ItemType); //, "ItemType");
            Assert.Equal(typeof(List<int>), model[typeof(TypeWithLists)][1].MemberType); //, "MemberType");
            Assert.Equal(typeof(List<int>), model[typeof(TypeWithLists)][1].DefaultType); //, "DefaultType");
        }

        [Fact]
        public void AddOnTypedIListShouldResolveCorrectly_String()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(2, "IListStringTyped");
            Assert.Equal(typeof(TypeWithLists), model[typeof(TypeWithLists)][2].ParentType); //, "ParentType");
            Assert.Equal(typeof(string), model[typeof(TypeWithLists)][2].ItemType); //, "ItemType");
            Assert.Equal(typeof(IList<string>), model[typeof(TypeWithLists)][2].MemberType); //, "MemberType");
            Assert.Equal(typeof(IList<string>), model[typeof(TypeWithLists)][2].DefaultType); //, "DefaultType");
        }

        [Fact]
        public void AddOnTypedIListShouldResolveCorrectly_Int32()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(2, "IListInt32Typed");
            Assert.Equal(typeof(TypeWithLists), model[typeof(TypeWithLists)][2].ParentType); //, "ParentType");
            Assert.Equal(typeof(int), model[typeof(TypeWithLists)][2].ItemType); //, "ItemType");
            Assert.Equal(typeof(IList<int>), model[typeof(TypeWithLists)][2].MemberType); //, "MemberType");
            Assert.Equal(typeof(IList<int>), model[typeof(TypeWithLists)][2].DefaultType); //, "DefaultType");
        }

        [Fact]
        public void RoundTripTypedList_String()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(1, "ListString");
            TypeWithLists obj = new TypeWithLists
            {
                ListString = new List<string>
                {
                    "abc",
                    "def"
                }
            };

            TypeWithLists clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.ListString);
            Assert.True(obj.ListString.SequenceEqual(clone.ListString));

            model.CompileInPlace();
            clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.ListString);
            Assert.True(obj.ListString.SequenceEqual(clone.ListString));

            clone = (TypeWithLists)model.Compile().DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.ListString);
            Assert.True(obj.ListString.SequenceEqual(clone.ListString));
        }

        [Fact]
        public void RoundTripTypedIList_String()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(2, "IListStringTyped");
            TypeWithLists obj = new TypeWithLists
            {
                IListStringTyped = new List<string>
                {
                    "abc",
                    "def"
                }
            };

            TypeWithLists clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.IListStringTyped);
            Assert.True(obj.IListStringTyped.SequenceEqual(clone.IListStringTyped));

            model.CompileInPlace();
            clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.IListStringTyped);
            Assert.True(obj.IListStringTyped.SequenceEqual(clone.IListStringTyped));

            clone = (TypeWithLists)model.Compile().DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.IListStringTyped);
            Assert.True(obj.IListStringTyped.SequenceEqual(clone.IListStringTyped));
        }


        [Fact]
        public void RoundTripTypedList_Int32()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(1, "ListInt32");
            TypeWithLists obj = new TypeWithLists
            {
                ListInt32 = new List<int>
                {
                    123,
                    456
                }
            };

            TypeWithLists clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.ListInt32);
            Assert.True(obj.ListInt32.SequenceEqual(clone.ListInt32));

            model.CompileInPlace();
            clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.ListInt32);
            Assert.True(obj.ListInt32.SequenceEqual(clone.ListInt32));

            clone = (TypeWithLists)model.Compile().DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.ListInt32);
            Assert.True(obj.ListInt32.SequenceEqual(clone.ListInt32));
        }

        [Fact]
        public void RoundTripTypedIList_Int32()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(TypeWithLists), false).Add(2, "IListInt32Typed");
            TypeWithLists obj = new TypeWithLists
            {
                IListInt32Typed = new List<int>
                {
                    123,
                    456
                }
            };

            TypeWithLists clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.IListInt32Typed);
            Assert.True(obj.IListInt32Typed.SequenceEqual(clone.IListInt32Typed));

            model.CompileInPlace();
            clone = (TypeWithLists)model.DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.IListInt32Typed);
            Assert.True(obj.IListInt32Typed.SequenceEqual(clone.IListInt32Typed));

            clone = (TypeWithLists)model.Compile().DeepClone(obj);
            Assert.NotNull(clone);
            Assert.NotNull(clone.IListInt32Typed);
            Assert.True(obj.IListInt32Typed.SequenceEqual(clone.IListInt32Typed));
        }

        public class NastyType
        {
            
            public List<List<int>> JaggedList { get; set; }

            public List<int[]> ListOfArray{ get; set; }

            public int[,] MultiDimArray { get; set; }

            public int[][] JaggedArray { get; set; }

            public List<int>[] ArrayOfList{ get; set; }

            public List<int> BasicList { get; set; }
            public List<int> BasicListField;

            public int[] BasicArray{ get; set; }
            public int[] BasicArrayField;

            public byte[] Blob { get; set; }
            public byte[] BlobField;

            public List<byte[]> Blobs{ get; set; }

            public List<byte[]> BlobsField;
        }
        [Fact]
        public void JaggedListShouldThrow()
        {
            try {
                var model = RuntimeTypeModel.Create();
                model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.JaggedList));
                model.CompileInPlace();
                Assert.Equal(42, 0); // fail
            } catch(NotSupportedException) {  }
        }
        [Fact]
        public void ListOfArrayShouldThrow()
        {
            try {
                var model = RuntimeTypeModel.Create();
                model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.ListOfArray));
                model.CompileInPlace();
                Assert.Equal(42, 0); // fail
            }
            catch (NotSupportedException) { }
        }
        [Fact]
        public void MultiDimArrayShouldThrow()
        {
            try {
                var model = RuntimeTypeModel.Create();
                model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.MultiDimArray));
                model.CompileInPlace();
                Assert.Equal(42, 0); // fail
            }
            catch (NotSupportedException) { }
        }
        [Fact]
        public void JaggedArrayShouldThrow()
        {
            try {
                var model = RuntimeTypeModel.Create();
                model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.JaggedArray));
                model.CompileInPlace();
                Assert.Equal(42, 0); // fail
            }
            catch (NotSupportedException) { }
        }
        [Fact]
        public void ArrayOfListShouldThrow()
        {
            Assert.Throws<NotSupportedException>(() =>
            {
                var model = RuntimeTypeModel.Create();
                model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.ArrayOfList));
                model.CompileInPlace();
                Assert.Equal(42, 0); // fail
            });
        }
        [Fact]
        public void BasicListIsFine()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.BasicList));
            model.CompileInPlace();
        }
        [Fact]
        public void BasicArrayIsFine()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.BasicArray));
            model.CompileInPlace();
        }
        [Fact]
        public void BlobIsFine()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.Blob));
            model.CompileInPlace();
        }
        [Fact]
        public void BlobsAreFine()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(NastyType), true).Add(1, nameof(NastyType.Blobs));
            model.CompileInPlace();
        }
        [Fact]
        public void PEVerifyArraysAndLists()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(NastyType), true)
                .Add(1, nameof(NastyType.Blobs))
                .Add(2, nameof(NastyType.Blob))
                .Add(3, nameof(NastyType.BasicArray))
                .Add(4, nameof(NastyType.BasicList))

                .Add(5, nameof(NastyType.BlobsField))
                .Add(6, nameof(NastyType.BlobField))
                .Add(7, nameof(NastyType.BasicArrayField))
                .Add(8, nameof(NastyType.BasicListField))
                ;
            model.CompileInPlace();

            model.Compile("PEVerifyArraysAndLists","PEVerifyArraysAndLists.dll");
            PEVerify.Verify("PEVerifyArraysAndLists.dll");
        }


    }

    
    public class PackedLists
    {
        [Fact]
        public void CanCompile()
        {
            var model = CreateModel();
            model.Compile("PEVerifyPackedLists", "PEVerifyPackedLists.dll");
            PEVerify.Verify("PEVerifyPackedLists.dll");
        }

        [Fact]
        public void TestNullRoundTrip()
        {
            var model = CreateModel();

            var orig = new PackedData {ListInt32 = null, ListSingle = null, ListDouble = null};

            var clone = RoundTrip(model, orig, "Runtime", out int len);
            Assert.Equal(0, len); //, "Runtime");
            Assert.Null(clone.ListDouble);
            Assert.Null(clone.ListInt32);
            Assert.Null(clone.ListSingle);

            model.CompileInPlace();
            clone = RoundTrip(model, orig, "CompileInPlace", out len);
            Assert.Equal(0, len); //, "CompileInPlace");
            Assert.Null(clone.ListDouble);
            Assert.Null(clone.ListInt32);
            Assert.Null(clone.ListSingle);

            clone = RoundTrip(model.Compile(), orig, "Compile", out len);
            Assert.Equal(0, len); //, "Compile");
            Assert.Null(clone.ListDouble);
            Assert.Null(clone.ListInt32);
            Assert.Null(clone.ListSingle);
        }

        [Fact]
        public void TestEmptyRoundTrip()
        {
            var model = CreateModel();

            var orig = new PackedData { ListInt32 = new List<int>(), ListSingle = new List<float>(), ListDouble = new List<double>()};

            var clone = RoundTrip(model, orig, "Runtime", out int len);
            Assert.Equal(6, len); //, "Runtime");
            Assert.Empty(clone.ListDouble);
            Assert.Empty(clone.ListInt32);
            Assert.Empty(clone.ListSingle);

            model.CompileInPlace();
            clone = RoundTrip(model, orig, "CompileInPlace", out len);
            Assert.Equal(6, len); //, "CompileInPlace");
            Assert.Empty(clone.ListDouble);
            Assert.Empty(clone.ListInt32);
            Assert.Empty(clone.ListSingle);

            clone = RoundTrip(model.Compile(), orig, "Compile", out len);
            Assert.Equal(6, len); //, "Compile");
            Assert.Empty(clone.ListDouble);
            Assert.Empty(clone.ListInt32);
            Assert.Empty(clone.ListSingle);
        }

#pragma warning disable IDE0060
        static void CheckExpectedListContents(PackedData data, string text)
#pragma warning restore IDE0060
        {
            Assert.NotNull(data); //, text);
            Assert.Equal(3, data.ListInt32.Count); //, text);
            Assert.Equal(3, data.ListInt32[0]); //, text);
            Assert.Equal(5, data.ListInt32[1]); //, text);
            Assert.Equal(7, data.ListInt32[2]); //, text);
            Assert.Equal(3, data.ListSingle.Count); //, text);
            Assert.Equal(3F, data.ListSingle[0]); //, text);
            Assert.Equal(5F, data.ListSingle[1]); //, text);
            Assert.Equal(7F, data.ListSingle[2]); //, text);
            Assert.Equal(3, data.ListDouble.Count); //, text);
            Assert.Equal(3D, data.ListDouble[0]); //, text);
            Assert.Equal(5D, data.ListDouble[1]); //, text);
            Assert.Equal(7D, data.ListDouble[2]); //, text);
        }
        [Fact]
        public void TestThreeItemsRoundTrip()
        {
            var model = CreateModel();

            var orig = new PackedData { ListInt32 = new List<int> {3,5,7}, ListSingle = new List<float> {3F,5F,7F}, ListDouble = new List<double> {3D,5D,7F} };
            CheckExpectedListContents(orig, "Original");

            var clone = RoundTrip(model, orig, "Runtime", out int len);
            const int expectedLen = (1 + 1 + 1 + 1 + 1) + (1 + 1 + 4 + 4 + 4) + (1 + 1 + 8 + 8 + 8);
            Assert.Equal(expectedLen, len); //, "Runtime");
            Assert.NotNull(clone);
            CheckExpectedListContents(clone, "Runtime");

            model.CompileInPlace();
            clone = RoundTrip(model, orig, "CompileInPlace", out len);
            Assert.Equal(expectedLen, len); //, "CompileInPlace");
            Assert.NotNull(clone);
            CheckExpectedListContents(clone, "CompileInPlace");

            clone = RoundTrip(model.Compile(), orig, "Compile", out len);
            Assert.Equal(expectedLen, len); //, "Compile");
            Assert.NotNull(clone);
            CheckExpectedListContents(clone, "Compile");
        }
        static PackedData RoundTrip(TypeModel model, PackedData orig, string scenario, out int length)
        {
            try
            {
                using MemoryStream ms = new MemoryStream();
                model.Serialize(ms, orig);
                length = (int)ms.Length;
                ms.Position = 0;
#pragma warning disable CS0618
                return (PackedData)model.Deserialize(ms, null, typeof(PackedData));
#pragma warning restore CS0618
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(scenario + ": " + ex.Message, ex);
            }
        }
        static RuntimeTypeModel CreateModel()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof (PackedData), true);
            return model;
        }
        [ProtoContract]
        public class PackedData
        {
            [ProtoMember(1, IsPacked = true)]
            public List<int> ListInt32 { get; set; }
            [ProtoMember(2, IsPacked = true)]
            public List<float> ListSingle { get; set; }
            [ProtoMember(3, IsPacked = true)]
            public List<double> ListDouble{ get; set; }
        }
    }

    
    public class PackedArrays
    {
        [Fact]
        public void CanCompile()
        {
            var model = CreateModel();
            model.Compile("PEVerifyPackedArrays", "PEVerifyPackedArrays.dll");
            PEVerify.Verify("PEVerifyPackedArrays.dll");
        }

        [Fact]
        public void TestEmptyRoundTrip()
        {
            var model = CreateModel();

            var orig = new PackedData { ArrayInt32 = new int[0], ArraySingle = new float[0], ArrayDouble = new double[0] };

            var clone = RoundTrip(model, orig, "Runtime", out int len);
            Assert.Equal(6, len); //, "Runtime");
            Assert.Empty(clone.ArrayDouble);
            Assert.Empty(clone.ArrayInt32);
            Assert.Empty(clone.ArraySingle);

            model.CompileInPlace();
            clone = RoundTrip(model, orig, "CompileInPlace", out len);
            Assert.Equal(6, len); //, "CompileInPlace");
            Assert.Empty(clone.ArrayDouble);
            Assert.Empty(clone.ArrayInt32);
            Assert.Empty(clone.ArraySingle);

            clone = RoundTrip(model.Compile(), orig, "Compile", out len);
            Assert.Equal(6, len); //, "Compile");
            Assert.Empty(clone.ArrayDouble);
            Assert.Empty(clone.ArrayInt32);
            Assert.Empty(clone.ArraySingle);
        }
        [Fact]
        public void TestNullRoundTrip()
        {
            var model = CreateModel();

            var orig = new PackedData { ArrayInt32 = null, ArraySingle = null, ArrayDouble = null };

            var clone = RoundTrip(model, orig, "Runtime", out int len);
            Assert.Equal(0, len); //, "Runtime");
            Assert.Null(clone.ArrayDouble);
            Assert.Null(clone.ArrayInt32);
            Assert.Null(clone.ArraySingle);

            model.CompileInPlace();
            clone = RoundTrip(model, orig, "CompileInPlace", out len);
            Assert.Equal(0, len); //, "CompileInPlace");
            Assert.Null(clone.ArrayDouble);
            Assert.Null(clone.ArrayInt32);
            Assert.Null(clone.ArraySingle);

            clone = RoundTrip(model.Compile(), orig, "Compile", out len);
            Assert.Equal(0, len); //, "Compile");
            Assert.Null(clone.ArrayDouble);
            Assert.Null(clone.ArrayInt32);
            Assert.Null(clone.ArraySingle);
        }

#pragma warning disable IDE0060
        static void CheckExpectedListContents(PackedData data, string text)
#pragma warning restore IDE0060
        {
            Assert.NotNull(data); //, text);
            Assert.Equal(3, data.ArrayInt32.Length); //, text);
            Assert.Equal(3, data.ArrayInt32[0]); //, text);
            Assert.Equal(5, data.ArrayInt32[1]); //, text);
            Assert.Equal(7, data.ArrayInt32[2]); //, text);
            Assert.Equal(3, data.ArraySingle.Length); //, text);
            Assert.Equal(3F, data.ArraySingle[0]); //, text);
            Assert.Equal(5F, data.ArraySingle[1]); //, text);
            Assert.Equal(7F, data.ArraySingle[2]); //, text);
            Assert.Equal(3, data.ArrayDouble.Length); //, text);
            Assert.Equal(3D, data.ArrayDouble[0]); //, text);
            Assert.Equal(5D, data.ArrayDouble[1]); //, text);
            Assert.Equal(7D, data.ArrayDouble[2]); //, text);
        }

        public PackedArrays(ITestOutputHelper log)
            => _log = log;
        private readonly ITestOutputHelper _log;

        [Fact]
        public void TestThreeItemsRoundTrip()
        {
            var model = CreateModel();

            var orig = new PackedData { ArrayInt32 = new int[] { 3, 5, 7 }, ArraySingle = new float[] { 3F, 5F, 7F }, ArrayDouble = new double[] { 3D, 5D, 7F } };
            CheckExpectedListContents(orig, "Original");

            var clone = RoundTrip(model, orig, "Runtime", out int len);
            const int expectedLen = (1 + 1 + 1 + 1 + 1) + (1 + 1 + 4 + 4 + 4) + (1 + 1 + 8 + 8 + 8);
            Assert.Equal(expectedLen, len); //, "Runtime");
            Assert.NotNull(clone);
            CheckExpectedListContents(clone, "Runtime");

            model.CompileInPlace();
            clone = RoundTrip(model, orig, "CompileInPlace", out len);
            Assert.Equal(expectedLen, len); //, "CompileInPlace");
            Assert.NotNull(clone);
            CheckExpectedListContents(clone, "CompileInPlace");

            clone = RoundTrip(model.Compile(), orig, "Compile", out len);
            Assert.Equal(expectedLen, len); //, "Compile");
            Assert.NotNull(clone);
            CheckExpectedListContents(clone, "Compile");
        }
        PackedData RoundTrip(TypeModel model, PackedData orig, string scenario, out int length)
        {
            try
            {
                using MemoryStream ms = new MemoryStream();
                model.Serialize(ms, orig);
                _log?.WriteLine($"r64: {orig.ArrayDouble?.Length}, i32: {orig.ArrayInt32?.Length}, {orig.ArraySingle?.Length}");
                _log?.WriteLine($"{ms.Length} bytes: {BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length)}");
                length = (int)ms.Length;
                ms.Position = 0;
#pragma warning disable CS0618
                return (PackedData)model.Deserialize(ms, null, typeof(PackedData));
#pragma warning restore CS0618
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(scenario + ": " + ex.Message, ex);
            }
        }
        static RuntimeTypeModel CreateModel()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(PackedData), true);
            return model;
        }
        [ProtoContract]
        public class PackedData
        {
            [ProtoMember(1, IsPacked = true)]
            public int[] ArrayInt32 { get; set; }
            [ProtoMember(2, IsPacked = true)]
            public float[] ArraySingle { get; set; }
            [ProtoMember(3, IsPacked = true)]
            public double[] ArrayDouble { get; set; }
        }
    }
}


<|start_filename|>src/protobuf-net.Test/Serializers/Util.cs<|end_filename|>
﻿using ProtoBuf.Compiler;
using ProtoBuf.Internal.Serializers;
using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using System;
using System.IO;
using System.Text;
using Xunit;

namespace ProtoBuf.unittest.Serializers
{
    internal static partial class Util
    {
#if !NO_INTERNAL_CONTEXT
        public static void Test<T>(T value, Type innerType, Func<IRuntimeProtoSerializerNode, IRuntimeProtoSerializerNode> ctor,
            string expectedHex)
        {
            Assert.NotEqual(typeof(object), typeof(T));
            byte[] expected = new byte[expectedHex.Length / 2];
            for (int i = 0; i < expected.Length; i++)
            {
                expected[i] = (byte)Convert.ToInt32(expectedHex.Substring(i*2,2),16);
            }
            NilSerializer nil = new NilSerializer(innerType);
            var ser = ctor(nil);

            var model = RuntimeTypeModel.Create();
            var decorator = model.GetSerializer<T>(ser, false);
            Test(value, decorator, "decorator", expected);

            var compiled = model.GetSerializer<T>(ser, true);
            Test(value, compiled, "compiled", expected);
        }

#pragma warning disable RCS1163, IDE0060 // Unused parameter.
        public static void Test<T>(T obj, ProtoSerializer<T> serializer, string message, byte[] expected)
#pragma warning restore RCS1163, IDE0060 // Unused parameter.
        {
            byte[] data;
            using (MemoryStream ms = new MemoryStream())
            {
                long reported;
                var state = ProtoWriter.State.Create(ms, RuntimeTypeModel.Default, null);
                try
                {
                    serializer(ref state, obj);
                    state.Close();
#pragma warning disable CS0618
                    reported = state.GetPosition();
#pragma warning restore CS0618
                }
                finally
                {
                    state.Dispose();
                }
                data = ms.ToArray();
                Assert.Equal(reported, data.Length); //, message + ":reported/actual");
            }
            Assert.Equal(expected.Length, data.Length); //, message + ":Length");
            for (int i = 0; i < data.Length; i++)
            {
                Assert.Equal(expected[i], data[i]); //, message + ":" + i);
            }
        }
#endif
        public static void TestModel(RuntimeTypeModel model, object value, string hex)
        {
            byte[] raw;
            using (MemoryStream ms = new MemoryStream())
            {
#pragma warning disable CS0618
                model.Serialize(ms, value);
#pragma warning restore CS0618
                raw = ms.ToArray();
            }

            Assert.Equal(hex, GetHex(raw));

            model.CompileInPlace();
            using (MemoryStream ms = new MemoryStream())
            {
#pragma warning disable CS0618
                model.Serialize(ms, value);
#pragma warning restore CS0618
                raw = ms.ToArray();
            }

            Assert.Equal(hex, GetHex(raw));

            TypeModel compiled = model.Compile("compiled", "compiled.dll");
            PEVerify.Verify("compiled.dll");
            using (MemoryStream ms = new MemoryStream())
            {
#pragma warning disable CS0618
                compiled.Serialize(ms, value);
#pragma warning restore CS0618
                raw = ms.ToArray();
            }
            Assert.Equal(hex, GetHex(raw));
        }
#if !NO_INTERNAL_CONTEXT
        public static void Test<T>(T value, Func<IRuntimeProtoSerializerNode, IRuntimeProtoSerializerNode> ctor, string expectedHex)
        {
            Test<T>(value, typeof(T), ctor, expectedHex);
        }
#endif
        internal static string GetHex(byte[] bytes)
        {
            int len = bytes.Length;
            StringBuilder sb = new StringBuilder(len * 2);
            for (int i = 0; i < len; i++)
            {
                sb.Append(bytes[i].ToString("X2"));
            }
            return sb.ToString();
        }

        public delegate void WriterRunner(ref ProtoWriter.State state);

        public static void Test(WriterRunner action, string expectedHex)
        {
            using var ms = new MemoryStream();
            var state = ProtoWriter.State.Create(ms, RuntimeTypeModel.Default, null);
            try
            {
                action(ref state);
                state.Close();
            }
            finally
            {
                state.Dispose();
            }
            string s = GetHex(ms.ToArray());
            Assert.Equal(expectedHex, s);
        }
    }
}

<|start_filename|>src/NativeGoogleTests/Dayofweek.cs<|end_filename|>
// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: google/type/dayofweek.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Type {

  /// <summary>Holder for reflection information generated from google/type/dayofweek.proto</summary>
  public static partial class DayofweekReflection {

    #region Descriptor
    /// <summary>File descriptor for google/type/dayofweek.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static DayofweekReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "<KEY>",
            "<KEY>",
            "<KEY>",
            "QVkQBB<KEY>",
            "<KEY>",
            "<KEY>",
            "<KEY>));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Type.DayOfWeek), }, null, null));
    }
    #endregion

  }
  #region Enums
  /// <summary>
  /// Represents a day of week.
  /// </summary>
  public enum DayOfWeek {
    /// <summary>
    /// The unspecified day-of-week.
    /// </summary>
    [pbr::OriginalName("DAY_OF_WEEK_UNSPECIFIED")] Unspecified = 0,
    /// <summary>
    /// The day-of-week of Monday.
    /// </summary>
    [pbr::OriginalName("MONDAY")] Monday = 1,
    /// <summary>
    /// The day-of-week of Tuesday.
    /// </summary>
    [pbr::OriginalName("TUESDAY")] Tuesday = 2,
    /// <summary>
    /// The day-of-week of Wednesday.
    /// </summary>
    [pbr::OriginalName("WEDNESDAY")] Wednesday = 3,
    /// <summary>
    /// The day-of-week of Thursday.
    /// </summary>
    [pbr::OriginalName("THURSDAY")] Thursday = 4,
    /// <summary>
    /// The day-of-week of Friday.
    /// </summary>
    [pbr::OriginalName("FRIDAY")] Friday = 5,
    /// <summary>
    /// The day-of-week of Saturday.
    /// </summary>
    [pbr::OriginalName("SATURDAY")] Saturday = 6,
    /// <summary>
    /// The day-of-week of Sunday.
    /// </summary>
    [pbr::OriginalName("SUNDAY")] Sunday = 7,
  }

  #endregion

}

#endregion Designer generated code


<|start_filename|>src/protobuf-net.BuildTools/Internal/DataContractFlags.cs<|end_filename|>
﻿#nullable enable
using System;

namespace ProtoBuf.BuildTools.Internal
{
    [Flags]
    internal enum DataContractContextFlags
    {
        None = 0,
        IsProtoContract = 1 << 0,
        SkipConstructor = 1 << 1,
        IgnoreUnknownSubTypes = 1 << 2,
    }
}


<|start_filename|>src/Examples/TagInference.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoBuf;
using System.Runtime.Serialization;
using Xunit;

namespace Examples
{
    [ProtoContract(InferTagFromName=true)]
    [DataContract]
    class TagData
    {
        [DataMember(Order = 1)]
        public int Bravo { get; set; }

        [DataMember(Order = 1, Name="Alpha")]
        public int Delta { get; set; }

        [DataMember]
        public int Zulu { get; set; }

        [DataMember(Order = 2)]
        public int Charlie { get; set; }
    }

    [ProtoContract]
    [DataContract]
    class TagDataWithoutInfer
    {
        [DataMember(Order = 1)]
        public int Bravo { get; set; }

        [DataMember(Order = 1, Name = "Alpha")]
        public int Delta { get; set; }

        [DataMember]
        public int Zulu { get; set; }

        [DataMember(Order = 2)]
        public int Charlie { get; set; }
    }

    [ProtoContract]
    class TagDataExpected
    {
        [ProtoMember(3)]
        public int Bravo { get; set; }

        [ProtoMember(2)]
        public int Delta { get; set; }

        [ProtoMember(1)]
        public int Zulu { get; set; }

        [ProtoMember(4)]
        public int Charlie { get; set; }
    }

    
    public class TagInference
    {
        [Fact]
        public void TestTagWithoutInference()
        {
            Program.ExpectFailure<InvalidOperationException>(() =>
            {
                TagDataWithoutInfer data = new TagDataWithoutInfer();
                Serializer.DeepClone(data);
            });
        }

        [Fact]
        public void TestTagWithInferenceRoundtrip()
        {
            TagData data = new TagData
            {
                Bravo = 15,
                Charlie = 17,
                Delta = 4,
                Zulu = 9
            };
            TagData clone = Serializer.DeepClone(data);
            Assert.Equal(data.Bravo, clone.Bravo); //, "Bravo");
            Assert.Equal(data.Charlie, clone.Charlie); //, "Charlie");
            Assert.Equal(data.Delta, clone.Delta); //, "Delta");
            Assert.Equal(data.Zulu, clone.Zulu); //, "Zulu");
        }

        [Fact]
        public void TestTagWithInferenceBinary()
        {
            TagData data = new TagData
            {
                Bravo = 15,
                Charlie = 17,
                Delta = 4,
                Zulu = 9
            };
            TagDataExpected clone = Serializer.ChangeType<TagData, TagDataExpected>(data);
            Assert.Equal(data.Bravo, clone.Bravo); //, "Bravo");
            Assert.Equal(data.Charlie, clone.Charlie); //, "Charlie");
            Assert.Equal(data.Delta, clone.Delta); //, "Delta");
            Assert.Equal(data.Zulu, clone.Zulu); //, "Zulu");
        }

        [Fact]
        public void RoundTripWithImplicitFields()
        {
            var obj = new WithImplicitFields {X = 123, Y = "abc"};
            var clone = Serializer.DeepClone(obj);
            Assert.Equal(123, clone.X);
            Assert.Equal("abc", clone.Y);
        }

        [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
        public class WithImplicitFields
        {
            public int X { get; set; }
            public string Y { get; set; }
        }
    }




}


<|start_filename|>src/protogen.site.blazor.client/Models/DecodeModel.cs<|end_filename|>
﻿using System.IO;

namespace ProtoBuf.Models
{
    public class DecodeModel
    {
        public DecodeModel(byte[] data, bool showFullStrings)
        {
            Data = data;
            ShowFullStrings = showFullStrings;
        }

        public ProtoReader GetReader()
        {
            var ms = new MemoryStream(Data, 0, Data.Length, false);
#pragma warning disable CS0618
            return ProtoReader.Create(ms, null, null);
#pragma warning restore CS0618

        }

        public byte[] Data { get; }

        public bool ShowFullStrings { get; }

    }
}


<|start_filename|>src/BuildToolsUnitTests/DataContractAnalyzerTests.cs<|end_filename|>
﻿using Microsoft.CodeAnalysis;
using ProtoBuf.BuildTools.Analyzers;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace BuildToolsUnitTests
{
    public class ProtobufFieldAnalyzerTests : AnalyzerTestBase<DataContractAnalyzer>
    {
        public ProtobufFieldAnalyzerTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }

        [Fact]
        public async Task DoesntReportOnUnrelatedCode()
        {
            var diagnostics = await AnalyzeAsync(@"
public class Foo
{
    public void Bar() {}
}");
            Assert.Empty(diagnostics);
        }

        [Theory]
        [InlineData(1)]
        [InlineData(42)]
        [InlineData(18999)]
        [InlineData(20000)]
        [InlineData(536870911)]
        // The smallest field number you can specify is 1, and the largest is 229 - 1, or 536,870,911. You also cannot use the numbers 19000 through 19999
        // from https://developers.google.com/protocol-buffers/docs/proto3#assigning_field_numbers
        public async Task DoesntReportOnLegalDto(int fieldNumber)
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf;
[ProtoContract]
public class Foo
{{
    [ProtoMember({fieldNumber})]
    public int Bar {{get;set;}}
}}");
            Assert.Empty(diagnostics);
        }

        [Theory]
        [InlineData(1)]
        [InlineData(42)]
        [InlineData(18999)]
        [InlineData(20000)]
        [InlineData(536870911)]
        // The smallest field number you can specify is 1, and the largest is 229 - 1, or 536,870,911. You also cannot use the numbers 19000 through 19999
        // from https://developers.google.com/protocol-buffers/docs/proto3#assigning_field_numbers
        public async Task DoesntReportOnLegalDto_Partial(int fieldNumber)
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf;
[ProtoContract]
[ProtoPartialMember({fieldNumber}, nameof(Bar))]
public class Foo
{{
    public int Bar {{get;set;}}
}}");
            Assert.Empty(diagnostics);
        }

        [Theory]
        [InlineData(0)]
        [InlineData(-42)]
        [InlineData(19000, true)]
        [InlineData(19500, true)]
        [InlineData(19999, true)]
        [InlineData(536870912)]
        [InlineData(int.MaxValue)]
        [InlineData(int.MinValue)]
        // The smallest field number you can specify is 1, and the largest is 229 - 1, or 536,870,911. You also cannot use the numbers 19000 through 19999
        // from https://developers.google.com/protocol-buffers/docs/proto3#assigning_field_numbers
        public async Task ReportsOnIllegalDto(int fieldNumber, bool warningOnly = false)
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf;
[ProtoContract]
public class Foo
{{
    [ProtoMember({fieldNumber})]
    public int Bar {{get;set;}}
}}");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.InvalidFieldNumber);
            Assert.Equal(warningOnly ? DiagnosticSeverity.Warning : DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The specified field number {fieldNumber} is invalid; the valid range is 1-536870911, omitting 19000-19999.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsOnIllegalPartialName()
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf;
[ProtoContract]
[ProtoPartialMember(42, ""Bar"")]
public class Foo
{{
    public int Blap {{get;set;}}
}}");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.MemberNotFound);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal("The specified type member 'Bar' could not be resolved.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData(0)]
        [InlineData(-42)]
        [InlineData(19000, true)]
        [InlineData(19500, true)]
        [InlineData(19999, true)]
        [InlineData(536870912)]
        [InlineData(int.MaxValue)]
        [InlineData(int.MinValue)]
        // The smallest field number you can specify is 1, and the largest is 229 - 1, or 536,870,911. You also cannot use the numbers 19000 through 19999
        // from https://developers.google.com/protocol-buffers/docs/proto3#assigning_field_numbers
        public async Task ReportsOnIllegalDto_Partial(int fieldNumber, bool warningOnly = false)
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf;
[ProtoContract]
[ProtoPartialMember({fieldNumber}, nameof(Bar))]
public class Foo
{{
    public int Bar {{get;set;}}
}}");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.InvalidFieldNumber);
            Assert.Equal(warningOnly ? DiagnosticSeverity.Warning : DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The specified field number {fieldNumber} is invalid; the valid range is 1-536870911, omitting 19000-19999.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsOnIllegalConst()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public class Foo
{
    private const int FieldNumber = -42;
    [ProtoMember(FieldNumber)]
    public int Bar {get;set;}
}");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.InvalidFieldNumber);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The specified field number -42 is invalid; the valid range is 1-536870911, omitting 19000-19999.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsDuplicateFieldBetweenFields()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public class Foo
{
    [ProtoMember(1)]
    public int A {get;set;}

    [ProtoMember(2)]
    public int B {get;set;}

    [ProtoMember(2)]
    public int C {get;set;}

    [ProtoMember(3)]
    public int D {get;set;}
}");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateFieldNumber);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The specified field number 2 is duplicated; field numbers must be unique between all declared members and includes on a single type.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsDuplicateFieldBetweenPartialsAndIncludes()
        {
            // note we don't need to test all combinations of fields vs partials vs includes; it is all one bucket - it
            // is sufficient that it *finds the problem*
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
[ProtoInclude(3, typeof(SuperFoo))]
[ProtoPartialMember(3, ""C"")]
public class Foo
{
    [ProtoMember(1)]
    public int A {get;set;}

    [ProtoMember(2)]
    public int B {get;set;}

    public int C {get;set;}
}

[ProtoContract]
public class SuperFoo : Foo {}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateFieldNumber);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The specified field number 3 is duplicated; field numbers must be unique between all declared members and includes on a single type.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsShouldBeContract_Member()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
public class Foo
{
    [ProtoMember(1)]
    public int A {get;set;}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ShouldBeProtoContract);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The type is not marked as a proto-contract; additional annotations will be ignored.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsShouldBeContract_Include()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoInclude(typeof(SuperFoo))]
public class Foo
{
    [ProtoMember(1)]
    public int A {get;set;}
}
[ProtoContract]
public class SuperFoo : Foo {}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ShouldBeProtoContract);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The type is not marked as a proto-contract; additional annotations will be ignored.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsShouldBeContract_Reservation()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoReserved(123)]
public class Foo
{
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ShouldBeProtoContract);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The type is not marked as a proto-contract; additional annotations will be ignored.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsBothDeclaredAndIgnored()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoPartialIgnore(""A"")]
public class Foo
{
    [ProtoMember(1)]
    public int A {get;set;}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DeclaredAndIgnored);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The member 'A' is marked to be ignored; additional annotations will be ignored.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsReservedField_Number()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, ProtoReserved(42)]
public class Foo
{
    [ProtoMember(42)]
    public int A {get;set;}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ReservedFieldNumber);
            Assert.Equal(DiagnosticSeverity.Warning, diag.Severity);
            Assert.Equal($"The specified field number 42 is explicitly reserved.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsReservedField_Number_Range()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, ProtoReserved(40,50)]
public class Foo
{
    [ProtoMember(42)]
    public int A {get;set;}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ReservedFieldNumber);
            Assert.Equal(DiagnosticSeverity.Warning, diag.Severity);
            Assert.Equal($"The specified field number [40-50] is explicitly reserved.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsReservedField_Name()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, ProtoReserved(""A"")]
public class Foo
{
    [ProtoMember(42)]
    public int A {get;set;}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ReservedFieldName);
            Assert.Equal(DiagnosticSeverity.Warning, diag.Severity);
            Assert.Equal($"The specified field name 'A' is explicitly reserved.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsDuplicateName()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public class Foo
{
    [ProtoMember(1, Name = ""C"")]
    public int A {get;set;}
    [ProtoMember(2, Name = ""C"")]
    public int B {get;set;}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateFieldName);
            Assert.Equal(DiagnosticSeverity.Warning, diag.Severity);
            Assert.Equal($"The specified field name 'C' is duplicated; field names should be unique between all declared members on a single type.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsDuplicateReservationName()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, ProtoReserved(""A""), ProtoReserved(""A"")]
public class Foo
{
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateReservation);
            Assert.Equal(DiagnosticSeverity.Info, diag.Severity);
            Assert.Equal($"The reservations 'A' and 'A' overlap each-other.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsDuplicateReservationNumbers()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, ProtoReserved(10, 25), ProtoReserved(20, 30)]
public class Foo
{
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateReservation);
            Assert.Equal(DiagnosticSeverity.Info, diag.Severity);
            Assert.Equal($"The reservations [20-30] and [10-25] overlap each-other.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsDuplicateInclude()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
[ProtoInclude(1, typeof(SuperFoo))]
[ProtoInclude(2, typeof(SuperFoo))]
public class Foo
{
}
[ProtoContract]
public class SuperFoo : Foo {}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateInclude);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The type 'SuperFoo' is declared as an include multiple times.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsNonDerivedInclude()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
[ProtoInclude(1, typeof(SuperFoo))]
public class Foo
{
}
[ProtoContract]
public class SuperFoo {}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.IncludeNonDerived);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"The type 'SuperFoo' is declared as an include, but is not a direct sub-type.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsMissingIncludeDeclaration()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public class Foo {}
[ProtoContract]
public class SuperFoo : Foo {}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.IncludeNotDeclared);
            Assert.Equal(DiagnosticSeverity.Warning, diag.Severity);
            Assert.Equal($"The base-type 'Foo' is a proto-contract, but no include is declared for 'SuperFoo' and the IgnoreUnknownSubTypes flag is not set.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DoesNotReportMissingIncludeDeclarationWhenIgnoreSubTypesSpecified()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract(IgnoreUnknownSubTypes = true)]
public class Foo {}
public class SuperFoo : Foo {}
");
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task ReportsIncludeNotContract()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, ProtoInclude(3, typeof(SuperFoo))]
public class Foo {}
public class SuperFoo : Foo {}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.SubTypeShouldBeProtoContract);
            Assert.Equal(DiagnosticSeverity.Warning, diag.Severity);
            Assert.Equal($"The base-type 'Foo' is a proto-contract and the IgnoreUnknownSubTypes flag is not set; 'SuperFoo' should also be a proto-contract.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsMissingConstructor()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public class Foo {
    public Foo(string _) {}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ConstructorMissing);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"There is no suitable (parameterless) constructor available for the proto-contract, and the SkipConstructor flag is not set.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DoesNotReportMissingConstructorOnAbstractType()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public abstract class Foo {
    public Foo(string _) {}
}
");
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task ReportsMissingConstructor_ExplicitNoSkip()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract(SkipConstructor = false)]
public class Foo {
    public Foo(string _) {}
}
");
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ConstructorMissing);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal($"There is no suitable (parameterless) constructor available for the proto-contract, and the SkipConstructor flag is not set.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DoesNotReportsMissingConstructor_ExplicitSkip()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract(SkipConstructor = true)]
public class Foo {
    public Foo(string _) {}
}
");
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task SuggestsCompatibilityLevelWhenNonMarkedContracts()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public class Foo {}
", ignoreCompatibilityLevelAdvice: false);
            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.MissingCompatibilityLevel);
            Assert.Equal(DiagnosticSeverity.Info, diag.Severity);
            Assert.Equal($"It is recommended to declare a module or assembly level CompatibilityLevel (or declare it for each contract type); new projects should use the highest currently available - old projects should use Level200 unless fully considered.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DoesNotSuggestCompatibilityLevelWhenNoContracts()
        {
            var diagnostics = await AnalyzeAsync(@"
public class Foo {}
", ignoreCompatibilityLevelAdvice: false);
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DoesNotSuggestCompatibilityLevelWhenNoNonMarkedContracts()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract, CompatibilityLevel(CompatibilityLevel.Level300)]
public class Foo {}
", ignoreCompatibilityLevelAdvice: false);
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DoesNotSuggestCompatibilityLevelWhenDeclaredAtModule()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[module:CompatibilityLevel(CompatibilityLevel.Level300)]
[ProtoContract]
public class Foo {}
", ignoreCompatibilityLevelAdvice: false);
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DoesNotSuggestCompatibilityLevelWhenDeclaredAtAssembly()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[assembly:CompatibilityLevel(CompatibilityLevel.Level300)]
[ProtoContract]
public class Foo {}
", ignoreCompatibilityLevelAdvice: false);
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DoNotWarnOnEnumsWithoutValue()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public enum SomeEnum {
    None = 0,
    [ProtoEnum]
    Foo = 1
}");
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task NotifiesAboutRedundantEnumValueOverride()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public enum SomeEnum {
    None = 0,
    [ProtoEnum(Value = 1)]
    Foo = 1
}");
            // we'll overlook that the setter isn't actually available
            var diag = diagnostics.Single(x => x.Id is not "CS0618" and not "CS0619");
            Assert.Equal(DataContractAnalyzer.EnumValueRedundant, diag.Descriptor);
            Assert.Equal(DiagnosticSeverity.Info, diag.Severity);
            Assert.Equal("This ProtoEnumAttribute.Value declaration is redundant; it is recommended to omit it.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task NotifiesAboutIncompatibleEnumValueOverride()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public enum SomeEnum {
    None = 0,
    [ProtoEnum(Value = 42)]
    Foo = 1
}");
            // we'll overlook that the setter isn't actually available
            var diag = diagnostics.Single(x => x.Id is not "CS0618" and not "CS0619");
            Assert.Equal(DataContractAnalyzer.EnumValueNotSupported, diag.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity); // error since we're targeting v3
            Assert.Equal("This ProtoEnumAttribute.Value declaration conflicts with the underlying value; this scenario is not supported from protobuf-net v3 onwards.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task NotifiesAboutRedundantEnumNameOverride()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public enum SomeEnum {
    None = 0,
    [ProtoEnum(Name = ""Foo"")]
    Foo = 1
}");
            var diag = Assert.Single(diagnostics);
            Assert.Equal(DataContractAnalyzer.EnumNameRedundant, diag.Descriptor);
            Assert.Equal(DiagnosticSeverity.Info, diag.Severity);
            Assert.Equal("This ProtoEnumAttribute.Name declaration is redundant; it is recommended to omit it.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DoesNotNotifyAboutMeaningfulEnumNameOverride()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
[ProtoContract]
public enum SomeEnum {
    None = 0,
    [ProtoEnum(Name = ""foo"")]
    Foo = 1
}");
            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DoesNotifyAboutBasicRecordsWithConflictingFields()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public class IsExternalInit{}
}
[ProtoContract]
public record Test
{
	[ProtoMember(1)]
	public string Name { get; init; } = string.Empty;

	[ProtoMember(1)] // This does NOT get flagged with PBN0003
	public string Value { get; init; } = string.Empty;
}");
            var diag = Assert.Single(diagnostics);
            Assert.Equal(DataContractAnalyzer.DuplicateFieldNumber, diag.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal("The specified field number 1 is duplicated; field numbers must be unique between all declared members and includes on a single type.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DoesNotifyAboutRecordsWithRecordConstructor()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public class IsExternalInit{}
}
[ProtoContract]
public record Test(
	[property: ProtoMember(1)]
	string Name,

	[property: ProtoMember(1)] // This does NOT get flagged with PBN0003
	string Value)
{}");
            Assert.Equal(2, diagnostics.Count);

            var diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.DuplicateFieldNumber);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal("The specified field number 1 is duplicated; field numbers must be unique between all declared members and includes on a single type.", diag.GetMessage(CultureInfo.InvariantCulture));

            diag = Assert.Single(diagnostics, x => x.Descriptor == DataContractAnalyzer.ConstructorMissing);
            Assert.Equal(DiagnosticSeverity.Error, diag.Severity);
            Assert.Equal("There is no suitable (parameterless) constructor available for the proto-contract, and the SkipConstructor flag is not set.", diag.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ReportsShouldDeclareDefault()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
using System;
[ProtoContract]
public class Foo {
    [ProtoMember(1)] public bool FieldDefaultTrue = true;
    [ProtoMember(2)] public bool PropertyDefaultTrue {get;set;} = true;
    [ProtoMember(3)] public DayOfWeek FieldDefaultMonday = DayOfWeek.Monday;
    [ProtoMember(4)] public DayOfWeek PropertyDefaultMonday {get;set;} = DayOfWeek.Monday;
    [ProtoMember(5)] public char TestChar {get;set;} = 'X';
    [ProtoMember(6)] public sbyte TestSByte {get;set;} = 1;
    [ProtoMember(7)] public byte TestByte {get;set;} = 0x2;
    [ProtoMember(8)] public short TestInt16 {get;set;} = 0b0000_0011;
    [ProtoMember(9)] public ushort TestUInt16 {get;set;} = 4;
    [ProtoMember(10)] public int TestInt32 {get;set;} = -5;
    [ProtoMember(11)] public uint TestUInt32 {get;set;} = 6u;
    [ProtoMember(12)] public long TestInt64 {get;set;} = 1234567890123456789L;
    [ProtoMember(13)] public ulong TestUInt64 {get;set;} = 6758493021UL;
    [ProtoMember(14)] public decimal TestDecimal {get;set;} = 1.618033m;
    [ProtoMember(15)] public float TestSingle {get;set;} = 2.71828f;
    [ProtoMember(16)] public double TestDouble {get;set;} = 3.14159265;
    [ProtoMember(17)] public nint TestIntPtr {get;set;} = 1;
    [ProtoMember(18)] public nuint TestUIntPtr {get;set;} = 2;
}
");
            var diags = diagnostics.Where(x => x.Descriptor == DataContractAnalyzer.ShouldDeclareDefault).ToList();
            Assert.All(diags, diag => Assert.Equal(DiagnosticSeverity.Warning, diag.Severity));
            Assert.Collection(diags.Select(diag => diag.GetMessage(CultureInfo.InvariantCulture)),
                msg => Assert.Equal("Field 'FieldDefaultTrue' should use [DefaultValue(true)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'PropertyDefaultTrue' should use [DefaultValue(true)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'FieldDefaultMonday' should use [DefaultValue(DayOfWeek.Monday)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'PropertyDefaultMonday' should use [DefaultValue(DayOfWeek.Monday)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestChar' should use [DefaultValue('X')] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestSByte' should use [DefaultValue(1)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestByte' should use [DefaultValue(0x2)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestInt16' should use [DefaultValue(0b0000_0011)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestUInt16' should use [DefaultValue(4)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestInt32' should use [DefaultValue(-5)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestUInt32' should use [DefaultValue(6u)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestInt64' should use [DefaultValue(1234567890123456789L)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestUInt64' should use [DefaultValue(6758493021UL)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestDecimal' should use [DefaultValue(1.618033m)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestSingle' should use [DefaultValue(2.71828f)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestDouble' should use [DefaultValue(3.14159265)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestIntPtr' should use [DefaultValue(1)] to ensure its value is sent since it's initialized to a non-default value.", msg),
                msg => Assert.Equal("Field 'TestUIntPtr' should use [DefaultValue(2)] to ensure its value is sent since it's initialized to a non-default value.", msg));
        }

        [Fact]
        public async Task DoesNotReportShouldDeclareDefault()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf;
using System;
using System.ComponentModel;
[ProtoContract]
public class Foo {
    [ProtoMember(1)] public bool FieldDefaultFalse;
    [ProtoMember(2), System.ComponentModel.DefaultValue(true)] public bool FieldDefaultTrue = true;
    [ProtoMember(3)] public bool PropertyDefaultFalse {get;set;}
    [ProtoMember(4, IsRequired = true)] public bool PropertyDefaultTrue {get;set;} = true;
    [ProtoMember(5)] public DayOfWeek FieldDefaultSunday;
    [ProtoMember(6), DefaultValue(DayOfWeek.Monday)] public DayOfWeek FieldDefaultMonday = DayOfWeek.Monday;
    [ProtoMember(7)] public DayOfWeek PropertyDefaultSunday {get;set;}
    [ProtoMember(8)] public DayOfWeek PropertyDefaultMonday {get;set;} = DayOfWeek.Monday;
    public bool ShouldSerializePropertyDefaultMonday() => true;
    [ProtoMember(9), DefaultValue('X')] public char TestChar {get;set;} = 'X';
    [ProtoMember(10), DefaultValue(1)] public sbyte TestSByte {get;set;} = 1;
    [ProtoMember(11), DefaultValue(0x2)] public byte TestByte {get;set;} = 0x2;
    [ProtoMember(12), DefaultValue(0b0000_0011)] public short TestInt16 {get;set;} = 0b0000_0011;
    [ProtoMember(13), DefaultValue(4)] public ushort TestUInt16 {get;set;} = 4;
    [ProtoMember(14), DefaultValue(-5)] public int TestInt32 {get;set;} = -5;
    [ProtoMember(15), DefaultValue(6u)] public uint TestUInt32 {get;set;} = 6u;
    [ProtoMember(16), DefaultValue(1234567890123456789L)] public long TestInt64 {get;set;} = 1234567890123456789L;
    [ProtoMember(17), DefaultValue(6758493021UL)] public ulong TestUInt64 {get;set;} = 6758493021UL;
    [ProtoMember(18), DefaultValue(1.618033m)] public decimal TestDecimal {get;set;} = 1.618033m;
    [ProtoMember(19), DefaultValue(2.71828f)] public float TestSingle {get;set;} = 2.71828f;
    [ProtoMember(20), DefaultValue(3.14159265)] public double TestDouble {get;set;} = 3.14159265;
    [ProtoMember(21), DefaultValue(1)] public nint TestIntPtr {get;set;} = 1;
    [ProtoMember(22), DefaultValue(2)] public nuint TestUIntPtr {get;set;} = 2;
    [ProtoMember(23)] public char Test0Char {get;set;}
    [ProtoMember(24)] public sbyte Test0SByte {get;set;}
    [ProtoMember(25)] public byte Test0Byte {get;set;}
    [ProtoMember(26)] public short Test0Int16 {get;set;}
    [ProtoMember(27)] public ushort Test0UInt16 {get;set;}
    [ProtoMember(28)] public int Test0Int32 {get;set;}
    [ProtoMember(29)] public uint Test0UInt32 {get;set;}
    [ProtoMember(30)] public long Test0Int64 {get;set;}
    [ProtoMember(31)] public ulong Test0UInt64 {get;set;}
    [ProtoMember(32)] public decimal Test0Decimal {get;set;}
    [ProtoMember(33)] public float Test0Single {get;set;}
    [ProtoMember(34)] public double Test0Double {get;set;}
    [ProtoMember(35)] public nint Test0IntPtr {get;set;}
    [ProtoMember(36)] public nuint Test0UIntPtr {get;set;}
}
");
            Assert.Empty(diagnostics.Where(x => x.Descriptor == DataContractAnalyzer.ShouldDeclareDefault));
        }
    }
}



<|start_filename|>src/Examples/UnwrappedOuters.cs<|end_filename|>
﻿using System;
using System.Linq;
using Xunit;
using ProtoBuf;
using System.IO;

namespace Examples
{
    
    public class UnwrappedOuters
    {
        [Fact]
        public void TestNakedByteArray()
        {
            Random rand = new Random(12345);
            byte[] data = new byte[100], clone;
            rand.NextBytes(data);
            using(var ms = new MemoryStream())
            {
                Serializer.Serialize<byte[]>(ms, data);
                ms.Position = 0;
                clone = Serializer.Deserialize<byte[]>(ms);
            }
            Assert.True(data.SequenceEqual(clone));
        }

        [Fact]
        public void TestNakedString()
        {
            Random rand = new Random(12345);
            byte[] data = new byte[100], clone;
            rand.NextBytes(data);
            using (var ms = new MemoryStream())
            {
                Serializer.Serialize<string>(ms, Convert.ToBase64String(data));
                ms.Position = 0;
                clone = Convert.FromBase64String(Serializer.Deserialize<string>(ms));
            }
            
            Assert.True(data.SequenceEqual(clone));
        }
    }
}


<|start_filename|>assorted/ProtoBufGenerator/Tools/register.bat<|end_filename|>
@echo off
rem "%windir%\Microsoft.NET\Framework\v2.0.50727\regasm.exe" /nologo /CodeBase "%1"
rem if errorlevel 1 goto BuildEventFailed

rem "%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe" /nologo /f /i "%1"
rem if errorlevel 1 goto BuildEventFailed

rem "%ProgramFiles%\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Tools\Bin\RegPkg.exe" /pkgdeffile:"%2" /codebase "%1"
rem "%ProgramFiles%\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Tools\Bin\RegPkg.exe" /regfile:"%3" /codebase "%1"

REM Exit properly because the build will not fail
REM unless the final step exits with an error code
goto BuildEventOK

:BuildEventFailed
echo POSTBUILDSTEP FAILED
exit 1

:BuildEventOK
echo POSTBUILDSTEP COMPLETED OK
exit 0

<|start_filename|>src/protobuf-net.Test/ManualSerializer.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using ProtoBuf.unittest;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using Xunit;

namespace ProtoBuf
{
    public class ManualSerializer
    {
#if !PLAT_NO_EMITDLL
        [Fact]
        public void EmitManualSerializer()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            model.Add(typeof(A));
            model.Add(typeof(B));
            model.Add(typeof(C));
            model.Add(typeof(D));
            model.Add(typeof(E));
            model.Add(typeof(F));
            model.CompileAndVerify();
        }
#endif

        [Theory]
        [InlineData(true)]
        [InlineData(false)]
        public void ReadWriteAutomated_StreamReaderWriter(bool withState)
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            using var ms = new MemoryStream();
            var obj = new C { AVal = 123, BVal = 456, CVal = 789 };

            if (withState)
            {
                using var writeState = ProtoWriter.State.Create(ms, model);
                writeState.SerializeRoot(obj);
                Assert.Equal(0, writeState.Depth);
                writeState.Close();
            }
            else
            {
#pragma warning disable CS0618
                using var writer = ProtoWriter.Create(ms, model);
                model.Serialize(writer, obj);
#pragma warning restore CS0618
                Assert.Equal(0, writer.Depth);
            }
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Assert.Equal("22-08-2A-03-18-95-06-10-C8-03-08-7B", hex);
            // 22 = field 4, type String
            // 08 = length 8
            //      2A = field 5, type String
            //      03 = length 3
            //          18 = field 3, type Variant
            //          95-06 = 789 (raw) or -395 (zigzag)
            //      10 = field 2, type Variant
            //      C8-03 = 456(raw) or 228(zigzag)
            // 08 = field 1, type Variant
            // 7B = 123(raw) or - 62(zigzag)

            ms.Position = 0;

            A raw;
            if (withState)
            {
                using var readState = ProtoReader.State.Create(ms, model);
                raw = readState.DeserializeRoot<A>(null);
            }
            else
            {
#pragma warning disable CS0618
                using var reader = ProtoReader.Create(ms, model);
#pragma warning restore CS0618
                raw = reader.DefaultState().DeserializeRoot<A>(null);
            }
            var clone = Assert.IsType<C>(raw);
            Assert.NotSame(obj, clone);
            Assert.Equal(123, clone.AVal);
            Assert.Equal(456, clone.BVal);
            Assert.Equal(789, clone.CVal);
        }

        [Fact]
        public void ReadWriteAutomated_Stream()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            using var ms = new MemoryStream();
            var obj = new C { AVal = 123, BVal = 456, CVal = 789 };
            model.Serialize(ms, obj);

            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Assert.Equal("22-08-2A-03-18-95-06-10-C8-03-08-7B", hex);
            // 22 = field 4, type String
            // 08 = length 8
            //      2A = field 5, type String
            //      03 = length 3
            //          18 = field 3, type Variant
            //          95-06 = 789 (raw) or -395 (zigzag)
            //      10 = field 2, type Variant
            //      C8-03 = 456(raw) or 228(zigzag)
            // 08 = field 1, type Variant
            // 7B = 123(raw) or - 62(zigzag)

            ms.Position = 0;
            var raw = model.Deserialize<A>(ms);
            var clone = Assert.IsType<C>(raw);
            Assert.NotSame(obj, clone);
            Assert.Equal(123, clone.AVal);
            Assert.Equal(456, clone.BVal);
            Assert.Equal(789, clone.CVal);
        }

        static string Hex(ReadOnlySequence<byte> sequence)
        {
            var len = checked((int)sequence.Length);
            var rented = ArrayPool<byte>.Shared.Rent(len);
            sequence.CopyTo(rented);
            var hex = BitConverter.ToString(rented, 0, len);
            ArrayPool<byte>.Shared.Return(rented);
            return hex;
        }

        [Fact]
        public void ReadWriteAutomated_PipeReaderWriter()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            using var pipe = Pipelines.Sockets.Unofficial.Buffers.BufferWriter<byte>.Create();
            var obj = new C { AVal = 123, BVal = 456, CVal = 789 };
            using (var writeState = ProtoWriter.State.Create(pipe.Writer, model))
            {
                writeState.SerializeRoot(obj);
                Assert.Equal(0, writeState.Depth);
                writeState.Close();
            }
            using var result = pipe.Flush();
            var hex = Hex(result.Value);
            Assert.Equal("22-08-2A-03-18-95-06-10-C8-03-08-7B", hex);
            // 22 = field 4, type String
            // 08 = length 8
            //      2A = field 5, type String
            //      03 = length 3
            //          18 = field 3, type Variant
            //          95-06 = 789 (raw) or -395 (zigzag)
            //      10 = field 2, type Variant
            //      C8-03 = 456(raw) or 228(zigzag)
            // 08 = field 1, type Variant
            // 7B = 123(raw) or - 62(zigzag)

            using var readState = ProtoReader.State.Create(result.Value, model);
            var raw = readState.DeserializeRoot<A>(null);
            var clone = Assert.IsType<C>(raw);
            Assert.NotSame(obj, clone);
            Assert.Equal(123, clone.AVal);
            Assert.Equal(456, clone.BVal);
            Assert.Equal(789, clone.CVal);
        }

        [Theory]
        [InlineData(true)]
        [InlineData(false)]
        public void ReadWriteManual_StreamReaderWriter(bool withState)
        {
            using var ms = new MemoryStream();
            var obj = new C { AVal = 123, BVal = 456, CVal = 789 };

            using (var writeState = ProtoWriter.State.Create(ms, null))
            {
                writeState.SerializeRoot(obj, ModelSerializer.Default);
                Assert.Equal(0, writeState.Depth);
                writeState.Close();
            }

            Assert.Equal(12, ms.Length);
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Assert.Equal("22-08-2A-03-18-95-06-10-C8-03-08-7B", hex);

            ms.Position = 0;
            A raw;
            if (withState)
            {
                using var readState = ProtoReader.State.Create(ms, null);
                raw = readState.DeserializeRoot<A>(serializer: ModelSerializer.Default);
            }
            else
            {
#pragma warning disable CS0618
                using var reader = ProtoReader.Create(ms, null);
#pragma warning restore CS0618
                raw = reader.DefaultState().DeserializeRoot<A>(serializer: ModelSerializer.Default);
            }
            var clone = Assert.IsType<C>(raw);
            Assert.NotSame(obj, clone);
            Assert.Equal(123, clone.AVal);
            Assert.Equal(456, clone.BVal);
            Assert.Equal(789, clone.CVal);
        }

        [Fact]
        public void ReadWriteManual_PipeReaderWriter()
        {
            using var pipe = Pipelines.Sockets.Unofficial.Buffers.BufferWriter<byte>.Create();
            var obj = new C { AVal = 123, BVal = 456, CVal = 789 };
            using (var writeState = ProtoWriter.State.Create(pipe.Writer, null))
            {
                var bytes = writeState.SerializeRoot<A>(obj, ModelSerializer.Default);
                Assert.Equal(12, bytes);
                Assert.Equal(0, writeState.Depth);
                writeState.Close();
            }
            Assert.Equal(12, pipe.Length);

            using var result = pipe.Flush();
            var hex = Hex(result.Value);
            Assert.Equal("22-08-2A-03-18-95-06-10-C8-03-08-7B", hex);

            using var readState = ProtoReader.State.Create(result.Value, null);
            var raw = readState.DeserializeRoot<A>(null, ModelSerializer.Default);
            var clone = Assert.IsType<C>(raw);
            Assert.NotSame(obj, clone);
            Assert.Equal(123, clone.AVal);
            Assert.Equal(456, clone.BVal);
            Assert.Equal(789, clone.CVal);
        }
    }

    class ModelSerializer :
        ISerializer<A>, ISubTypeSerializer<A>, IFactory<A>,
        ISerializer<B>, ISubTypeSerializer<B>, IFactory<B>,
        ISerializer<C>, ISubTypeSerializer<C>, IFactory<C>,
        ISerializer<D>, IFactory<D>, ISerializerProxy<SomeEnum>
    {
        public static ModelSerializer Default = new ModelSerializer();
        public ModelSerializer() { }

        ISerializer<SomeEnum> ISerializerProxy<SomeEnum>.Serializer => EnumSerializer.CreateInt32<SomeEnum>();

        SerializerFeatures ISerializer<A>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        SerializerFeatures ISerializer<B>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        SerializerFeatures ISerializer<C>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        SerializerFeatures ISerializer<D>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        A IFactory<A>.Create(ISerializationContext context) => new A();
        B IFactory<B>.Create(ISerializationContext context) => new B();
        C IFactory<C>.Create(ISerializationContext context) => new C();
        D IFactory<D>.Create(ISerializationContext context) => new D();

        //void IProtoFactory<A, A>.Copy(SerializationContext context, A from, A to)
        //{
        //    to.AVal = from.AVal;
        //}

        //void IProtoFactory<A, B>.Copy(SerializationContext context, A from, B to)
        //{
        //    if (from is B b)
        //    {
        //        to.BVal = b.BVal;
        //    }

        //    ((IProtoFactory<A, A>)Serializer).Copy(context, from, to);
        //}

        //void IProtoFactory<A, C>.Copy(SerializationContext context, A from, C to)
        //{
        //    if (from is C c)
        //    {
        //        to.CVal = c.CVal;
        //    }

        //    if (from is B b)
        //    {
        //        ((IProtoFactory<A, B>)Serializer).Copy(context, b, to);
        //    }
        //    else
        //    {
        //        ((IProtoFactory<A, A>)Serializer).Copy(context, from, to);
        //    }
        //}

        void ISerializer<A>.Write(ref ProtoWriter.State state, A value)
            => ((ISubTypeSerializer<A>)this).WriteSubType(ref state, value);
        void ISerializer<B>.Write(ref ProtoWriter.State state, B value)
            => ((ISubTypeSerializer<A>)this).WriteSubType(ref state, value);
        void ISerializer<C>.Write(ref ProtoWriter.State state, C value)
            => ((ISubTypeSerializer<A>)this).WriteSubType(ref state, value);

        A ISerializer<A>.Read(ref ProtoReader.State state, A value)
            => ((ISubTypeSerializer<A>)this).ReadSubType(ref state, SubTypeState<A>.Create<A>(state.Context, value));
        B ISerializer<B>.Read(ref ProtoReader.State state, B value)
            => (B)((ISubTypeSerializer<A>)this).ReadSubType(ref state, SubTypeState<A>.Create<B>(state.Context, value));
        C ISerializer<C>.Read(ref ProtoReader.State state, C value)
            => (C)((ISubTypeSerializer<A>)this).ReadSubType(ref state, SubTypeState<A>.Create<C>(state.Context, value));

        void ISubTypeSerializer<A>.WriteSubType(ref ProtoWriter.State state, A value)
        {
            if (TypeModel.IsSubType<A>(value))
            {
                if (value is B b)
                {
                    state.WriteFieldHeader(4, WireType.String);
                    state.WriteSubType<B>(b, this);
                }
                else
                {
                    TypeModel.ThrowUnexpectedSubtype<A>(value);
                }
            }
            if (value.AVal != 0)
            {
                state.WriteFieldHeader(1, WireType.Varint);
                state.WriteInt32(value.AVal);
            }
        }

        A ISubTypeSerializer<A>.ReadSubType(ref ProtoReader.State state, SubTypeState<A> value)
        {
            int field;
            value.OnBeforeDeserialize((obj, ctx) => obj.OnBeforeDeserialize());
            while ((field = state.ReadFieldHeader()) != 0)
            {
                switch (field)
                {
                    case 1:
                        value.Value.AVal = state.ReadInt32();
                        break;
                    case 4:
                        value.ReadSubType<B>(ref state, this);
                        break;
                    default:
                        state.SkipField();
                        break;
                }
            }
            value.Value.OnAfterDeserialize();
            return value.Value;
        }

        void ISubTypeSerializer<B>.WriteSubType(ref ProtoWriter.State state, B value)
        {
            if (TypeModel.IsSubType<B>(value))
            {
                if (value is C c)
                {
                    state.WriteFieldHeader(5, WireType.String);
                    state.WriteSubType<C>(c, this);
                }
                else
                {
                    TypeModel.ThrowUnexpectedSubtype<B>(value);
                }
            }
            if (value.BVal != 0)
            {
                state.WriteFieldHeader(2, WireType.Varint);
                state.WriteInt32(value.BVal);
            }
        }

        B ISubTypeSerializer<B>.ReadSubType(ref ProtoReader.State state, SubTypeState<B> value)
        {
            int field;
            while ((field = state.ReadFieldHeader()) != 0)
            {
                switch (field)
                {
                    case 2:
                        value.Value.BVal = state.ReadInt32();
                        break;
                    case 5:
                        value.ReadSubType<C>(ref state, this);
                        break;
                    default:
                        state.SkipField();
                        break;
                }
            }
            return value.Value;
        }

        void ISubTypeSerializer<C>.WriteSubType(ref ProtoWriter.State state, C value)
        {
            TypeModel.ThrowUnexpectedSubtype<C>(value);
            if (value.CVal != 0)
            {
                state.WriteFieldHeader(3, WireType.Varint);
                state.WriteInt32(value.CVal);
            }
        }

        C ISubTypeSerializer<C>.ReadSubType(ref ProtoReader.State state, SubTypeState<C> value)
        {
            int field;
            while ((field = state.ReadFieldHeader()) != 0)
            {
                switch (field)
                {
                    case 3:
                        value.Value.CVal = state.ReadInt32();
                        break;
                    default:
                        state.SkipField();
                        break;
                }
            }
            return value.Value;
        }

        void ISerializer<D>.Write(ref ProtoWriter.State state, D value)
        {
            TypeModel.ThrowUnexpectedSubtype<D>(value);
            if (value.DVal != 0) state.WriteInt32Varint(1, value.DVal);
            if (value.Name != null) state.WriteString(2, value.Name);
            state.WriteMessage<D>(3, default, value.Nested, this);
            if (value.EnumValue != 0) state.WriteInt32Varint(4, (int)value.EnumValue);
        }

        D ISerializer<D>.Read(ref ProtoReader.State state, D value)
        {
            if (value == null) value = state.CreateInstance<D>(this);
            int field;
            while ((field = state.ReadFieldHeader()) != 0)
            {
                switch (field)
                {
                    case 1:
                        value.DVal = state.ReadInt32();
                        break;
                    case 2:
                        value.Name = state.ReadString();
                        break;
                    case 3:
                        value.Nested = state.ReadMessage<D>(default, value.Nested, this);
                        break;
                    case 4:
                        value.EnumValue = (SomeEnum)state.ReadInt32();
                        break;
                    default:
                        state.SkipField();
                        break;
                }
            }
            return value;
        }
    }


    [ProtoContract]
    [ProtoInclude(4, typeof(B))]
    public class A
    {
        [ProtoMember(1)]
        public int AVal { get; set; }

        [ProtoAfterDeserialization]
        public void OnAfterDeserialize() { }

        [ProtoBeforeDeserialization]
        public void OnBeforeDeserialize() { }

        [ProtoAfterSerialization]
        public void OnAfterSerialize() { }

        [ProtoBeforeSerialization]
        public void OnBeforeSerialize() { }
    }

    [ProtoContract]
    [ProtoInclude(5, typeof(C))]
    public class B : A
    {
        [ProtoMember(2)]
        public int BVal { get; set; }
    }
    [ProtoContract]
    public class C : B
    {
        [ProtoMember(3)]
        public int CVal { get; set; }

    }
    [ProtoContract(SkipConstructor = true)]
    public class D
    {
        [ProtoMember(1)]
        public int DVal { get; set; }

        [ProtoMember(2)]
        public string Name { get; set; }

        [ProtoMember(3)]
        public D Nested { get; set; }

        [ProtoMember(4)]
        public SomeEnum EnumValue { get; set; }
    }

    public enum SomeEnum
    {
        X, Y, Z
    }

    [ProtoInclude(7, typeof(G))]
    [ProtoContract(IsGroup = true)]
    public class F {}

    [ProtoContract]
    public sealed class G : F
    { }

    [ProtoContract]
    public sealed class E
    {
        [ProtoMember(1)]
        public E PublicAssignable { get; set; }

        [ProtoMember(2)]
        public E PrivateAssignable { get; private set; }

        [ProtoMember(3)]
        public E NonAssignable => _nonAssignable ??= new E();
        private E _nonAssignable;

        [ProtoMember(4)]
        public List<E> PublicAssignableList { get; set; }

        [ProtoMember(5)]
        public List<E> PrivateAssignableList { get; private set; }

        [ProtoMember(6)]
        public List<E> NonAssignableList => _nonAssignableList ??= new List<E>();
        public List<E> _nonAssignableList;
        
        [ProtoMember(7)]
        public F Group { get; set; }

        [ProtoMember(8)]
        public G GroupSubClass { get; set; }

        [Browsable(false)]
        public bool ShouldSerializeNonAssignableList() => _nonAssignableList != null && _nonAssignableList.Count != 0;
    }
}


<|start_filename|>src/protobuf-net.Core/Internal/PrimaryTypeProvider.Utf8String.cs<|end_filename|>
﻿//#if PLAT_UTF8_STRING

//using ProtoBuf.Serializers;
//using System;

//namespace ProtoBuf.Internal
//{
//    internal sealed class Utf8String // mock-up for now
//    {
//        public int Length => throw new NotImplementedException();
//        public ReadOnlyMemory<byte> AsMemory() => throw new NotImplementedException();
//        public static Utf8String Empty => throw new NotImplementedException();
//    }
//    partial class PrimaryTypeProvider :
//        IMeasuringSerializer<Utf8String>,
//        IFactory<Utf8String>,
//        IValueChecker<Utf8String>
//    {
//        Utf8String ISerializer<Utf8String>.Read(ref ProtoReader.State state, Utf8String value)
//            => throw new NotImplementedException(); // should use public static Utf8String Create<TState>(int length, TState state, SpanAction<byte, TState> action)
//        void ISerializer<Utf8String>.Write(ref ProtoWriter.State state, Utf8String value) => state.WriteBytes(value.AsMemory());
//        SerializerFeatures ISerializer<Utf8String>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryScalar;
//        int IMeasuringSerializer<Utf8String>.Measure(ISerializationContext context, WireType wireType, Utf8String value)
//            => wireType switch
//            {
//                WireType.String => value.Length,
//                _ => -1,
//            };
//        Utf8String IFactory<Utf8String>.Create(ISerializationContext context) => Utf8String.Empty;

//        bool IValueChecker<Utf8String>.HasNonTrivialValue(Utf8String value) => value is object; //  note: we write "" (when found), for compat
//        bool IValueChecker<Utf8String>.IsNull(Utf8String value) => value is null; //  note: we write "" (when found), for compat
//    }
//}
//#endif

<|start_filename|>src/Examples/Issues/Issue695.cs<|end_filename|>
﻿using System;
using System.IO;
using Xunit;

namespace ProtoBuf.Issues
{
    public class Issue695
    {
        [ProtoContract]
        [ProtoInclude(1, typeof(DeclaredDerived_Derived))]
        public class DeclaredDerived_Base
        {
        }

        [ProtoContract]
        public class DeclaredDerived_Derived : DeclaredDerived_Base
        {
            [ProtoAfterDeserialization]
            public void PostDeserialization()
            {
                Value = 42;
            }

            public int Value { get; set; }
        }

        [ProtoContract]
        [ProtoInclude(1, typeof(DeclaredRoot_Derived))]
        public class DeclaredRoot_Base
        {
            [ProtoAfterDeserialization]
            public virtual void PostDeserialization()
            {
            }
        }

        [ProtoContract]
        public class DeclaredRoot_Derived : DeclaredRoot_Base
        {
            public override void PostDeserialization()
            {
                base.PostDeserialization();
                Value = 42;
            }

            public int Value { get; set; }
        }

        [Fact]
        public void ExecuteDeclaredDerived()
        {
            var req = new DeclaredDerived_Derived();
            byte[] bytes;
            using (var ms = new MemoryStream())
            {
                Serializer.Serialize(ms, req);
                bytes = ms.ToArray();
            }
            using (var ms = new MemoryStream(bytes))
            {
                var dRequest = Serializer.Deserialize<DeclaredDerived_Derived>(ms);
                Assert.IsType<DeclaredDerived_Derived>(dRequest);
                Assert.Equal(0, dRequest.Value);
            }
        }

        [Fact]
        public void ExecuteDeclaredRoot()
        {
            var req = new DeclaredRoot_Derived();
            byte[] bytes;
            using (var ms = new MemoryStream())
            {
                Serializer.Serialize(ms, req);
                bytes = ms.ToArray();
            }
            using (var ms = new MemoryStream(bytes))
            {
                var dRequest = Serializer.Deserialize<DeclaredRoot_Derived>(ms);
                Assert.IsType<DeclaredRoot_Derived>(dRequest);
                Assert.Equal(42, dRequest.Value);
            }
        }
    }
}


<|start_filename|>src/Examples/Issues/SO17245073.cs<|end_filename|>
﻿using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using System;

namespace Examples.Issues
{
    
    public class SO17245073
    {
        [Fact]
        public void Exec()
        {
            var model = RuntimeTypeModel.Create();
#pragma warning disable CS0618 // we know that EnumPassthru is obsolete; we still want to check the output
            Assert.True(model[typeof(A)].EnumPassthru, "A");
            Assert.True(model[typeof(B)].EnumPassthru, "B");

            Assert.True(model[typeof(C)].EnumPassthru, "C");
            Assert.True(model[typeof(D)].EnumPassthru, "D");

            Assert.True(model[typeof(E)].EnumPassthru, "E");
            Assert.True(model[typeof(F)].EnumPassthru, "F");

            Assert.True(model[typeof(G)].EnumPassthru, "G");
            Assert.True(model[typeof(H)].EnumPassthru, "H");
#pragma warning restore CS0618
        }

        // no ProtoContract; with [Flags] is pass-thru, else not
        public enum A { X, Y, Z }
        [Flags]
        public enum B { X, Y, Z }

        // basic ProtoContract; with [Flags] is pass-thru, else not
        [ProtoContract]
        public enum C { X, Y, Z }
        [ProtoContract, Flags]
        public enum D { X, Y, Z }

        // ProtoContract with explicit pass-thru enabled; always pass-thru
        [ProtoContract]
        public enum E { X, Y, Z }
        [ProtoContract, Flags]
        public enum F { X, Y, Z }

        // ProtoContract with explicit pass-thru disabled; never pass-thru (even if [Flags])
        [ProtoContract]
        public enum G { X, Y, Z }
        [ProtoContract, Flags]
        public enum H { X, Y, Z }
    }
    
    
}


<|start_filename|>src/protobuf-net.Core/Internal/GuidHelper.cs<|end_filename|>
﻿using System;
using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics;
using System.Text;

namespace ProtoBuf.Internal
{
    //internal readonly struct GuidBytes : IEquatable<GuidBytes>
    //{
    //    internal readonly Guid ValueField;
    //    public Guid Value => ValueField;
    //    public GuidBytes(in Guid value) => ValueField = value;
    //    public static implicit operator Guid(in GuidBytes value) => value.ValueField;
    //    public static implicit operator GuidBytes(in Guid value) => new GuidBytes(value);
    //    public bool Equals(in GuidBytes other) => ValueField.Equals(other.ValueField);
    //    bool IEquatable<GuidBytes>.Equals(GuidBytes other) => ValueField.Equals(other.ValueField);
    //    public override int GetHashCode() => ValueField.GetHashCode();
    //    public override string ToString() => ValueField.ToString();
    //    public override bool Equals(object obj) => obj is GuidBytes other && ValueField.Equals(other.ValueField);
    //}

    //internal readonly struct GuidString : IEquatable<GuidString>
    //{
    //    internal readonly Guid ValueField;
    //    public Guid Value => ValueField;
    //    public GuidString(in Guid value) => ValueField = value;
    //    public static implicit operator Guid(in GuidString value) => value.ValueField;
    //    public static implicit operator GuidString(in Guid value) => new GuidString(value);
    //    public bool Equals(in GuidString other) => ValueField.Equals(other.ValueField);
    //    bool IEquatable<GuidString>.Equals(GuidString other) => ValueField.Equals(other.ValueField);
    //    public override int GetHashCode() => ValueField.GetHashCode();
    //    public override string ToString() => ValueField.ToString();
    //    public override bool Equals(object obj) => obj is GuidString other && ValueField.Equals(other.ValueField);
    //}

    internal static class GuidHelper
    {
        internal const int WRITE_BYTES_LENGTH = 16, WRITE_STRING_LENGTH = 36, MAX_LENGTH = 40;

        internal static unsafe Guid Read(ref ProtoReader.State state)
        {
            // note: we can't use a stackalloc-span here because the compiler doesn't trust
            // state, which is a ref-local (and can store spans), not to store it; since we *don't*
            // do that, we can be evil
            byte* ptr = stackalloc byte[MAX_LENGTH];
            var available = state.ReadBytes(new Span<byte>(ptr, MAX_LENGTH));

            char standardFormat;
            switch (available.Length)
            {
                case 0:
                    return Guid.Empty;
                case 16: // treat as big-endian bytes
                    // expand those bytes to hex, backwards so we don't overwrite live data
                    int write = 32;
                    for (int i = 15; i >= 0; i--)
                    {
                        var val = ptr[i];
                        ptr[--write] = ToHex(val & 0b1111);
                        ptr[--write] = ToHex((val >> 4) & 0b1111);
                    }
                    available = new Span<byte>(ptr, 32);
                    standardFormat = 'N';
                    break;
                case 32: // no hyphens
                    standardFormat = 'N';
                    break;
                case 36: // hyphens
                    standardFormat = 'D';
                    break;
                default:
                    ThrowHelper.Format($"Unexpected Guid length: {available.Length}");
                    return default;
            }

            if (!(Utf8Parser.TryParse(available, out Guid guid, out int bytes, standardFormat) && bytes == available.Length))
                ThrowHelper.Format($"Failed to read Guid: '{Encoding.UTF8.GetString(ptr, available.Length)}'");

            return guid;
            static byte ToHex(int value) => (byte)"0123456789abcdef"[value];
        }

        internal static void Write(ref ProtoWriter.State state, in Guid value, bool asBytes)
        {
            if (value.Equals(Guid.Empty))
            {
                state.WriteBytes(default(ReadOnlyMemory<byte>));
                return;
            }

            // note: we don't use stackalloc here because the ImplWriteBytes API currently takes ROM<byte>,
            // because it tries to use MemoryMarshal.TryGetArray etc if it needs to write to underlying streams
            var arr = ArrayPool<byte>.Shared.Rent(MAX_LENGTH);
            try
            {
                if (!(Utf8Formatter.TryFormat(value, arr, out int bytesWritten, asBytes ? 'N' : 'D')))
                    ThrowHelper.Format($"Failed to write Guid: '{value}'");

                if (asBytes)
                {
                    // pack down that hex to bytes
                    int read = 0;
                    Debug.Assert(bytesWritten == 2  * WRITE_BYTES_LENGTH, $"expected {2 * WRITE_BYTES_LENGTH} bytes, got {bytesWritten}");
                    for (int i = 0; i < WRITE_BYTES_LENGTH; i++)
                    {
                        arr[i] = (byte)((FromHex(arr[read++]) << 4) | FromHex(arr[read++]));
                    }
                    bytesWritten = WRITE_BYTES_LENGTH;
                }
                state.WriteBytes(new ReadOnlyMemory<byte>(arr, 0, bytesWritten));
            }
            finally
            {
                ArrayPool<byte>.Shared.Return(arr);
            }

            static int FromHex(int value)
            {
                if (value >= '0' && value <= '9')
                    return value - '0';
                if (value >= 'a' && value <= 'f')
                    return 10 + value - 'a';
                if (value >= 'A' && value <= 'F')
                    return 10 + value - 'A';
                Throw(value);
                return default;

                static void Throw(int value)
                {
                    ThrowHelper.ThrowArgumentOutOfRangeException(nameof(value), $"Unexpected hex character: '{(char)value}'");
                }
            };
        }
    }
}


<|start_filename|>src/BuildToolsUnitTests/ProtoGeneratorTests.cs<|end_filename|>
﻿using Microsoft.CodeAnalysis;
using ProtoBuf.BuildTools.Generators;
using System;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace BuildToolsUnitTests
{
    public class ProtoGeneratorTests : GeneratorTestBase<ProtoFileGenerator>
    {
        public ProtoGeneratorTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }

        [Fact]
        public async Task BasicGenerateWorks()
        {
            (var result, var diagnostics) = await GenerateAsync(Text("test.proto", @"syntax = ""proto3""; message Foo {}"));

            Assert.Empty(diagnostics);
            Assert.Single(result.GeneratedTrees);
        }

        [Fact]
        public async Task GenerateWithImport()
        {
            (var result, var diagnostics) = await GenerateAsync(
                Texts(
                    ("/code/x/y/foo.proto", @"
syntax = ""proto3"";
import ""import/bar.proto"";

message Foo {
    Bar bar = 1;
}
"),
                    ("/code/x/y/import/bar.proto", @"
syntax = ""proto3"";

message Bar {
    int32 i = 1;
}")
                ));
            Assert.Empty(diagnostics);
            Assert.Equal(2, result.GeneratedTrees.Length);
        }

        [Fact]
        public async Task EmbeddedImportWorks()
        {
            (var result, var diagnostics) = await GenerateAsync(Text("test.proto", @"
syntax = ""proto3"";
import ""google/protobuf/timestamp.proto"";
message Foo {
    .google.protobuf.Timestamp when = 1;
}"));
            Assert.Empty(diagnostics);
            Assert.Single(result.GeneratedTrees);
        }

        [Fact]
        public async Task DeepImportWorksWithExtraImport()
        {
            (var result, var diagnostics) = await GenerateAsync(Texts(
                ("/foo/google/protobuf/a.proto", @"
syntax = ""proto3"";
import ""google/protobuf/b.proto"";
message Foo {
    Bar bar = 1;
}", new[] { ("ImportPaths", "../../") }),
("/foo/google/protobuf/b.proto", @"
syntax = ""proto3"";
message Bar {}", null)
));
            Assert.Empty(diagnostics);
            Assert.Equal(2, result.GeneratedTrees.Length);
        }

        [Fact]
        public async Task DeepImportFailsWithoutExtraImport()
        {
            (var result, var diagnostics) = await GenerateAsync(Texts(
                ("/foo/google/protobuf/a.proto", @"
syntax = ""proto3"";
import ""google/protobuf/b.proto"";
message Foo {
    Bar bar = 1;
}", Array.Empty<(string,string)>()),
("/foo/google/protobuf/b.proto", @"
syntax = ""proto3"";
message Bar {}", null)
));
            Assert.Equal(3, diagnostics.Length);
            Assert.Single(diagnostics.Where(x => x.Id == "PBN1004" && x.GetMessage() == "unable to find: 'google/protobuf/b.proto'" && x.Severity == DiagnosticSeverity.Error));
            Assert.Single(diagnostics.Where(x => x.Id == "PBN1002" && x.GetMessage() == "type not found: 'Bar'" && x.Severity == DiagnosticSeverity.Error));
            Assert.Single(diagnostics.Where(x => x.Id == "PBN1020" && x.GetMessage() == "import not used: 'google/protobuf/b.proto'" && x.Severity == DiagnosticSeverity.Warning));
        }
    }
}


<|start_filename|>src/protobuf-net.Test/Issues/GrpcIssue100.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using System;
using System.Buffers;
using System.IO;
using System.Runtime.InteropServices;
using Xunit;
using Xunit.Abstractions;

namespace ProtoBuf.Issues
{
    // context: https://github.com/protobuf-net/protobuf-net.Grpc/issues/100
    public class GrpcIssue100
    {
        public GrpcIssue100(ITestOutputHelper log) => _log = log;
        private readonly ITestOutputHelper _log;
        private void Log(string message) => _log?.WriteLine(message);

        private static TestObject GetTestInstance() => new TestObject
        {
            Test = new TestThingy { SomeText = "abc", SomeText2 = "def" }
        };

        [Fact]
        public void MeasuredSerialize()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            MeasuredSerializeImpl(model);

            model.CompileInPlace();
            MeasuredSerializeImpl(model);

            MeasuredSerializeImpl(model.Compile());
        }
        private void MeasuredSerializeImpl(TypeModel model)
        {
            var obj = GetTestInstance();
            var ms = new MemoryStream();
            model.Serialize(ms, obj); // regular serialize
            Assert.Equal(14, ms.Length);
            var expected = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Log(expected);
            Assert.Equal("0A-0C-0A-05-0A-03-64-65-66-12-03-61-62-63", expected);

            /*
Field #1: 0A String Length = 12, Hex = 0C, UTF8 = "  defabc"
As sub-object :
  Field #1: 0A String Length = 5, Hex = 0C, UTF8 = " def"
  As sub-object :
    Field #1: 0A String Length = 3, Hex = 0C, UTF8 = "def"
  Field #2: 65 String Length = 3, Hex = 66, UTF8 = "abc"
             */


            // now try measured
            if ((object)RuntimeTypeModel.Default is IMeasuredProtoOutput<IBufferWriter<byte>> writer)
            {
                using var measured = writer.Measure(obj);
                Assert.Equal(ms.Length, measured.Length);

#if !NET462

                int hitsBefore = measured.GetLengthHits(out int missesBefore);

                var abw = new ArrayBufferWriter<byte>();
                writer.Serialize(measured, abw);
                Assert.Equal(ms.Length, abw.WrittenCount);

                var mem = abw.WrittenMemory;
                Assert.True(MemoryMarshal.TryGetArray(mem, out var segment));
                var actual = BitConverter.ToString(segment.Array, segment.Offset, segment.Count);
                Log(actual);
                Assert.Equal(expected, actual);

                int hitsAfter = measured.GetLengthHits(out int missesAfter);

                Log($"hits: {hitsAfter - hitsBefore}, misses: {missesAfter - missesBefore}");
                Assert.True(hitsAfter > hitsBefore, "got hits");
                Assert.Equal(0, missesBefore - missesBefore);
#endif
            }
        }

        [ProtoContract]
        public class TestObject
        {
            [ProtoMember(1)]
            public TestThingy Test { get; set; }
        }

        [ProtoContract]
        [ProtoInclude(1, typeof(TestThingy))]
        public abstract class TestBase
        {
            [ProtoMember(2)]
            public string SomeText { get; set; }

            public abstract string SomeText2 { get; set; }
        }

        [ProtoContract]
        public class TestThingy : TestBase
        {
            [ProtoMember(1)]
            public override string SomeText2 { get; set; }
        }
    }
}


<|start_filename|>src/protobuf-net.Core/Serializers/EnumSerializer.cs<|end_filename|>
﻿using ProtoBuf.Internal;
using System;
using System.Runtime.CompilerServices;

namespace ProtoBuf.Serializers
{
    /// <summary>
    /// Provides utility methods for creating enum serializers
    /// </summary>
    public static class EnumSerializer
    {
        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateSByte<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerSByte<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateInt16<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerInt16<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateInt32<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerInt32<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateInt64<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerInt64<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateByte<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerByte<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateUInt16<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerUInt16<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateUInt32<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerUInt32<T>>.InstanceField;

        /// <summary>
        /// Create an enum serializer for the provided type, which much be a matching enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public static EnumSerializer<T> CreateUInt64<T>()
            where T : unmanaged
            => SerializerCache<EnumSerializerUInt64<T>>.InstanceField;
    }

    /// <summary>
    /// Base type for enum serializers
    /// </summary>
    public abstract class EnumSerializer<TEnum>
        : ISerializer<TEnum>, ISerializer<TEnum?>

        where TEnum : unmanaged
    {
        SerializerFeatures ISerializer<TEnum>.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar;
        SerializerFeatures ISerializer<TEnum?>.Features => SerializerFeatures.WireTypeVarint | SerializerFeatures.CategoryScalar;

        [MethodImpl(ProtoReader.HotPath)]
        TEnum? ISerializer<TEnum?>.Read(ref ProtoReader.State state, TEnum? value)
            => Read(ref state, default);
        [MethodImpl(ProtoReader.HotPath)]
        void ISerializer<TEnum?>.Write(ref ProtoWriter.State state, TEnum? value)
            => Write(ref state, value.Value);

        /// <summary>
        /// Deserialize an enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public abstract TEnum Read(ref ProtoReader.State state, TEnum value);

        /// <summary>
        /// Serialize an enum
        /// </summary>
        [MethodImpl(ProtoReader.HotPath)]
        public abstract void Write(ref ProtoWriter.State state, TEnum value);

        private protected EnumSerializer() { }
    }
    internal abstract class EnumSerializer<TEnum, TRaw> : EnumSerializer<TEnum>
        , IMeasuringSerializer<TEnum>, IMeasuringSerializer<TEnum?>
        where TRaw : unmanaged
        where TEnum : unmanaged
    {
        private protected const int NegLength = 10;
        private protected unsafe EnumSerializer()
        {
            Type tEnum = typeof(TEnum);
            if (sizeof(TEnum) != sizeof(TRaw) || !tEnum.IsEnum || Enum.GetUnderlyingType(tEnum) != typeof(TRaw))
            {
                ThrowHelper.ThrowInvalidOperationException($"{typeof(TEnum).NormalizeName()} is not a valid enum for {typeof(TRaw).NormalizeName()}");
            }
        }

        [MethodImpl(ProtoReader.HotPath)]
        protected abstract TRaw Read(ref ProtoReader.State state);
        [MethodImpl(ProtoReader.HotPath)]
        protected abstract void Write(ref ProtoWriter.State state, TRaw value);
        [MethodImpl(ProtoReader.HotPath)]
        public abstract int MeasureVarint(TRaw value);
        [MethodImpl(ProtoReader.HotPath)]
        public virtual int MeasureSignedVarint(TRaw value) => -1;

        [MethodImpl(ProtoReader.HotPath)]
        public unsafe override TEnum Read(ref ProtoReader.State state, TEnum value)
        {
            var raw = Read(ref state);
            return *(TEnum*)&raw;
        }
        [MethodImpl(ProtoReader.HotPath)]
        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) => wireType switch
        {
            WireType.Fixed32 => 4,
            WireType.Fixed64 => 8,
            WireType.Varint => MeasureVarint(*(TRaw*)&value),
            WireType.SignedVarint => MeasureSignedVarint(*(TRaw*)&value),
            _ => -1,
        };

        int IMeasuringSerializer<TEnum?>.Measure(ISerializationContext context, WireType wireType, TEnum? value)
            => Measure(context, wireType, value.Value);
    }

    internal sealed class EnumSerializerSByte<T> : EnumSerializer<T, sbyte> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override sbyte Read(ref ProtoReader.State state) => state.ReadSByte();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, sbyte value) => state.WriteSByte(value);

        public override int MeasureVarint(sbyte value) => value < 0 ? NegLength : ProtoWriter.MeasureUInt32((uint)value);
        public override int MeasureSignedVarint(sbyte value) => ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value));
    }
    internal sealed class EnumSerializerInt16<T> : EnumSerializer<T, short> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override short Read(ref ProtoReader.State state) => state.ReadInt16();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, short value) => state.WriteInt16(value);
        public override int MeasureVarint(short value) => value < 0 ? NegLength : ProtoWriter.MeasureUInt32((uint)value);
        public override int MeasureSignedVarint(short value) => ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value));
    }
    internal sealed class EnumSerializerInt32<T> : EnumSerializer<T, int> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override int Read(ref ProtoReader.State state) => state.ReadInt32();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, int value) => state.WriteInt32(value);
        public override int MeasureVarint(int value) => value < 0 ? NegLength : ProtoWriter.MeasureUInt32((uint)value);
        public override int MeasureSignedVarint(int value) => ProtoWriter.MeasureUInt32(ProtoWriter.Zig(value));
    }
    internal sealed class EnumSerializerInt64<T> : EnumSerializer<T, long> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override long Read(ref ProtoReader.State state) => state.ReadInt64();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, long value) => state.WriteInt64(value);
        public override int MeasureVarint(long value) => ProtoWriter.MeasureUInt64((ulong)value);
        public override int MeasureSignedVarint(long value) => ProtoWriter.MeasureUInt64(ProtoWriter.Zig(value));
    }
    internal sealed class EnumSerializerByte<T> : EnumSerializer<T, byte> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override byte Read(ref ProtoReader.State state) => state.ReadByte();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, byte value) => state.WriteByte(value);

        public override int MeasureVarint(byte value) => ProtoWriter.MeasureUInt32(value);
    }
    internal sealed class EnumSerializerUInt16<T> : EnumSerializer<T, ushort> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override ushort Read(ref ProtoReader.State state) => state.ReadUInt16();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, ushort value) => state.WriteUInt16(value);

        public override int MeasureVarint(ushort value) => ProtoWriter.MeasureUInt32(value);
    }
    internal sealed class EnumSerializerUInt32<T> : EnumSerializer<T, uint> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override uint Read(ref ProtoReader.State state) => state.ReadUInt32();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, uint value) => state.WriteUInt32(value);

        public override int MeasureVarint(uint value) => ProtoWriter.MeasureUInt32(value);
    }
    internal sealed class EnumSerializerUInt64<T> : EnumSerializer<T, ulong> where T : unmanaged
    {
        [MethodImpl(ProtoReader.HotPath)]
        protected override ulong Read(ref ProtoReader.State state) => state.ReadUInt64();
        [MethodImpl(ProtoReader.HotPath)]
        protected override void Write(ref ProtoWriter.State state, ulong value) => state.WriteUInt64(value);

        public override int MeasureVarint(ulong value) => ProtoWriter.MeasureUInt64(value);
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/DecimalSerializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class DecimalSerializer : IRuntimeProtoSerializerNode
    {
        private enum Variant
        {
            BclDecimal,
            String
        }

        private static DecimalSerializer s_BclDecimal, s_String;

        public static DecimalSerializer Create(CompatibilityLevel compatibilityLevel)
        {
            if (compatibilityLevel < CompatibilityLevel.Level300)
                return s_BclDecimal ??= new DecimalSerializer(Variant.BclDecimal);
            return s_String ??= new DecimalSerializer(Variant.String);
        }

        private readonly Variant _variant;
        private DecimalSerializer(Variant variant) => _variant = variant;

        private static readonly Type expectedType = typeof(decimal);

        public Type ExpectedType => expectedType;

        bool IRuntimeProtoSerializerNode.RequiresOldValue => false;

        bool IRuntimeProtoSerializerNode.ReturnsValue => true;

        public object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return _variant switch
            {
                Variant.String => BclHelpers.ReadDecimalString(ref state),
                _ => BclHelpers.ReadDecimal(ref state),
            };
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            switch (_variant)
            {
                case Variant.String:
                    BclHelpers.WriteDecimalString(ref state, (decimal)value);
                    break;
                default:
                    BclHelpers.WriteDecimal(ref state, (decimal)value);
                    break;
            }
        }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            ctx.EmitStateBasedWrite(_variant switch
            {
                Variant.String => nameof(BclHelpers.WriteDecimalString),
                _ => nameof(BclHelpers.WriteDecimal),
            }, valueFrom, typeof(BclHelpers));
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            ctx.EmitStateBasedRead(typeof(BclHelpers), _variant switch
            {
                Variant.String => nameof(BclHelpers.ReadDecimalString),
                _ => nameof(BclHelpers.ReadDecimal),
            }, ExpectedType);
        }
    }
}

<|start_filename|>src/Examples/Issues/Issue203.cs<|end_filename|>
﻿#if FEAT_DYNAMIC_REF

using ProtoBuf;
using System;
using System.Collections.Generic;
using Xunit;

namespace Examples.Issues
{

    public class Issue203
    {
        [ProtoContract(SkipConstructor = true)]
        public class SerializeClass
        {
            [ProtoMember(1, AsReference = true)]
            private SomeCollection _someList = null;
            public SomeCollection SomeList
            {
                get
                {
                    return _someList;
                }
                set
                {
                    _someList = value;
                }
            }
        }

        public class SomeCollection : List<SomeCollectionItem>
        { }

        [ProtoContract(SkipConstructor = true)]
        public class SomeCollectionItem
        {
            public SomeCollectionItem()
            {
                throw new InvalidOperationException("I should never be called");
            }

            public SomeCollectionItem(string init)
            {
                SomeField = init;
            }

            [ProtoMember(1)]
            public string SomeField;
        }

        [Fact]
        public void Execute()
        {
            for (int i = 0; i < 5; i++)
            {
                SerializeClass m = new SerializeClass();

                var u = new SomeCollectionItem("ABC");
                m.SomeList = new SomeCollection();
                m.SomeList.Add(u);
                m.SomeList.Add(u);

                var clone = Serializer.DeepClone(m);
                Assert.NotSame(m, clone);
            }
        }
    }
}


#endif

<|start_filename|>src/protobuf-net.Test/Perf/Primitives.cs<|end_filename|>
﻿using ProtoBuf.Internal;
using ProtoBuf.Meta;
using ProtoBuf.WellKnownTypes;
using System;
using System.IO;
using Xunit;

namespace ProtoBuf.Perf
{
    public class Primitives
    {
        [Fact]
        public void DecimalIsOptimized()
        {
            Assert.True(PrimaryTypeProvider.DecimalOptimized);
        }

        [Theory]
        [InlineData(true)]
        [InlineData(false)]
#pragma warning disable xUnit1026
        public void CheckDecimalLayout(bool optimized)
#pragma warning restore xUnit1026
        {
            bool oldVal = PrimaryTypeProvider.GuidOptimized;
            decimal value = 1.0000000000045000000003000000M;
            try
            {
#if DEBUG
                PrimaryTypeProvider.DecimalOptimized = optimized;
#endif
                using var ms = new MemoryStream();
                var writeState = ProtoWriter.State.Create(ms, RuntimeTypeModel.Default);
                try
                {
                    writeState.WriteFieldHeader(1, WireType.String);
                    BclHelpers.WriteDecimal(ref writeState, value);
                    writeState.Close();
                }
                finally
                {
                    writeState.Dispose();
                }
                var hex = BitConverter.ToString(
                    ms.GetBuffer(), 0, (int)ms.Length);
                Assert.Equal("0A-12-08-C0-8D-C9-B8-C0-B4-B8-E2-3E-10-DE-9C-BF-82-02-18-38", hex);

                ms.Position = 0;
                var readState = ProtoReader.State.Create(ms, RuntimeTypeModel.Default);
                try
                {
                    Assert.Equal(1, readState.ReadFieldHeader());
                    var result = BclHelpers.ReadDecimal(ref readState);
                    Assert.Equal(value, result);
                    Assert.Equal(0, readState.ReadFieldHeader());
                }
                finally
                {
                    readState.Dispose();
                }
            }
            finally
            {
#if DEBUG
                PrimaryTypeProvider.DecimalOptimized = oldVal;
#endif
            }
        }

        [Fact]
        public void GuidIsOptimized()
        {
            Assert.True(PrimaryTypeProvider.GuidOptimized);
        }

        [Theory]
        [InlineData(true)]
        [InlineData(false)]
#pragma warning disable xUnit1026
        public void CheckGuidLayout(bool optimized)
#pragma warning restore xUnit1026
        {
            Assert.True(Guid.TryParse("12345678-2345-3456-4567-56789a6789ab", out var value));

            bool oldVal = PrimaryTypeProvider.GuidOptimized;
            try
            {
#if DEBUG
                PrimaryTypeProvider.GuidOptimized = optimized;
#endif
                using var ms = new MemoryStream();
                CheckGuidLayoutImpl(ms, value, "0A-12-09-78-56-34-12-45-23-56-34-11-45-67-56-78-9A-67-89-AB");
                for (int i = 0; i < 100; i++)
                {
                    value = Guid.NewGuid();
                    CheckGuidLayoutImpl(ms, value, null);
                }
            }
            finally
            {
#if DEBUG
                PrimaryTypeProvider.GuidOptimized = oldVal;
#endif
            }

        }

        private void CheckGuidLayoutImpl(MemoryStream ms, Guid value, string expected)
        {
            ms.Position = 0;
            ms.SetLength(0);
            var state = ProtoWriter.State.Create(ms, RuntimeTypeModel.Default);
            try
            {
                state.WriteFieldHeader(1, WireType.String);
                BclHelpers.WriteGuid(ref state, value);
                state.Close();
            }
            finally
            {
                state.Dispose();
            }

            if (expected != null)
            {
                var hex = BitConverter.ToString(
                    ms.GetBuffer(), 0, (int)ms.Length);
                Assert.Equal(expected, hex);
            }

            ms.Position = 0;
            var readState = ProtoReader.State.Create(ms, RuntimeTypeModel.Default);
            try
            {
                Assert.Equal(1, readState.ReadFieldHeader());
                var result = BclHelpers.ReadGuid(ref readState);
                Assert.Equal(value, result);
                Assert.Equal(0, readState.ReadFieldHeader());
            }
            finally
            {
                readState.Dispose();
            }
        }
    }
}


<|start_filename|>src/protobuf-net.Core/ISerializationContext.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using System;

namespace ProtoBuf
{
    /// <summary>
    /// Represents common state during a serialization operation; this instance should not be stored - it may be reused later with different meaning
    /// </summary>
    public interface ISerializationContext
    {
        /// <summary>
        /// The type-model that represents the operation
        /// </summary>
        TypeModel Model { get; }

        /// <summary>
        /// Addition information about this serialization operation.
        /// </summary>
        object UserState { get; }
    }
}


<|start_filename|>src/protobuf-net.Core/Meta/ServiceMethod.cs<|end_filename|>
﻿using ProtoBuf.WellKnownTypes;
using System;
namespace ProtoBuf.Meta
{
    /// <summary>
    /// Describes a method of a service.
    /// </summary>
    public sealed class ServiceMethod
    {
        /// <summary>
        /// The name of the method.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// The type sent by the client.
        /// </summary>
        public Type InputType { get; set; } = typeof(Empty);

        /// <summary>
        /// The type returned from the server.
        /// </summary>
        public Type OutputType { get; set; } = typeof(Empty);

        /// <summary>
        /// Identifies if server streams multiple server messages.
        /// </summary>
        public bool ServerStreaming { get; set; }

        /// <summary>
        /// Identifies if client streams multiple client messages.
        /// </summary>
        public bool ClientStreaming { get; set; }
    }
}


<|start_filename|>assorted/SampleDto/Orders.cs<|end_filename|>
﻿using System;
using System.Runtime.Serialization;

namespace SampleDto
{
    #if !FX11
    [DataContract]
#endif
    public class OrderHeader
    {
        private int _id;
        #if !FX11
        [DataMember(Order=1)]
#endif
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _customerRef;
        #if !FX11
        [DataMember(Order=2)]
#endif
        public string CustomerRef
        {
            get { return _customerRef; }
            set { _customerRef = value; }
        }

        private DateTime _orderDate;
        #if !FX11
        [DataMember(Order=3)]
#endif
        public DateTime OrderDate
        {
            get { return _orderDate; }
            set { _orderDate = value; }
        }

        private DateTime _dueDate;
        #if !FX11
        [DataMember(Order=4)]
#endif
        public DateTime DueDate
        {
            get { return _dueDate; }
            set { _dueDate = value; }
        }

        private OrderDetail[] lines = new OrderDetail[0];
        #if !FX11
        [DataMember(Order = 5)]
#endif
        public OrderDetail[] Lines { get { return lines; } set { lines = value; } }
    }

    #if !FX11
    [DataContract]
#endif
    public class OrderDetail
    {
        private int _lineNumber;
        #if !FX11
        [DataMember(Order=1)]
#endif
        public int LineNumber
        {
            get { return _lineNumber; }
            set { _lineNumber = value; }
        }

        private string _sku;
        #if !FX11
        [DataMember(Order=2)]
#endif
        public string SKU
        {
            get { return _sku; }
            set { _sku = value; }
        }

        private int _quantity;
        #if !FX11
        [DataMember(Order=3)]
        #endif
        public int Quantity
        {
            get { return _quantity; }
            set { _quantity = value; }
        }

        private decimal _unitPrice;
        #if !FX11
        [DataMember(Order=4)]
        #endif
        public decimal UnitPrice
        {
            get { return _unitPrice; }
            set { _unitPrice = value; }
        }

        private decimal _notes;
        #if !FX11
        [DataMember(Order=5)]
        #endif
        public decimal Notes
        {
            get { return _notes; }
            set { _notes = value; }
        }
    }
}


<|start_filename|>src/protobuf-net.Test/Serializers/Writer.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace ProtoBuf.unittest.Serializers
{
    public class Writer
    {
        [Fact]
        public void TestString_abc()
        {
            Util.Test((ref ProtoWriter.State st) =>
            {
                st.WriteFieldHeader(1, WireType.String);
                st.WriteString("abc");
            }, "0A03616263");
        }
        [Fact]
        public void TestVariantInt32()
        {
            for (int i = 0; i < 128; i++)
            {
                Util.Test((ref ProtoWriter.State st) =>
                  {
                      st.WriteFieldHeader(1, WireType.Varint);
                      st.WriteInt32(i);
                  }, "08" // 1 * 8 + 0
                 + i.ToString("X2")
                );
            }
            Util.Test((ref ProtoWriter.State st) => {
                st.WriteFieldHeader(1, WireType.Varint);
                st.WriteInt32(128);
            }, "088001");
        }
    }
}

<|start_filename|>src/Benchmark/SpanPerformance.cs<|end_filename|>
﻿using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Buffers;
using System.IO;

#if NEW_API
namespace Benchmark
{
    [SimpleJob(RuntimeMoniker.Net472), SimpleJob(RuntimeMoniker.NetCoreApp31), SimpleJob(RuntimeMoniker.NetCoreApp50), MemoryDiagnoser]
    public class SpanPerformance
    {
        private MemoryStream _ms;
        private ReadOnlySequence<byte> _ros;
        public ProtoReader.State ReadMS()
            => ProtoReader.State.Create(_ms, Model);

        public ProtoReader.State ReadROS()
            => ProtoReader.State.Create(_ros, Model);

        public ProtoReader.State ReadROM()
        {
            if (!_ros.IsSingleSegment) throw new InvalidOperationException("Expected single segment");
            return ProtoReader.State.Create(_ros.First, Model);
        }

        public TypeModel Model => RuntimeTypeModel.Default;

        [GlobalSetup]
        public void Setup()
        {
            var data = File.ReadAllBytes("nwind.proto.bin");
            _ms = new MemoryStream(data);
            _ros = new ReadOnlySequence<byte>(data);
        }

        [Benchmark(Baseline = true)]
        public void MemoryStream()
        {
            _ms.Position = 0;
            using var reader = ReadMS();
            var dal = reader.DeserializeRoot<protogen.Database>();
            GC.KeepAlive(dal);
        }

        [Benchmark]
        public void ReadOnlySequence()
        {
            using var reader = ReadROS();
            var dal = reader.DeserializeRoot<protogen.Database>();
            GC.KeepAlive(dal);
        }
        [Benchmark]
        public void ReadOnlyMemory()
        {
            using var reader = ReadROM();
            var dal = reader.DeserializeRoot<protogen.Database>();
            GC.KeepAlive(dal);
        }
    }
}
#endif

<|start_filename|>src/protobuf-net/Internal/Serializers/Int32Serializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;
using System.Reflection;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class Int32Serializer : IRuntimeProtoSerializerNode, IDirectWriteNode
    {
        private Int32Serializer() { }
        internal static readonly Int32Serializer Instance = new Int32Serializer();

        private static readonly Type expectedType = typeof(int);

        public Type ExpectedType => expectedType;

        bool IRuntimeProtoSerializerNode.RequiresOldValue => false;

        bool IRuntimeProtoSerializerNode.ReturnsValue => true;

        public object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return state.ReadInt32();
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteInt32((int)value);
        }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            ctx.EmitStateBasedWrite(nameof(ProtoWriter.State.WriteInt32), valueFrom);
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            ctx.EmitStateBasedRead(nameof(ProtoReader.State.ReadInt32), ExpectedType);
        }

        bool IDirectWriteNode.CanEmitDirectWrite(WireType wireType) => wireType == WireType.Varint;

        void IDirectWriteNode.EmitDirectWrite(int fieldNumber, WireType wireType, Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using var loc = ctx.GetLocalWithValue(typeof(int), valueFrom);
            ctx.LoadState();
            ctx.LoadValue(fieldNumber);
            ctx.LoadValue(loc);
            ctx.EmitCall(typeof(ProtoWriter.State).GetMethod(nameof(ProtoWriter.State.WriteInt32Varint), BindingFlags.Instance | BindingFlags.Public,
                null, new[] { typeof(int), typeof(int) }, null));
        }
    }
}

<|start_filename|>src/protobuf-net.Test/CompatibilityLevelConfigTests.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using System;
using Xunit;
using Xunit.Abstractions;

namespace ProtoBuf.Test
{
    // explore different ways of manually configuring the compatibility level
    public class CompatibilityLevelConfigTests
    {
        private readonly ITestOutputHelper _log;
        public CompatibilityLevelConfigTests(ITestOutputHelper log)
            => _log = log;

        private string Log(string message)
        {
            _log?.WriteLine(message);
            return message;
        }

        private static TypeModel CreateModelVanilla()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            var mt = model.Add<SomeRandomType>();
            Assert.Equal(CompatibilityLevel.Level200, mt.CompatibilityLevel);
            return model;
        }

        private static TypeModel CreateModelDefaulted()
        {
            var model = RuntimeTypeModel.Create();
            model.DefaultCompatibilityLevel = CompatibilityLevel.Level300;
            model.AutoCompile = false;
            var mt = model.Add<SomeRandomType>();
            Assert.Equal(CompatibilityLevel.Level300, mt.CompatibilityLevel);
            return model;
        }

        private static TypeModel CreateModelCallback()
        {
            var model = RuntimeTypeModel.Create();
            model.BeforeApplyDefaultBehaviour += (s, e) => e.MetaType.CompatibilityLevel = CompatibilityLevel.Level300;
            model.AutoCompile = false;
            var mt = model.Add<SomeRandomType>();
            Assert.Equal(CompatibilityLevel.Level300, mt.CompatibilityLevel);
            return model;
        }

        [Fact]
        public void VanillaSchema()
            => Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Test;
import ""protobuf-net/bcl.proto""; // schema for protobuf-net's handling of core .NET types

message SomeRandomType {
   .bcl.Guid Id = 1; // default value could not be applied: 00000000-0000-0000-0000-000000000000
   .bcl.DateTime When = 2;
}
", Log(CreateModelVanilla().GetSchema(typeof(SomeRandomType), ProtoSyntax.Proto3)), ignoreLineEndingDifferences: true);

        [Fact]
        public void ModelDefaultedSchema()
    => Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Test;
import ""google/protobuf/timestamp.proto"";

message SomeRandomType {
   string Id = 1; // default value could not be applied: 00000000-0000-0000-0000-000000000000
   .google.protobuf.Timestamp When = 2;
}
", Log(CreateModelDefaulted().GetSchema(typeof(SomeRandomType), ProtoSyntax.Proto3)), ignoreLineEndingDifferences: true);

        [Fact]
        public void CallbackHookSchema()
    => Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Test;
import ""google/protobuf/timestamp.proto"";

message SomeRandomType {
   string Id = 1; // default value could not be applied: 00000000-0000-0000-0000-000000000000
   .google.protobuf.Timestamp When = 2;
}
", Log(CreateModelCallback().GetSchema(typeof(SomeRandomType), ProtoSyntax.Proto3)), ignoreLineEndingDifferences: true);

        [ProtoContract]
        public class SomeRandomType
        {
            [ProtoMember(1)]
            public Guid Id { get; set; }
            [ProtoMember(2)]
            public DateTime When { get; set; }
        }
    }

    
}


<|start_filename|>src/protobuf-net.AspNetCore/Formatters/ProtoInputFormatter.cs<|end_filename|>
﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.WebUtilities;
using ProtoBuf.Meta;
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Threading;
using System.Threading.Tasks;

namespace ProtoBuf.AspNetCore.Formatters
{
    /// <summary>
    /// Implements a protobuf-net based input formatter
    /// </summary>
    public sealed class ProtoInputFormatter : InputFormatter
    {
        private readonly TypeModel _model;
        private readonly int _memoryBufferThreshold;
        private readonly bool _suppressBuffering;

        /// <summary>
        /// Create a new <see cref="ProtoInputFormatter"/> instance
        /// </summary>
        public ProtoInputFormatter(MvcProtoBufNetOptions options, MvcOptions mvcOptions)
        {
            _model = options.Model ?? RuntimeTypeModel.Default;
            _memoryBufferThreshold = options.ReadMemoryBufferThreshold;
            _suppressBuffering = mvcOptions.SuppressInputFormatterBuffering;
        }

        /// <inheritdoc/>
        protected override bool CanReadType(Type type)
            => _model.CanSerializeContractType(type);

        /// <inheritdoc/>
        public override Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
        {
            // default implementation does length checks; we *really* don't want those, since
            // zero length is a perfectly valid payload in protobuf
            return ReadRequestBodyAsync(context);
        }

        /// <inheritdoc/>
        public override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            // note: *today*, protobuf-net lacks fully async read, so this buffers in the pipe until
            // we get the Content-Length that was advertised by the caller

            if (context is null) throw new ArgumentNullException(nameof(context));
            var request = context.HttpContext.Request;

            var length = request.ContentLength ?? -1;
            if (length < 0 || length > _memoryBufferThreshold)
            {
                // use Stream-based read - either chunked or oversized
                // - if buffering is disabled, or if the caller has already buffered it fully (EnableRewind), go direct
                // - otherwise uses FileBufferingReadStream based on _memoryBufferThreshold
                return (_suppressBuffering || request.Body.CanSeek) ? DirectStreamAsync(context) : BufferedStreamAsync(context);
            }

            // otherwise, we can use the Pipe itself for in-memory buffering
            var reader = request.BodyReader;

            // try and read synchronously
            if (reader.TryRead(out var readResult) && ProcessReadBuffer(context.ModelType, reader, length, readResult, out var payload))
            {
                return InputFormatterResult.SuccessAsync(payload);
            }
            return ReadRequestBodyAsyncSlow(context.ModelType, reader, length);
        }

        private Task<InputFormatterResult> DirectStreamAsync(InputFormatterContext context)
        {
            var payload = _model.Deserialize(context.HttpContext.Request.Body, value: null, type: context.ModelType);
            return InputFormatterResult.SuccessAsync(payload);
        }
        private async Task<InputFormatterResult> BufferedStreamAsync(InputFormatterContext context)
        {
            using var readStream = new FileBufferingReadStream(context.HttpContext.Request.Body, _memoryBufferThreshold);
            await readStream.DrainAsync(CancellationToken.None);
            readStream.Position = 0;
            var payload = _model.Deserialize(readStream, value: null, type: context.ModelType);
            return InputFormatterResult.Success(payload);
        }

        private bool ProcessReadBuffer(Type type, PipeReader reader, long length, in ReadResult readResult, out object payload)
        {
            if (readResult.IsCanceled) throw new OperationCanceledException();
            var buffer = readResult.Buffer;
            if (ParseIfComplete(type, ref buffer, length, out payload))
            {
                // mark consumed
                reader.AdvanceTo(buffer.End, buffer.End);
                return true;
            }
            else if (readResult.IsCompleted)
            {
                throw new InvalidOperationException($"Incomplete protobuf payload received; got {buffer.Length} of {length} bytes");
            }
            // not enough data; put it back by saying we looked at everything and took nothing
            reader.AdvanceTo(buffer.Start, buffer.End);
            return false;
        }

        private async Task<InputFormatterResult> ReadRequestBodyAsyncSlow(Type type, PipeReader reader, long length)
        {
            while (true)
            {
                var readResult = await reader.ReadAsync();
                if (ProcessReadBuffer(type, reader, length, readResult, out var payload))
                {
                    return InputFormatterResult.Success(payload);
                }
            }
        }
        private bool ParseIfComplete(Type type, ref ReadOnlySequence<byte> buffer, long expectedLength, out object payload)
        {
            long availableLength = buffer.Length;
            if (availableLength < expectedLength)
            {   // not enough (yet, we can retry later)
                payload = default;
                return false;
            }
            else if (availableLength > expectedLength)
            {   // too much; cut it down to size
                buffer = buffer.Slice(0, expectedLength);
            }

            payload = _model.Deserialize(buffer, type: type);
            return true;
        }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/CharSerializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class CharSerializer : UInt16Serializer
    {
        private CharSerializer() : base() { }
        internal static new readonly CharSerializer Instance = new CharSerializer();

        private static readonly Type expectedType = typeof(char);

        public override Type ExpectedType => expectedType;

        public override void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteUInt16((ushort)(char)value);
        }

        public override object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return (char)state.ReadUInt16();
        }

        // no need for any special IL here; ushort and char are
        // interchangeable as long as there is no boxing/unboxing
    }
}

<|start_filename|>src/Examples/DictionaryTests.cs<|end_filename|>
﻿using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Xunit;
using Xunit.Abstractions;

namespace Examples.Dictionary
{
    [ProtoContract]
    class DataWithDictionary<T>
    {
        public DataWithDictionary()
        {
            Data = new Dictionary<int, T>();
        }
        [ProtoMember(1)]
        public IDictionary<int, T> Data { get; private set; }
    }

    [ProtoContract]
    class SimpleData : IEquatable<SimpleData>
    {
        public SimpleData() {}
        public SimpleData(int value) {
            Value = value;}

        [ProtoMember(1)]
        public int Value { get; set; }

        public bool Equals(SimpleData other)
        {
            return Value == other.Value;
        }

        public override int GetHashCode() => Value.GetHashCode();
        public override bool Equals(object obj)
        {
            return Equals(obj as SimpleData);
        }
    }


    public class DictionaryTests
    {
        [Fact]
        public void TestNestedDictionaryWithStrings()
        {
            var obj = new DataWithDictionary<string>();
            obj.Data[0] = "abc";
            obj.Data[4] = "def";
            obj.Data[7] = "abc";

            var clone = Serializer.DeepClone(obj);
            Assert.NotSame(obj,clone);
            AssertEqual(obj.Data, clone.Data);
        }

        [Fact]
        public void TestNestedDictionaryWithSimpleData()
        {
            var obj = new DataWithDictionary<SimpleData>();
            obj.Data[0] = new SimpleData(5);
            obj.Data[4] = new SimpleData(72);
            obj.Data[7] = new SimpleData(72);

            var clone = Serializer.DeepClone(obj);
            Assert.NotSame(obj, clone);
            AssertEqual(obj.Data, clone.Data);
        }

        [Fact]
        public void RoundtripDictionary()
        {
            var lookup = new Dictionary<int, string>
            {
                [0] = "abc",
                [4] = "def",
                [7] = "abc"
            };

            var clone = Serializer.DeepClone(lookup);
            
            AssertEqual(lookup, clone);
        }
        static void AssertEqual<TKey, TValue>(
            IDictionary<TKey, TValue> expected,
            IDictionary<TKey, TValue> actual)
        {
            Assert.NotSame(expected, actual); //, "Instance");
            Assert.Equal(expected.Count, actual.Count); //, "Count");
            foreach (var pair in expected)
            {
                Assert.True(actual.TryGetValue(pair.Key, out TValue value)); //, "Missing: " + pair.Key);
                Assert.Equal(pair.Value, value); //, "Value: " + pair.Key);
            }
        }
    }
    
    public class EmptyDictionaryTests
    {
        [Fact]
        public void EmptyDictionaryShouldDeserializeAsNonNull()
        {
            using var ms = new MemoryStream();
            var data = new Dictionary<string, int>();

            Serializer.Serialize(ms, data);
            ms.Position = 0;
            var clone = Serializer.Deserialize<Dictionary<string, int>>(ms);

            Assert.NotNull(clone);
            Assert.Empty(clone);
        }
        [Fact]
        public void NonEmptyDictionaryShouldDeserialize()
        {
            using var ms = new MemoryStream();
            var data = new Dictionary<string, int> { { "abc", 123 } };

            Serializer.Serialize(ms, data);
            ms.Position = 0;
            var clone = Serializer.Deserialize<Dictionary<string, int>>(ms);

            Assert.NotNull(clone);
            Assert.Single(clone);
            Assert.Equal(123, clone["abc"]);
        }
        [Fact]
        public void EmptyDictionaryShouldDeserializeAsNonNullViaInterface()
        {
            using var ms = new MemoryStream();
            var data = new Dictionary<string, int>();

            Serializer.Serialize(ms, data);
            Assert.Equal(0, ms.Length);
            ms.Position = 0;
            var clone = Serializer.Deserialize<IDictionary<string, int>>(ms);

            Assert.NotNull(clone);
            Assert.Equal(0, clone.Count);

        }
        [Fact]
        public void NonEmptyDictionaryShouldDeserializeViaInterface()
        {
            using var ms = new MemoryStream();
            var data = new Dictionary<string, int> { { "abc", 123 } };

            Serializer.Serialize(ms, data);
            ms.Position = 0;
            var clone = Serializer.Deserialize<IDictionary<string, int>>(ms);

            Assert.NotNull(clone);
            Assert.Equal(1, clone.Count);
            Assert.Equal(123, clone["abc"]);
        }
    }
    
    public class NestedDictionaryTests
    {
        const string ExpectedHex = "0A-11-0A-03-61-62-63-12-0A-0A-03-64-65-66-12-03-67-68-69";
        /*
0A = field 1, type String
11 = length 17
  0A = field 1, type String
  03 = length 3
  61-62-63 = "abc"
  12 = field 2, type String
  0A = length 10
    0A = field 1, type String
    03 = length 3
    64-65-66 = "def"
    12 = field 2, type String
    03 = length 3
    67-68-69 = "ghi"
etc
         */
        private ITestOutputHelper Log { get; }
        public NestedDictionaryTests(ITestOutputHelper _log) => Log = _log;

        [Fact]
        public void TestNestedConcreteConcreteDictionary()
        {
            Dictionary<string, Dictionary<string, string>> data = new Dictionary<string, Dictionary<string, string>>
            {
                { "abc", new Dictionary<string,string> {{"def","ghi"}}},
                { "jkl", new Dictionary<string,string> {{"mno","pqr"},{"stu","vwx"}}}
            };
            CheckNested(data, "original");
            // CheckHex(data, ExpectedHex);
            var clone = Serializer.DeepClone(data);
            CheckNested(clone, "clone");
        }

        private static void CheckHex<T>(T data, string expected)
        {
            using var ms = new MemoryStream();
            Serializer.Serialize(ms, data);
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Assert.Equal(expected, hex);
        }

        [Fact]
        public void TestNestedInterfaceInterfaceDictionary()
        {
            IDictionary<string, IDictionary<string, string>> data = new Dictionary<string, IDictionary<string, string>>
            {
                { "abc", new Dictionary<string,string> {{"def","ghi"}}},
                { "jkl", new Dictionary<string,string> {{"mno","pqr"},{"stu","vwx"}}}
            };
            CheckNested(data, "original");
            var clone = Serializer.DeepClone(data);
            CheckNested(clone, "clone");
        }

        [Fact]
        public void TestNestedInterfaceConcreteDictionary()
        {
            IDictionary<string, Dictionary<string, string>> data = new Dictionary<string, Dictionary<string, string>>
            {
                { "abc", new Dictionary<string,string> {{"def","ghi"}}},
                { "jkl", new Dictionary<string,string> {{"mno","pqr"},{"stu","vwx"}}}
            };
            CheckNested(data, "original");
            var clone = Serializer.DeepClone(data);
            CheckNested(clone, "clone");
        }

        [Fact]
        public void TestNestedConcreteInterfaceDictionary()
        {
            Dictionary<string, IDictionary<string, string>> data = new Dictionary<string, IDictionary<string, string>>
            {
                { "abc", new Dictionary<string,string> {{"def","ghi"}}},
                { "jkl", new Dictionary<string,string> {{"mno","pqr"},{"stu","vwx"}}}
            };
            CheckNested(data, "original");
            var clone = Serializer.DeepClone(data);
            CheckNested(clone, "clone");
        }

#pragma warning disable IDE0060
        static void CheckNested<TInner>(IDictionary<string, TInner> data, string message)
#pragma warning restore IDE0060
            where TInner : IDictionary<string, string>
        {
            Assert.NotNull(data); //, message);
            Assert.Equal(2, data.Keys.Count); //, message);
            var allKeys = string.Join(", ", data.Keys.OrderBy(x => x));
            Assert.Equal("abc, jkl", allKeys);

            var inner = data["abc"];
            Assert.Equal(1, inner.Keys.Count); //, message);
            Assert.Equal("ghi", inner["def"]); //, message);
            inner = data["jkl"];
            Assert.Equal(2, inner.Keys.Count); //, message);
            Assert.Equal("pqr", inner["mno"]); //, message);
            Assert.Equal("vwx", inner["stu"]); //, message);
        }

#if LONG_RUNNING
        [Fact]
        public void CheckPerformanceNotInsanelyBad()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof (PropsViaDictionaryDefault), true);
            model.Add(typeof (PropsViaDictionaryGrouped), true);
            model.Add(typeof (PropsViaProperties), true);
            model.CompileInPlace();
            var o1 = new PropsViaProperties { Field1 = 123, Field2 = 456, Field3 = 789 };

            var o2 = new PropsViaDictionaryDefault()
            {
                Values = new List<KeyValuePair> {
                new KeyValuePair {Key = "Field1", Value =123 },
                new KeyValuePair {Key = "Field2", Value =456 },
                new KeyValuePair {Key = "Field2", Value =789 },
            }
            };
            var o3 = new PropsViaDictionaryGrouped()
            {
                Values = new List<KeyValuePair> {
                new KeyValuePair {Key = "Field1", Value =123 },
                new KeyValuePair {Key = "Field2", Value =456 },
                new KeyValuePair {Key = "Field2", Value =789 },
            }
            };


            int l1 = BulkTest(model, o1, out int s1, out int d1);
            int l2 = BulkTest(model, o2, out int s2, out int d2);
            int l3 = BulkTest(model, o3, out int s3, out int d3);

            Log.WriteLine("Bytes (props)\t" + l1);
            Log.WriteLine("Ser (props)\t" + s1);
            Log.WriteLine("Deser (props)\t" + d1);
            Log.WriteLine("Bytes (kv-default)\t" + l2);
            Log.WriteLine("Ser (kv-default)\t" + s2);
            Log.WriteLine("Deser (kv-default)\t" + d2);
            Log.WriteLine("Bytes (kv-grouped)\t" + l3);
            Log.WriteLine("Ser (kv-grouped)\t" + s3);
            Log.WriteLine("Deser (kv-grouped)\t" + d3);

            using var state = ProtoWriter.State.Create(Stream.Null, null, null);
            Stopwatch watch = Stopwatch.StartNew();
            for (int i = 0; i < LOOP; i++ ) {
                state.WriteFieldHeader(1, WireType.String);
                state.WriteString("Field1");
                state.WriteFieldHeader(1, WireType.String);
                state.WriteString("Field2");
                state.WriteFieldHeader(1, WireType.String);
                state.WriteString("Field3");
            }
            watch.Stop();
            state.Close();
            Log.WriteLine("Encoding: " + watch.ElapsedMilliseconds);
            
        }
#endif

        const int LOOP = 500000;
        static int BulkTest<T>(TypeModel model, T obj, out int serialize, out int deserialize) where T: class
        {

            using MemoryStream ms = new MemoryStream();
            Stopwatch watch = Stopwatch.StartNew();
            for (int i = 0; i < LOOP; i++)
            {
                ms.Position = 0;
                ms.SetLength(0);
                model.Serialize(ms, obj);
            }
            watch.Stop();
            serialize = (int)watch.ElapsedMilliseconds;
            watch.Reset();
            Type type = typeof(T);
            watch.Start();
            for (int i = 0; i < LOOP; i++)
            {
                ms.Position = 0;
#pragma warning disable CS0618
                model.Deserialize(ms, null, type);
#pragma warning restore CS0618
            }
            watch.Stop();
            deserialize = (int)watch.ElapsedMilliseconds;
            return (int)ms.Length;
        }


        [ProtoContract]
        public class PropsViaDictionaryDefault
        {
            [ProtoMember(1, DataFormat = DataFormat.Default)] public List<KeyValuePair> Values { get; set;}
        }
        [ProtoContract]
        public class PropsViaDictionaryGrouped
        {
            [ProtoMember(1, DataFormat = DataFormat.Group)]
            public List<KeyValuePair> Values { get; set; }
        }
        [ProtoContract]
        public class KeyValuePair
        {
            [ProtoMember(1)] public string Key { get; set;}
            [ProtoMember(2)] public int Value { get; set;}
        }
        [ProtoContract]
        class PropsViaProperties
        {
            [ProtoMember(1)] public int Field1 { get; set;}
            [ProtoMember(2)] public int Field2 { get; set;}
            [ProtoMember(3)] public int Field3 { get; set;}
        }
    }
}


<|start_filename|>src/Examples/StupidlyComplexModel.cs<|end_filename|>
﻿using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Diagnostics;
using System.Linq;
using Xunit.Abstractions;

namespace Examples
{   
    public class StupidlyComplexModel
    {
        private ITestOutputHelper Log { get; }
        public StupidlyComplexModel(ITestOutputHelper _log) => Log = _log;

#if LONG_RUNNING
        [Fact]
        public void TimeStupidlyComplexModel()
        {
            TimeModel<StupidlyComplexModel>(5, Test);
        }
        [Fact]
        public void TimeSimpleModel()
        {
            TimeModel<SimpleModel>(100);
        }
#endif

        [ProtoContract]
        public class SimpleModel
        {
            [ProtoMember(1)] public int A {get;set;}
            [ProtoMember(2)] public float B {get;set;}
            [ProtoMember(3)] public decimal C {get;set;}
            [ProtoMember(4)] public bool D {get;set;}
            [ProtoMember(5)] public byte E {get;set;}
            [ProtoMember(6)] public long F {get;set;}
            [ProtoMember(7)] public short G {get;set;}
            [ProtoMember(8)] public double H {get;set;}
            [ProtoMember(9)] public float I {get;set;}
            [ProtoMember(10)] public uint J {get;set;}
            [ProtoMember(11)] public ulong K {get;set;}
            [ProtoMember(12)] public ushort L {get;set;}
            [ProtoMember(13)] public sbyte M {get;set;}
            [ProtoMember(14)] public DateTime N {get;set;}
            [ProtoMember(15)] public string O {get;set;}
            [ProtoMember(16)] public Type P {get;set;}
            [ProtoMember(17)] public byte[] Q {get;set;}
            [ProtoMember(18)] public SimpleModel R {get;set;}
            [ProtoMember(19)] public TimeSpan S {get;set;}
            [ProtoMember(20)] public int T {get;set;}
        }

        private void TimeModel<T>(int count, Action<TypeModel, string> test = null)
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            model.Add(typeof(T), true);
            test?.Invoke(model, "Time");
            model.Compile(); // do discovery etc
            int typeCount = model.GetTypes().Cast<MetaType>().Count();

            var watch = Stopwatch.StartNew();
            for (int i = 0; i < count; i++)
            {
                model.Compile();
            }
            watch.Stop();
            Log.WriteLine(string.Format("{0}: {1}ms/Compile, {2} types, {3}ms total, {4} iteratons",
                typeof(T).Name, watch.ElapsedMilliseconds / count, typeCount, watch.ElapsedMilliseconds, count));
        }

#if LONG_RUNNING
        [Fact]
        public void TestStupidlyComplexModel()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            model.Add(typeof(Outer), true);

            Test(model, "Runtime");
            model.CompileInPlace();
            Test(model, "CompileInPlace");
            Test(model.Compile(), "Compile");

            model.Compile("TestStupidlyComplexModel", "TestStupidlyComplexModel.dll");
            PEVerify.AssertValid("TestStupidlyComplexModel.dll");
        }
#endif

        private void Test(TypeModel model, string test)
        {
            var orig = new Outer {
                Value500 = new Inner500 { Value = 123 },
                Value501 = new Inner501 { Value = 456 }
            };
            var clone = (Outer)model.DeepClone(orig);
            Assert.NotSame(orig, clone); //, test);
            
            var props = typeof(Outer).GetProperties();
            foreach (var prop in props)
            {
                switch(prop.Name)
                {
                    case "Value500":
                    case "Value501":
                        Assert.NotNull(prop.GetValue(orig)); //, test + ":orig:" + prop.Name);
                        Assert.NotNull(prop.GetValue(clone)); //, test + ":clone:" + prop.Name);
                        break;
                    default:
                        Assert.Null(prop.GetValue(orig)); //, test + ":orig:" + prop.Name);
                        Assert.Null(prop.GetValue(clone)); //, test + ":clone:" + prop.Name);
                        break;
                }
            }

            Assert.Equal(123, orig.Value500.Value); //, test + ":orig:Value500.Value");
            Assert.Equal(123, clone.Value500.Value); //, test + ":clone:Value500.Value");
            Assert.Equal(456, orig.Value501.Value); //, test + ":orig:Value501.Value");
            Assert.Equal(456, clone.Value501.Value); //, test + ":clone:Value501.Value");

            var clone500 = (Inner500)model.DeepClone(orig.Value500);
            var clone501 = (Inner501)model.DeepClone(orig.Value501);

            Assert.Equal(123, clone500.Value); //, test + ":clone500.Value");
            Assert.Equal(456, clone501.Value); //, test + ":clone501.Value");

        }
        [ProtoContract]
        public class Outer
        {
            [ProtoMember(1)]
            public Inner1 Value1 { get; set; }
            [ProtoMember(2)]
            public Inner2 Value2 { get; set; }
            [ProtoMember(3)]
            public Inner3 Value3 { get; set; }
            [ProtoMember(4)]
            public Inner4 Value4 { get; set; }
            [ProtoMember(5)]
            public Inner5 Value5 { get; set; }
            [ProtoMember(6)]
            public Inner6 Value6 { get; set; }
            [ProtoMember(7)]
            public Inner7 Value7 { get; set; }
            [ProtoMember(8)]
            public Inner8 Value8 { get; set; }
            [ProtoMember(9)]
            public Inner9 Value9 { get; set; }
            [ProtoMember(10)]
            public Inner10 Value10 { get; set; }
            [ProtoMember(11)]
            public Inner11 Value11 { get; set; }
            [ProtoMember(12)]
            public Inner12 Value12 { get; set; }
            [ProtoMember(13)]
            public Inner13 Value13 { get; set; }
            [ProtoMember(14)]
            public Inner14 Value14 { get; set; }
            [ProtoMember(15)]
            public Inner15 Value15 { get; set; }
            [ProtoMember(16)]
            public Inner16 Value16 { get; set; }
            [ProtoMember(17)]
            public Inner17 Value17 { get; set; }
            [ProtoMember(18)]
            public Inner18 Value18 { get; set; }
            [ProtoMember(19)]
            public Inner19 Value19 { get; set; }
            [ProtoMember(20)]
            public Inner20 Value20 { get; set; }
            [ProtoMember(21)]
            public Inner21 Value21 { get; set; }
            [ProtoMember(22)]
            public Inner22 Value22 { get; set; }
            [ProtoMember(23)]
            public Inner23 Value23 { get; set; }
            [ProtoMember(24)]
            public Inner24 Value24 { get; set; }
            [ProtoMember(25)]
            public Inner25 Value25 { get; set; }
            [ProtoMember(26)]
            public Inner26 Value26 { get; set; }
            [ProtoMember(27)]
            public Inner27 Value27 { get; set; }
            [ProtoMember(28)]
            public Inner28 Value28 { get; set; }
            [ProtoMember(29)]
            public Inner29 Value29 { get; set; }
            [ProtoMember(30)]
            public Inner30 Value30 { get; set; }
            [ProtoMember(31)]
            public Inner31 Value31 { get; set; }
            [ProtoMember(32)]
            public Inner32 Value32 { get; set; }
            [ProtoMember(33)]
            public Inner33 Value33 { get; set; }
            [ProtoMember(34)]
            public Inner34 Value34 { get; set; }
            [ProtoMember(35)]
            public Inner35 Value35 { get; set; }
            [ProtoMember(36)]
            public Inner36 Value36 { get; set; }
            [ProtoMember(37)]
            public Inner37 Value37 { get; set; }
            [ProtoMember(38)]
            public Inner38 Value38 { get; set; }
            [ProtoMember(39)]
            public Inner39 Value39 { get; set; }
            [ProtoMember(40)]
            public Inner40 Value40 { get; set; }
            [ProtoMember(41)]
            public Inner41 Value41 { get; set; }
            [ProtoMember(42)]
            public Inner42 Value42 { get; set; }
            [ProtoMember(43)]
            public Inner43 Value43 { get; set; }
            [ProtoMember(44)]
            public Inner44 Value44 { get; set; }
            [ProtoMember(45)]
            public Inner45 Value45 { get; set; }
            [ProtoMember(46)]
            public Inner46 Value46 { get; set; }
            [ProtoMember(47)]
            public Inner47 Value47 { get; set; }
            [ProtoMember(48)]
            public Inner48 Value48 { get; set; }
            [ProtoMember(49)]
            public Inner49 Value49 { get; set; }
            [ProtoMember(50)]
            public Inner50 Value50 { get; set; }
            [ProtoMember(51)]
            public Inner51 Value51 { get; set; }
            [ProtoMember(52)]
            public Inner52 Value52 { get; set; }
            [ProtoMember(53)]
            public Inner53 Value53 { get; set; }
            [ProtoMember(54)]
            public Inner54 Value54 { get; set; }
            [ProtoMember(55)]
            public Inner55 Value55 { get; set; }
            [ProtoMember(56)]
            public Inner56 Value56 { get; set; }
            [ProtoMember(57)]
            public Inner57 Value57 { get; set; }
            [ProtoMember(58)]
            public Inner58 Value58 { get; set; }
            [ProtoMember(59)]
            public Inner59 Value59 { get; set; }
            [ProtoMember(60)]
            public Inner60 Value60 { get; set; }
            [ProtoMember(61)]
            public Inner61 Value61 { get; set; }
            [ProtoMember(62)]
            public Inner62 Value62 { get; set; }
            [ProtoMember(63)]
            public Inner63 Value63 { get; set; }
            [ProtoMember(64)]
            public Inner64 Value64 { get; set; }
            [ProtoMember(65)]
            public Inner65 Value65 { get; set; }
            [ProtoMember(66)]
            public Inner66 Value66 { get; set; }
            [ProtoMember(67)]
            public Inner67 Value67 { get; set; }
            [ProtoMember(68)]
            public Inner68 Value68 { get; set; }
            [ProtoMember(69)]
            public Inner69 Value69 { get; set; }
            [ProtoMember(70)]
            public Inner70 Value70 { get; set; }
            [ProtoMember(71)]
            public Inner71 Value71 { get; set; }
            [ProtoMember(72)]
            public Inner72 Value72 { get; set; }
            [ProtoMember(73)]
            public Inner73 Value73 { get; set; }
            [ProtoMember(74)]
            public Inner74 Value74 { get; set; }
            [ProtoMember(75)]
            public Inner75 Value75 { get; set; }
            [ProtoMember(76)]
            public Inner76 Value76 { get; set; }
            [ProtoMember(77)]
            public Inner77 Value77 { get; set; }
            [ProtoMember(78)]
            public Inner78 Value78 { get; set; }
            [ProtoMember(79)]
            public Inner79 Value79 { get; set; }
            [ProtoMember(80)]
            public Inner80 Value80 { get; set; }
            [ProtoMember(81)]
            public Inner81 Value81 { get; set; }
            [ProtoMember(82)]
            public Inner82 Value82 { get; set; }
            [ProtoMember(83)]
            public Inner83 Value83 { get; set; }
            [ProtoMember(84)]
            public Inner84 Value84 { get; set; }
            [ProtoMember(85)]
            public Inner85 Value85 { get; set; }
            [ProtoMember(86)]
            public Inner86 Value86 { get; set; }
            [ProtoMember(87)]
            public Inner87 Value87 { get; set; }
            [ProtoMember(88)]
            public Inner88 Value88 { get; set; }
            [ProtoMember(89)]
            public Inner89 Value89 { get; set; }
            [ProtoMember(90)]
            public Inner90 Value90 { get; set; }
            [ProtoMember(91)]
            public Inner91 Value91 { get; set; }
            [ProtoMember(92)]
            public Inner92 Value92 { get; set; }
            [ProtoMember(93)]
            public Inner93 Value93 { get; set; }
            [ProtoMember(94)]
            public Inner94 Value94 { get; set; }
            [ProtoMember(95)]
            public Inner95 Value95 { get; set; }
            [ProtoMember(96)]
            public Inner96 Value96 { get; set; }
            [ProtoMember(97)]
            public Inner97 Value97 { get; set; }
            [ProtoMember(98)]
            public Inner98 Value98 { get; set; }
            [ProtoMember(99)]
            public Inner99 Value99 { get; set; }
            [ProtoMember(100)]
            public Inner100 Value100 { get; set; }
            [ProtoMember(101)]
            public Inner101 Value101 { get; set; }
            [ProtoMember(102)]
            public Inner102 Value102 { get; set; }
            [ProtoMember(103)]
            public Inner103 Value103 { get; set; }
            [ProtoMember(104)]
            public Inner104 Value104 { get; set; }
            [ProtoMember(105)]
            public Inner105 Value105 { get; set; }
            [ProtoMember(106)]
            public Inner106 Value106 { get; set; }
            [ProtoMember(107)]
            public Inner107 Value107 { get; set; }
            [ProtoMember(108)]
            public Inner108 Value108 { get; set; }
            [ProtoMember(109)]
            public Inner109 Value109 { get; set; }
            [ProtoMember(110)]
            public Inner110 Value110 { get; set; }
            [ProtoMember(111)]
            public Inner111 Value111 { get; set; }
            [ProtoMember(112)]
            public Inner112 Value112 { get; set; }
            [ProtoMember(113)]
            public Inner113 Value113 { get; set; }
            [ProtoMember(114)]
            public Inner114 Value114 { get; set; }
            [ProtoMember(115)]
            public Inner115 Value115 { get; set; }
            [ProtoMember(116)]
            public Inner116 Value116 { get; set; }
            [ProtoMember(117)]
            public Inner117 Value117 { get; set; }
            [ProtoMember(118)]
            public Inner118 Value118 { get; set; }
            [ProtoMember(119)]
            public Inner119 Value119 { get; set; }
            [ProtoMember(120)]
            public Inner120 Value120 { get; set; }
            [ProtoMember(121)]
            public Inner121 Value121 { get; set; }
            [ProtoMember(122)]
            public Inner122 Value122 { get; set; }
            [ProtoMember(123)]
            public Inner123 Value123 { get; set; }
            [ProtoMember(124)]
            public Inner124 Value124 { get; set; }
            [ProtoMember(125)]
            public Inner125 Value125 { get; set; }
            [ProtoMember(126)]
            public Inner126 Value126 { get; set; }
            [ProtoMember(127)]
            public Inner127 Value127 { get; set; }
            [ProtoMember(128)]
            public Inner128 Value128 { get; set; }
            [ProtoMember(129)]
            public Inner129 Value129 { get; set; }
            [ProtoMember(130)]
            public Inner130 Value130 { get; set; }
            [ProtoMember(131)]
            public Inner131 Value131 { get; set; }
            [ProtoMember(132)]
            public Inner132 Value132 { get; set; }
            [ProtoMember(133)]
            public Inner133 Value133 { get; set; }
            [ProtoMember(134)]
            public Inner134 Value134 { get; set; }
            [ProtoMember(135)]
            public Inner135 Value135 { get; set; }
            [ProtoMember(136)]
            public Inner136 Value136 { get; set; }
            [ProtoMember(137)]
            public Inner137 Value137 { get; set; }
            [ProtoMember(138)]
            public Inner138 Value138 { get; set; }
            [ProtoMember(139)]
            public Inner139 Value139 { get; set; }
            [ProtoMember(140)]
            public Inner140 Value140 { get; set; }
            [ProtoMember(141)]
            public Inner141 Value141 { get; set; }
            [ProtoMember(142)]
            public Inner142 Value142 { get; set; }
            [ProtoMember(143)]
            public Inner143 Value143 { get; set; }
            [ProtoMember(144)]
            public Inner144 Value144 { get; set; }
            [ProtoMember(145)]
            public Inner145 Value145 { get; set; }
            [ProtoMember(146)]
            public Inner146 Value146 { get; set; }
            [ProtoMember(147)]
            public Inner147 Value147 { get; set; }
            [ProtoMember(148)]
            public Inner148 Value148 { get; set; }
            [ProtoMember(149)]
            public Inner149 Value149 { get; set; }
            [ProtoMember(150)]
            public Inner150 Value150 { get; set; }
            [ProtoMember(151)]
            public Inner151 Value151 { get; set; }
            [ProtoMember(152)]
            public Inner152 Value152 { get; set; }
            [ProtoMember(153)]
            public Inner153 Value153 { get; set; }
            [ProtoMember(154)]
            public Inner154 Value154 { get; set; }
            [ProtoMember(155)]
            public Inner155 Value155 { get; set; }
            [ProtoMember(156)]
            public Inner156 Value156 { get; set; }
            [ProtoMember(157)]
            public Inner157 Value157 { get; set; }
            [ProtoMember(158)]
            public Inner158 Value158 { get; set; }
            [ProtoMember(159)]
            public Inner159 Value159 { get; set; }
            [ProtoMember(160)]
            public Inner160 Value160 { get; set; }
            [ProtoMember(161)]
            public Inner161 Value161 { get; set; }
            [ProtoMember(162)]
            public Inner162 Value162 { get; set; }
            [ProtoMember(163)]
            public Inner163 Value163 { get; set; }
            [ProtoMember(164)]
            public Inner164 Value164 { get; set; }
            [ProtoMember(165)]
            public Inner165 Value165 { get; set; }
            [ProtoMember(166)]
            public Inner166 Value166 { get; set; }
            [ProtoMember(167)]
            public Inner167 Value167 { get; set; }
            [ProtoMember(168)]
            public Inner168 Value168 { get; set; }
            [ProtoMember(169)]
            public Inner169 Value169 { get; set; }
            [ProtoMember(170)]
            public Inner170 Value170 { get; set; }
            [ProtoMember(171)]
            public Inner171 Value171 { get; set; }
            [ProtoMember(172)]
            public Inner172 Value172 { get; set; }
            [ProtoMember(173)]
            public Inner173 Value173 { get; set; }
            [ProtoMember(174)]
            public Inner174 Value174 { get; set; }
            [ProtoMember(175)]
            public Inner175 Value175 { get; set; }
            [ProtoMember(176)]
            public Inner176 Value176 { get; set; }
            [ProtoMember(177)]
            public Inner177 Value177 { get; set; }
            [ProtoMember(178)]
            public Inner178 Value178 { get; set; }
            [ProtoMember(179)]
            public Inner179 Value179 { get; set; }
            [ProtoMember(180)]
            public Inner180 Value180 { get; set; }
            [ProtoMember(181)]
            public Inner181 Value181 { get; set; }
            [ProtoMember(182)]
            public Inner182 Value182 { get; set; }
            [ProtoMember(183)]
            public Inner183 Value183 { get; set; }
            [ProtoMember(184)]
            public Inner184 Value184 { get; set; }
            [ProtoMember(185)]
            public Inner185 Value185 { get; set; }
            [ProtoMember(186)]
            public Inner186 Value186 { get; set; }
            [ProtoMember(187)]
            public Inner187 Value187 { get; set; }
            [ProtoMember(188)]
            public Inner188 Value188 { get; set; }
            [ProtoMember(189)]
            public Inner189 Value189 { get; set; }
            [ProtoMember(190)]
            public Inner190 Value190 { get; set; }
            [ProtoMember(191)]
            public Inner191 Value191 { get; set; }
            [ProtoMember(192)]
            public Inner192 Value192 { get; set; }
            [ProtoMember(193)]
            public Inner193 Value193 { get; set; }
            [ProtoMember(194)]
            public Inner194 Value194 { get; set; }
            [ProtoMember(195)]
            public Inner195 Value195 { get; set; }
            [ProtoMember(196)]
            public Inner196 Value196 { get; set; }
            [ProtoMember(197)]
            public Inner197 Value197 { get; set; }
            [ProtoMember(198)]
            public Inner198 Value198 { get; set; }
            [ProtoMember(199)]
            public Inner199 Value199 { get; set; }
            [ProtoMember(200)]
            public Inner200 Value200 { get; set; }
            [ProtoMember(201)]
            public Inner201 Value201 { get; set; }
            [ProtoMember(202)]
            public Inner202 Value202 { get; set; }
            [ProtoMember(203)]
            public Inner203 Value203 { get; set; }
            [ProtoMember(204)]
            public Inner204 Value204 { get; set; }
            [ProtoMember(205)]
            public Inner205 Value205 { get; set; }
            [ProtoMember(206)]
            public Inner206 Value206 { get; set; }
            [ProtoMember(207)]
            public Inner207 Value207 { get; set; }
            [ProtoMember(208)]
            public Inner208 Value208 { get; set; }
            [ProtoMember(209)]
            public Inner209 Value209 { get; set; }
            [ProtoMember(210)]
            public Inner210 Value210 { get; set; }
            [ProtoMember(211)]
            public Inner211 Value211 { get; set; }
            [ProtoMember(212)]
            public Inner212 Value212 { get; set; }
            [ProtoMember(213)]
            public Inner213 Value213 { get; set; }
            [ProtoMember(214)]
            public Inner214 Value214 { get; set; }
            [ProtoMember(215)]
            public Inner215 Value215 { get; set; }
            [ProtoMember(216)]
            public Inner216 Value216 { get; set; }
            [ProtoMember(217)]
            public Inner217 Value217 { get; set; }
            [ProtoMember(218)]
            public Inner218 Value218 { get; set; }
            [ProtoMember(219)]
            public Inner219 Value219 { get; set; }
            [ProtoMember(220)]
            public Inner220 Value220 { get; set; }
            [ProtoMember(221)]
            public Inner221 Value221 { get; set; }
            [ProtoMember(222)]
            public Inner222 Value222 { get; set; }
            [ProtoMember(223)]
            public Inner223 Value223 { get; set; }
            [ProtoMember(224)]
            public Inner224 Value224 { get; set; }
            [ProtoMember(225)]
            public Inner225 Value225 { get; set; }
            [ProtoMember(226)]
            public Inner226 Value226 { get; set; }
            [ProtoMember(227)]
            public Inner227 Value227 { get; set; }
            [ProtoMember(228)]
            public Inner228 Value228 { get; set; }
            [ProtoMember(229)]
            public Inner229 Value229 { get; set; }
            [ProtoMember(230)]
            public Inner230 Value230 { get; set; }
            [ProtoMember(231)]
            public Inner231 Value231 { get; set; }
            [ProtoMember(232)]
            public Inner232 Value232 { get; set; }
            [ProtoMember(233)]
            public Inner233 Value233 { get; set; }
            [ProtoMember(234)]
            public Inner234 Value234 { get; set; }
            [ProtoMember(235)]
            public Inner235 Value235 { get; set; }
            [ProtoMember(236)]
            public Inner236 Value236 { get; set; }
            [ProtoMember(237)]
            public Inner237 Value237 { get; set; }
            [ProtoMember(238)]
            public Inner238 Value238 { get; set; }
            [ProtoMember(239)]
            public Inner239 Value239 { get; set; }
            [ProtoMember(240)]
            public Inner240 Value240 { get; set; }
            [ProtoMember(241)]
            public Inner241 Value241 { get; set; }
            [ProtoMember(242)]
            public Inner242 Value242 { get; set; }
            [ProtoMember(243)]
            public Inner243 Value243 { get; set; }
            [ProtoMember(244)]
            public Inner244 Value244 { get; set; }
            [ProtoMember(245)]
            public Inner245 Value245 { get; set; }
            [ProtoMember(246)]
            public Inner246 Value246 { get; set; }
            [ProtoMember(247)]
            public Inner247 Value247 { get; set; }
            [ProtoMember(248)]
            public Inner248 Value248 { get; set; }
            [ProtoMember(249)]
            public Inner249 Value249 { get; set; }
            [ProtoMember(250)]
            public Inner250 Value250 { get; set; }
            [ProtoMember(251)]
            public Inner251 Value251 { get; set; }
            [ProtoMember(252)]
            public Inner252 Value252 { get; set; }
            [ProtoMember(253)]
            public Inner253 Value253 { get; set; }
            [ProtoMember(254)]
            public Inner254 Value254 { get; set; }
            [ProtoMember(255)]
            public Inner255 Value255 { get; set; }
            [ProtoMember(256)]
            public Inner256 Value256 { get; set; }
            [ProtoMember(257)]
            public Inner257 Value257 { get; set; }
            [ProtoMember(258)]
            public Inner258 Value258 { get; set; }
            [ProtoMember(259)]
            public Inner259 Value259 { get; set; }
            [ProtoMember(260)]
            public Inner260 Value260 { get; set; }
            [ProtoMember(261)]
            public Inner261 Value261 { get; set; }
            [ProtoMember(262)]
            public Inner262 Value262 { get; set; }
            [ProtoMember(263)]
            public Inner263 Value263 { get; set; }
            [ProtoMember(264)]
            public Inner264 Value264 { get; set; }
            [ProtoMember(265)]
            public Inner265 Value265 { get; set; }
            [ProtoMember(266)]
            public Inner266 Value266 { get; set; }
            [ProtoMember(267)]
            public Inner267 Value267 { get; set; }
            [ProtoMember(268)]
            public Inner268 Value268 { get; set; }
            [ProtoMember(269)]
            public Inner269 Value269 { get; set; }
            [ProtoMember(270)]
            public Inner270 Value270 { get; set; }
            [ProtoMember(271)]
            public Inner271 Value271 { get; set; }
            [ProtoMember(272)]
            public Inner272 Value272 { get; set; }
            [ProtoMember(273)]
            public Inner273 Value273 { get; set; }
            [ProtoMember(274)]
            public Inner274 Value274 { get; set; }
            [ProtoMember(275)]
            public Inner275 Value275 { get; set; }
            [ProtoMember(276)]
            public Inner276 Value276 { get; set; }
            [ProtoMember(277)]
            public Inner277 Value277 { get; set; }
            [ProtoMember(278)]
            public Inner278 Value278 { get; set; }
            [ProtoMember(279)]
            public Inner279 Value279 { get; set; }
            [ProtoMember(280)]
            public Inner280 Value280 { get; set; }
            [ProtoMember(281)]
            public Inner281 Value281 { get; set; }
            [ProtoMember(282)]
            public Inner282 Value282 { get; set; }
            [ProtoMember(283)]
            public Inner283 Value283 { get; set; }
            [ProtoMember(284)]
            public Inner284 Value284 { get; set; }
            [ProtoMember(285)]
            public Inner285 Value285 { get; set; }
            [ProtoMember(286)]
            public Inner286 Value286 { get; set; }
            [ProtoMember(287)]
            public Inner287 Value287 { get; set; }
            [ProtoMember(288)]
            public Inner288 Value288 { get; set; }
            [ProtoMember(289)]
            public Inner289 Value289 { get; set; }
            [ProtoMember(290)]
            public Inner290 Value290 { get; set; }
            [ProtoMember(291)]
            public Inner291 Value291 { get; set; }
            [ProtoMember(292)]
            public Inner292 Value292 { get; set; }
            [ProtoMember(293)]
            public Inner293 Value293 { get; set; }
            [ProtoMember(294)]
            public Inner294 Value294 { get; set; }
            [ProtoMember(295)]
            public Inner295 Value295 { get; set; }
            [ProtoMember(296)]
            public Inner296 Value296 { get; set; }
            [ProtoMember(297)]
            public Inner297 Value297 { get; set; }
            [ProtoMember(298)]
            public Inner298 Value298 { get; set; }
            [ProtoMember(299)]
            public Inner299 Value299 { get; set; }
            [ProtoMember(300)]
            public Inner300 Value300 { get; set; }
            [ProtoMember(301)]
            public Inner301 Value301 { get; set; }
            [ProtoMember(302)]
            public Inner302 Value302 { get; set; }
            [ProtoMember(303)]
            public Inner303 Value303 { get; set; }
            [ProtoMember(304)]
            public Inner304 Value304 { get; set; }
            [ProtoMember(305)]
            public Inner305 Value305 { get; set; }
            [ProtoMember(306)]
            public Inner306 Value306 { get; set; }
            [ProtoMember(307)]
            public Inner307 Value307 { get; set; }
            [ProtoMember(308)]
            public Inner308 Value308 { get; set; }
            [ProtoMember(309)]
            public Inner309 Value309 { get; set; }
            [ProtoMember(310)]
            public Inner310 Value310 { get; set; }
            [ProtoMember(311)]
            public Inner311 Value311 { get; set; }
            [ProtoMember(312)]
            public Inner312 Value312 { get; set; }
            [ProtoMember(313)]
            public Inner313 Value313 { get; set; }
            [ProtoMember(314)]
            public Inner314 Value314 { get; set; }
            [ProtoMember(315)]
            public Inner315 Value315 { get; set; }
            [ProtoMember(316)]
            public Inner316 Value316 { get; set; }
            [ProtoMember(317)]
            public Inner317 Value317 { get; set; }
            [ProtoMember(318)]
            public Inner318 Value318 { get; set; }
            [ProtoMember(319)]
            public Inner319 Value319 { get; set; }
            [ProtoMember(320)]
            public Inner320 Value320 { get; set; }
            [ProtoMember(321)]
            public Inner321 Value321 { get; set; }
            [ProtoMember(322)]
            public Inner322 Value322 { get; set; }
            [ProtoMember(323)]
            public Inner323 Value323 { get; set; }
            [ProtoMember(324)]
            public Inner324 Value324 { get; set; }
            [ProtoMember(325)]
            public Inner325 Value325 { get; set; }
            [ProtoMember(326)]
            public Inner326 Value326 { get; set; }
            [ProtoMember(327)]
            public Inner327 Value327 { get; set; }
            [ProtoMember(328)]
            public Inner328 Value328 { get; set; }
            [ProtoMember(329)]
            public Inner329 Value329 { get; set; }
            [ProtoMember(330)]
            public Inner330 Value330 { get; set; }
            [ProtoMember(331)]
            public Inner331 Value331 { get; set; }
            [ProtoMember(332)]
            public Inner332 Value332 { get; set; }
            [ProtoMember(333)]
            public Inner333 Value333 { get; set; }
            [ProtoMember(334)]
            public Inner334 Value334 { get; set; }
            [ProtoMember(335)]
            public Inner335 Value335 { get; set; }
            [ProtoMember(336)]
            public Inner336 Value336 { get; set; }
            [ProtoMember(337)]
            public Inner337 Value337 { get; set; }
            [ProtoMember(338)]
            public Inner338 Value338 { get; set; }
            [ProtoMember(339)]
            public Inner339 Value339 { get; set; }
            [ProtoMember(340)]
            public Inner340 Value340 { get; set; }
            [ProtoMember(341)]
            public Inner341 Value341 { get; set; }
            [ProtoMember(342)]
            public Inner342 Value342 { get; set; }
            [ProtoMember(343)]
            public Inner343 Value343 { get; set; }
            [ProtoMember(344)]
            public Inner344 Value344 { get; set; }
            [ProtoMember(345)]
            public Inner345 Value345 { get; set; }
            [ProtoMember(346)]
            public Inner346 Value346 { get; set; }
            [ProtoMember(347)]
            public Inner347 Value347 { get; set; }
            [ProtoMember(348)]
            public Inner348 Value348 { get; set; }
            [ProtoMember(349)]
            public Inner349 Value349 { get; set; }
            [ProtoMember(350)]
            public Inner350 Value350 { get; set; }
            [ProtoMember(351)]
            public Inner351 Value351 { get; set; }
            [ProtoMember(352)]
            public Inner352 Value352 { get; set; }
            [ProtoMember(353)]
            public Inner353 Value353 { get; set; }
            [ProtoMember(354)]
            public Inner354 Value354 { get; set; }
            [ProtoMember(355)]
            public Inner355 Value355 { get; set; }
            [ProtoMember(356)]
            public Inner356 Value356 { get; set; }
            [ProtoMember(357)]
            public Inner357 Value357 { get; set; }
            [ProtoMember(358)]
            public Inner358 Value358 { get; set; }
            [ProtoMember(359)]
            public Inner359 Value359 { get; set; }
            [ProtoMember(360)]
            public Inner360 Value360 { get; set; }
            [ProtoMember(361)]
            public Inner361 Value361 { get; set; }
            [ProtoMember(362)]
            public Inner362 Value362 { get; set; }
            [ProtoMember(363)]
            public Inner363 Value363 { get; set; }
            [ProtoMember(364)]
            public Inner364 Value364 { get; set; }
            [ProtoMember(365)]
            public Inner365 Value365 { get; set; }
            [ProtoMember(366)]
            public Inner366 Value366 { get; set; }
            [ProtoMember(367)]
            public Inner367 Value367 { get; set; }
            [ProtoMember(368)]
            public Inner368 Value368 { get; set; }
            [ProtoMember(369)]
            public Inner369 Value369 { get; set; }
            [ProtoMember(370)]
            public Inner370 Value370 { get; set; }
            [ProtoMember(371)]
            public Inner371 Value371 { get; set; }
            [ProtoMember(372)]
            public Inner372 Value372 { get; set; }
            [ProtoMember(373)]
            public Inner373 Value373 { get; set; }
            [ProtoMember(374)]
            public Inner374 Value374 { get; set; }
            [ProtoMember(375)]
            public Inner375 Value375 { get; set; }
            [ProtoMember(376)]
            public Inner376 Value376 { get; set; }
            [ProtoMember(377)]
            public Inner377 Value377 { get; set; }
            [ProtoMember(378)]
            public Inner378 Value378 { get; set; }
            [ProtoMember(379)]
            public Inner379 Value379 { get; set; }
            [ProtoMember(380)]
            public Inner380 Value380 { get; set; }
            [ProtoMember(381)]
            public Inner381 Value381 { get; set; }
            [ProtoMember(382)]
            public Inner382 Value382 { get; set; }
            [ProtoMember(383)]
            public Inner383 Value383 { get; set; }
            [ProtoMember(384)]
            public Inner384 Value384 { get; set; }
            [ProtoMember(385)]
            public Inner385 Value385 { get; set; }
            [ProtoMember(386)]
            public Inner386 Value386 { get; set; }
            [ProtoMember(387)]
            public Inner387 Value387 { get; set; }
            [ProtoMember(388)]
            public Inner388 Value388 { get; set; }
            [ProtoMember(389)]
            public Inner389 Value389 { get; set; }
            [ProtoMember(390)]
            public Inner390 Value390 { get; set; }
            [ProtoMember(391)]
            public Inner391 Value391 { get; set; }
            [ProtoMember(392)]
            public Inner392 Value392 { get; set; }
            [ProtoMember(393)]
            public Inner393 Value393 { get; set; }
            [ProtoMember(394)]
            public Inner394 Value394 { get; set; }
            [ProtoMember(395)]
            public Inner395 Value395 { get; set; }
            [ProtoMember(396)]
            public Inner396 Value396 { get; set; }
            [ProtoMember(397)]
            public Inner397 Value397 { get; set; }
            [ProtoMember(398)]
            public Inner398 Value398 { get; set; }
            [ProtoMember(399)]
            public Inner399 Value399 { get; set; }
            [ProtoMember(400)]
            public Inner400 Value400 { get; set; }
            [ProtoMember(401)]
            public Inner401 Value401 { get; set; }
            [ProtoMember(402)]
            public Inner402 Value402 { get; set; }
            [ProtoMember(403)]
            public Inner403 Value403 { get; set; }
            [ProtoMember(404)]
            public Inner404 Value404 { get; set; }
            [ProtoMember(405)]
            public Inner405 Value405 { get; set; }
            [ProtoMember(406)]
            public Inner406 Value406 { get; set; }
            [ProtoMember(407)]
            public Inner407 Value407 { get; set; }
            [ProtoMember(408)]
            public Inner408 Value408 { get; set; }
            [ProtoMember(409)]
            public Inner409 Value409 { get; set; }
            [ProtoMember(410)]
            public Inner410 Value410 { get; set; }
            [ProtoMember(411)]
            public Inner411 Value411 { get; set; }
            [ProtoMember(412)]
            public Inner412 Value412 { get; set; }
            [ProtoMember(413)]
            public Inner413 Value413 { get; set; }
            [ProtoMember(414)]
            public Inner414 Value414 { get; set; }
            [ProtoMember(415)]
            public Inner415 Value415 { get; set; }
            [ProtoMember(416)]
            public Inner416 Value416 { get; set; }
            [ProtoMember(417)]
            public Inner417 Value417 { get; set; }
            [ProtoMember(418)]
            public Inner418 Value418 { get; set; }
            [ProtoMember(419)]
            public Inner419 Value419 { get; set; }
            [ProtoMember(420)]
            public Inner420 Value420 { get; set; }
            [ProtoMember(421)]
            public Inner421 Value421 { get; set; }
            [ProtoMember(422)]
            public Inner422 Value422 { get; set; }
            [ProtoMember(423)]
            public Inner423 Value423 { get; set; }
            [ProtoMember(424)]
            public Inner424 Value424 { get; set; }
            [ProtoMember(425)]
            public Inner425 Value425 { get; set; }
            [ProtoMember(426)]
            public Inner426 Value426 { get; set; }
            [ProtoMember(427)]
            public Inner427 Value427 { get; set; }
            [ProtoMember(428)]
            public Inner428 Value428 { get; set; }
            [ProtoMember(429)]
            public Inner429 Value429 { get; set; }
            [ProtoMember(430)]
            public Inner430 Value430 { get; set; }
            [ProtoMember(431)]
            public Inner431 Value431 { get; set; }
            [ProtoMember(432)]
            public Inner432 Value432 { get; set; }
            [ProtoMember(433)]
            public Inner433 Value433 { get; set; }
            [ProtoMember(434)]
            public Inner434 Value434 { get; set; }
            [ProtoMember(435)]
            public Inner435 Value435 { get; set; }
            [ProtoMember(436)]
            public Inner436 Value436 { get; set; }
            [ProtoMember(437)]
            public Inner437 Value437 { get; set; }
            [ProtoMember(438)]
            public Inner438 Value438 { get; set; }
            [ProtoMember(439)]
            public Inner439 Value439 { get; set; }
            [ProtoMember(440)]
            public Inner440 Value440 { get; set; }
            [ProtoMember(441)]
            public Inner441 Value441 { get; set; }
            [ProtoMember(442)]
            public Inner442 Value442 { get; set; }
            [ProtoMember(443)]
            public Inner443 Value443 { get; set; }
            [ProtoMember(444)]
            public Inner444 Value444 { get; set; }
            [ProtoMember(445)]
            public Inner445 Value445 { get; set; }
            [ProtoMember(446)]
            public Inner446 Value446 { get; set; }
            [ProtoMember(447)]
            public Inner447 Value447 { get; set; }
            [ProtoMember(448)]
            public Inner448 Value448 { get; set; }
            [ProtoMember(449)]
            public Inner449 Value449 { get; set; }
            [ProtoMember(450)]
            public Inner450 Value450 { get; set; }
            [ProtoMember(451)]
            public Inner451 Value451 { get; set; }
            [ProtoMember(452)]
            public Inner452 Value452 { get; set; }
            [ProtoMember(453)]
            public Inner453 Value453 { get; set; }
            [ProtoMember(454)]
            public Inner454 Value454 { get; set; }
            [ProtoMember(455)]
            public Inner455 Value455 { get; set; }
            [ProtoMember(456)]
            public Inner456 Value456 { get; set; }
            [ProtoMember(457)]
            public Inner457 Value457 { get; set; }
            [ProtoMember(458)]
            public Inner458 Value458 { get; set; }
            [ProtoMember(459)]
            public Inner459 Value459 { get; set; }
            [ProtoMember(460)]
            public Inner460 Value460 { get; set; }
            [ProtoMember(461)]
            public Inner461 Value461 { get; set; }
            [ProtoMember(462)]
            public Inner462 Value462 { get; set; }
            [ProtoMember(463)]
            public Inner463 Value463 { get; set; }
            [ProtoMember(464)]
            public Inner464 Value464 { get; set; }
            [ProtoMember(465)]
            public Inner465 Value465 { get; set; }
            [ProtoMember(466)]
            public Inner466 Value466 { get; set; }
            [ProtoMember(467)]
            public Inner467 Value467 { get; set; }
            [ProtoMember(468)]
            public Inner468 Value468 { get; set; }
            [ProtoMember(469)]
            public Inner469 Value469 { get; set; }
            [ProtoMember(470)]
            public Inner470 Value470 { get; set; }
            [ProtoMember(471)]
            public Inner471 Value471 { get; set; }
            [ProtoMember(472)]
            public Inner472 Value472 { get; set; }
            [ProtoMember(473)]
            public Inner473 Value473 { get; set; }
            [ProtoMember(474)]
            public Inner474 Value474 { get; set; }
            [ProtoMember(475)]
            public Inner475 Value475 { get; set; }
            [ProtoMember(476)]
            public Inner476 Value476 { get; set; }
            [ProtoMember(477)]
            public Inner477 Value477 { get; set; }
            [ProtoMember(478)]
            public Inner478 Value478 { get; set; }
            [ProtoMember(479)]
            public Inner479 Value479 { get; set; }
            [ProtoMember(480)]
            public Inner480 Value480 { get; set; }
            [ProtoMember(481)]
            public Inner481 Value481 { get; set; }
            [ProtoMember(482)]
            public Inner482 Value482 { get; set; }
            [ProtoMember(483)]
            public Inner483 Value483 { get; set; }
            [ProtoMember(484)]
            public Inner484 Value484 { get; set; }
            [ProtoMember(485)]
            public Inner485 Value485 { get; set; }
            [ProtoMember(486)]
            public Inner486 Value486 { get; set; }
            [ProtoMember(487)]
            public Inner487 Value487 { get; set; }
            [ProtoMember(488)]
            public Inner488 Value488 { get; set; }
            [ProtoMember(489)]
            public Inner489 Value489 { get; set; }
            [ProtoMember(490)]
            public Inner490 Value490 { get; set; }
            [ProtoMember(491)]
            public Inner491 Value491 { get; set; }
            [ProtoMember(492)]
            public Inner492 Value492 { get; set; }
            [ProtoMember(493)]
            public Inner493 Value493 { get; set; }
            [ProtoMember(494)]
            public Inner494 Value494 { get; set; }
            [ProtoMember(495)]
            public Inner495 Value495 { get; set; }
            [ProtoMember(496)]
            public Inner496 Value496 { get; set; }
            [ProtoMember(497)]
            public Inner497 Value497 { get; set; }
            [ProtoMember(498)]
            public Inner498 Value498 { get; set; }
            [ProtoMember(499)]
            public Inner499 Value499 { get; set; }
            [ProtoMember(500)]
            public Inner500 Value500 { get; set; }
            [ProtoMember(501)]
            public Inner501 Value501 { get; set; }
            [ProtoMember(502)]
            public Inner502 Value502 { get; set; }
            [ProtoMember(503)]
            public Inner503 Value503 { get; set; }
            [ProtoMember(504)]
            public Inner504 Value504 { get; set; }
            [ProtoMember(505)]
            public Inner505 Value505 { get; set; }
            [ProtoMember(506)]
            public Inner506 Value506 { get; set; }
            [ProtoMember(507)]
            public Inner507 Value507 { get; set; }
            [ProtoMember(508)]
            public Inner508 Value508 { get; set; }
            [ProtoMember(509)]
            public Inner509 Value509 { get; set; }
            [ProtoMember(510)]
            public Inner510 Value510 { get; set; }
            [ProtoMember(511)]
            public Inner511 Value511 { get; set; }
            [ProtoMember(512)]
            public Inner512 Value512 { get; set; }
            [ProtoMember(513)]
            public Inner513 Value513 { get; set; }
            [ProtoMember(514)]
            public Inner514 Value514 { get; set; }
            [ProtoMember(515)]
            public Inner515 Value515 { get; set; }
            [ProtoMember(516)]
            public Inner516 Value516 { get; set; }
            [ProtoMember(517)]
            public Inner517 Value517 { get; set; }
            [ProtoMember(518)]
            public Inner518 Value518 { get; set; }
            [ProtoMember(519)]
            public Inner519 Value519 { get; set; }
            [ProtoMember(520)]
            public Inner520 Value520 { get; set; }
            [ProtoMember(521)]
            public Inner521 Value521 { get; set; }
            [ProtoMember(522)]
            public Inner522 Value522 { get; set; }
            [ProtoMember(523)]
            public Inner523 Value523 { get; set; }
            [ProtoMember(524)]
            public Inner524 Value524 { get; set; }
            [ProtoMember(525)]
            public Inner525 Value525 { get; set; }
            [ProtoMember(526)]
            public Inner526 Value526 { get; set; }
            [ProtoMember(527)]
            public Inner527 Value527 { get; set; }
            [ProtoMember(528)]
            public Inner528 Value528 { get; set; }
            [ProtoMember(529)]
            public Inner529 Value529 { get; set; }
            [ProtoMember(530)]
            public Inner530 Value530 { get; set; }
            [ProtoMember(531)]
            public Inner531 Value531 { get; set; }
            [ProtoMember(532)]
            public Inner532 Value532 { get; set; }
            [ProtoMember(533)]
            public Inner533 Value533 { get; set; }
            [ProtoMember(534)]
            public Inner534 Value534 { get; set; }
            [ProtoMember(535)]
            public Inner535 Value535 { get; set; }
            [ProtoMember(536)]
            public Inner536 Value536 { get; set; }
            [ProtoMember(537)]
            public Inner537 Value537 { get; set; }
            [ProtoMember(538)]
            public Inner538 Value538 { get; set; }
            [ProtoMember(539)]
            public Inner539 Value539 { get; set; }
            [ProtoMember(540)]
            public Inner540 Value540 { get; set; }
            [ProtoMember(541)]
            public Inner541 Value541 { get; set; }
            [ProtoMember(542)]
            public Inner542 Value542 { get; set; }
            [ProtoMember(543)]
            public Inner543 Value543 { get; set; }
            [ProtoMember(544)]
            public Inner544 Value544 { get; set; }
            [ProtoMember(545)]
            public Inner545 Value545 { get; set; }
            [ProtoMember(546)]
            public Inner546 Value546 { get; set; }
            [ProtoMember(547)]
            public Inner547 Value547 { get; set; }
            [ProtoMember(548)]
            public Inner548 Value548 { get; set; }
            [ProtoMember(549)]
            public Inner549 Value549 { get; set; }
            [ProtoMember(550)]
            public Inner550 Value550 { get; set; }
            [ProtoMember(551)]
            public Inner551 Value551 { get; set; }
            [ProtoMember(552)]
            public Inner552 Value552 { get; set; }
            [ProtoMember(553)]
            public Inner553 Value553 { get; set; }
            [ProtoMember(554)]
            public Inner554 Value554 { get; set; }
            [ProtoMember(555)]
            public Inner555 Value555 { get; set; }
            [ProtoMember(556)]
            public Inner556 Value556 { get; set; }
            [ProtoMember(557)]
            public Inner557 Value557 { get; set; }
            [ProtoMember(558)]
            public Inner558 Value558 { get; set; }
            [ProtoMember(559)]
            public Inner559 Value559 { get; set; }
            [ProtoMember(560)]
            public Inner560 Value560 { get; set; }
            [ProtoMember(561)]
            public Inner561 Value561 { get; set; }
            [ProtoMember(562)]
            public Inner562 Value562 { get; set; }
            [ProtoMember(563)]
            public Inner563 Value563 { get; set; }
            [ProtoMember(564)]
            public Inner564 Value564 { get; set; }
            [ProtoMember(565)]
            public Inner565 Value565 { get; set; }
            [ProtoMember(566)]
            public Inner566 Value566 { get; set; }
            [ProtoMember(567)]
            public Inner567 Value567 { get; set; }
            [ProtoMember(568)]
            public Inner568 Value568 { get; set; }
            [ProtoMember(569)]
            public Inner569 Value569 { get; set; }
            [ProtoMember(570)]
            public Inner570 Value570 { get; set; }
            [ProtoMember(571)]
            public Inner571 Value571 { get; set; }
            [ProtoMember(572)]
            public Inner572 Value572 { get; set; }
            [ProtoMember(573)]
            public Inner573 Value573 { get; set; }
            [ProtoMember(574)]
            public Inner574 Value574 { get; set; }
            [ProtoMember(575)]
            public Inner575 Value575 { get; set; }
            [ProtoMember(576)]
            public Inner576 Value576 { get; set; }
            [ProtoMember(577)]
            public Inner577 Value577 { get; set; }
            [ProtoMember(578)]
            public Inner578 Value578 { get; set; }
            [ProtoMember(579)]
            public Inner579 Value579 { get; set; }
            [ProtoMember(580)]
            public Inner580 Value580 { get; set; }
            [ProtoMember(581)]
            public Inner581 Value581 { get; set; }
            [ProtoMember(582)]
            public Inner582 Value582 { get; set; }
            [ProtoMember(583)]
            public Inner583 Value583 { get; set; }
            [ProtoMember(584)]
            public Inner584 Value584 { get; set; }
            [ProtoMember(585)]
            public Inner585 Value585 { get; set; }
            [ProtoMember(586)]
            public Inner586 Value586 { get; set; }
            [ProtoMember(587)]
            public Inner587 Value587 { get; set; }
            [ProtoMember(588)]
            public Inner588 Value588 { get; set; }
            [ProtoMember(589)]
            public Inner589 Value589 { get; set; }
            [ProtoMember(590)]
            public Inner590 Value590 { get; set; }
            [ProtoMember(591)]
            public Inner591 Value591 { get; set; }
            [ProtoMember(592)]
            public Inner592 Value592 { get; set; }
            [ProtoMember(593)]
            public Inner593 Value593 { get; set; }
            [ProtoMember(594)]
            public Inner594 Value594 { get; set; }
            [ProtoMember(595)]
            public Inner595 Value595 { get; set; }
            [ProtoMember(596)]
            public Inner596 Value596 { get; set; }
            [ProtoMember(597)]
            public Inner597 Value597 { get; set; }
            [ProtoMember(598)]
            public Inner598 Value598 { get; set; }
            [ProtoMember(599)]
            public Inner599 Value599 { get; set; }
            [ProtoMember(600)]
            public Inner600 Value600 { get; set; }
            [ProtoMember(601)]
            public Inner601 Value601 { get; set; }
            [ProtoMember(602)]
            public Inner602 Value602 { get; set; }
            [ProtoMember(603)]
            public Inner603 Value603 { get; set; }
            [ProtoMember(604)]
            public Inner604 Value604 { get; set; }
            [ProtoMember(605)]
            public Inner605 Value605 { get; set; }
            [ProtoMember(606)]
            public Inner606 Value606 { get; set; }
            [ProtoMember(607)]
            public Inner607 Value607 { get; set; }
            [ProtoMember(608)]
            public Inner608 Value608 { get; set; }
            [ProtoMember(609)]
            public Inner609 Value609 { get; set; }
            [ProtoMember(610)]
            public Inner610 Value610 { get; set; }
            [ProtoMember(611)]
            public Inner611 Value611 { get; set; }
            [ProtoMember(612)]
            public Inner612 Value612 { get; set; }
            [ProtoMember(613)]
            public Inner613 Value613 { get; set; }
            [ProtoMember(614)]
            public Inner614 Value614 { get; set; }
            [ProtoMember(615)]
            public Inner615 Value615 { get; set; }
            [ProtoMember(616)]
            public Inner616 Value616 { get; set; }
            [ProtoMember(617)]
            public Inner617 Value617 { get; set; }
            [ProtoMember(618)]
            public Inner618 Value618 { get; set; }
            [ProtoMember(619)]
            public Inner619 Value619 { get; set; }
            [ProtoMember(620)]
            public Inner620 Value620 { get; set; }
            [ProtoMember(621)]
            public Inner621 Value621 { get; set; }
            [ProtoMember(622)]
            public Inner622 Value622 { get; set; }
            [ProtoMember(623)]
            public Inner623 Value623 { get; set; }
            [ProtoMember(624)]
            public Inner624 Value624 { get; set; }
            [ProtoMember(625)]
            public Inner625 Value625 { get; set; }
            [ProtoMember(626)]
            public Inner626 Value626 { get; set; }
            [ProtoMember(627)]
            public Inner627 Value627 { get; set; }
            [ProtoMember(628)]
            public Inner628 Value628 { get; set; }
            [ProtoMember(629)]
            public Inner629 Value629 { get; set; }
            [ProtoMember(630)]
            public Inner630 Value630 { get; set; }
            [ProtoMember(631)]
            public Inner631 Value631 { get; set; }
            [ProtoMember(632)]
            public Inner632 Value632 { get; set; }
            [ProtoMember(633)]
            public Inner633 Value633 { get; set; }
            [ProtoMember(634)]
            public Inner634 Value634 { get; set; }
            [ProtoMember(635)]
            public Inner635 Value635 { get; set; }
            [ProtoMember(636)]
            public Inner636 Value636 { get; set; }
            [ProtoMember(637)]
            public Inner637 Value637 { get; set; }
            [ProtoMember(638)]
            public Inner638 Value638 { get; set; }
            [ProtoMember(639)]
            public Inner639 Value639 { get; set; }
            [ProtoMember(640)]
            public Inner640 Value640 { get; set; }
            [ProtoMember(641)]
            public Inner641 Value641 { get; set; }
            [ProtoMember(642)]
            public Inner642 Value642 { get; set; }
            [ProtoMember(643)]
            public Inner643 Value643 { get; set; }
            [ProtoMember(644)]
            public Inner644 Value644 { get; set; }
            [ProtoMember(645)]
            public Inner645 Value645 { get; set; }
            [ProtoMember(646)]
            public Inner646 Value646 { get; set; }
            [ProtoMember(647)]
            public Inner647 Value647 { get; set; }
            [ProtoMember(648)]
            public Inner648 Value648 { get; set; }
            [ProtoMember(649)]
            public Inner649 Value649 { get; set; }
            [ProtoMember(650)]
            public Inner650 Value650 { get; set; }
            [ProtoMember(651)]
            public Inner651 Value651 { get; set; }
            [ProtoMember(652)]
            public Inner652 Value652 { get; set; }
            [ProtoMember(653)]
            public Inner653 Value653 { get; set; }
            [ProtoMember(654)]
            public Inner654 Value654 { get; set; }
            [ProtoMember(655)]
            public Inner655 Value655 { get; set; }
            [ProtoMember(656)]
            public Inner656 Value656 { get; set; }
            [ProtoMember(657)]
            public Inner657 Value657 { get; set; }
            [ProtoMember(658)]
            public Inner658 Value658 { get; set; }
            [ProtoMember(659)]
            public Inner659 Value659 { get; set; }
            [ProtoMember(660)]
            public Inner660 Value660 { get; set; }
            [ProtoMember(661)]
            public Inner661 Value661 { get; set; }
            [ProtoMember(662)]
            public Inner662 Value662 { get; set; }
            [ProtoMember(663)]
            public Inner663 Value663 { get; set; }
            [ProtoMember(664)]
            public Inner664 Value664 { get; set; }
            [ProtoMember(665)]
            public Inner665 Value665 { get; set; }
            [ProtoMember(666)]
            public Inner666 Value666 { get; set; }
            [ProtoMember(667)]
            public Inner667 Value667 { get; set; }
            [ProtoMember(668)]
            public Inner668 Value668 { get; set; }
            [ProtoMember(669)]
            public Inner669 Value669 { get; set; }
            [ProtoMember(670)]
            public Inner670 Value670 { get; set; }
            [ProtoMember(671)]
            public Inner671 Value671 { get; set; }
            [ProtoMember(672)]
            public Inner672 Value672 { get; set; }
            [ProtoMember(673)]
            public Inner673 Value673 { get; set; }
            [ProtoMember(674)]
            public Inner674 Value674 { get; set; }
            [ProtoMember(675)]
            public Inner675 Value675 { get; set; }
            [ProtoMember(676)]
            public Inner676 Value676 { get; set; }
            [ProtoMember(677)]
            public Inner677 Value677 { get; set; }
            [ProtoMember(678)]
            public Inner678 Value678 { get; set; }
            [ProtoMember(679)]
            public Inner679 Value679 { get; set; }
            [ProtoMember(680)]
            public Inner680 Value680 { get; set; }
            [ProtoMember(681)]
            public Inner681 Value681 { get; set; }
            [ProtoMember(682)]
            public Inner682 Value682 { get; set; }
            [ProtoMember(683)]
            public Inner683 Value683 { get; set; }
            [ProtoMember(684)]
            public Inner684 Value684 { get; set; }
            [ProtoMember(685)]
            public Inner685 Value685 { get; set; }
            [ProtoMember(686)]
            public Inner686 Value686 { get; set; }
            [ProtoMember(687)]
            public Inner687 Value687 { get; set; }
            [ProtoMember(688)]
            public Inner688 Value688 { get; set; }
            [ProtoMember(689)]
            public Inner689 Value689 { get; set; }
            [ProtoMember(690)]
            public Inner690 Value690 { get; set; }
            [ProtoMember(691)]
            public Inner691 Value691 { get; set; }
            [ProtoMember(692)]
            public Inner692 Value692 { get; set; }
            [ProtoMember(693)]
            public Inner693 Value693 { get; set; }
            [ProtoMember(694)]
            public Inner694 Value694 { get; set; }
            [ProtoMember(695)]
            public Inner695 Value695 { get; set; }
            [ProtoMember(696)]
            public Inner696 Value696 { get; set; }
            [ProtoMember(697)]
            public Inner697 Value697 { get; set; }
            [ProtoMember(698)]
            public Inner698 Value698 { get; set; }
            [ProtoMember(699)]
            public Inner699 Value699 { get; set; }
            [ProtoMember(700)]
            public Inner700 Value700 { get; set; }
            [ProtoMember(701)]
            public Inner701 Value701 { get; set; }
            [ProtoMember(702)]
            public Inner702 Value702 { get; set; }
            [ProtoMember(703)]
            public Inner703 Value703 { get; set; }
            [ProtoMember(704)]
            public Inner704 Value704 { get; set; }
            [ProtoMember(705)]
            public Inner705 Value705 { get; set; }
            [ProtoMember(706)]
            public Inner706 Value706 { get; set; }
            [ProtoMember(707)]
            public Inner707 Value707 { get; set; }
            [ProtoMember(708)]
            public Inner708 Value708 { get; set; }
            [ProtoMember(709)]
            public Inner709 Value709 { get; set; }
            [ProtoMember(710)]
            public Inner710 Value710 { get; set; }
            [ProtoMember(711)]
            public Inner711 Value711 { get; set; }
            [ProtoMember(712)]
            public Inner712 Value712 { get; set; }
            [ProtoMember(713)]
            public Inner713 Value713 { get; set; }
            [ProtoMember(714)]
            public Inner714 Value714 { get; set; }
            [ProtoMember(715)]
            public Inner715 Value715 { get; set; }
            [ProtoMember(716)]
            public Inner716 Value716 { get; set; }
            [ProtoMember(717)]
            public Inner717 Value717 { get; set; }
            [ProtoMember(718)]
            public Inner718 Value718 { get; set; }
            [ProtoMember(719)]
            public Inner719 Value719 { get; set; }
            [ProtoMember(720)]
            public Inner720 Value720 { get; set; }
            [ProtoMember(721)]
            public Inner721 Value721 { get; set; }
            [ProtoMember(722)]
            public Inner722 Value722 { get; set; }
            [ProtoMember(723)]
            public Inner723 Value723 { get; set; }
            [ProtoMember(724)]
            public Inner724 Value724 { get; set; }
            [ProtoMember(725)]
            public Inner725 Value725 { get; set; }
            [ProtoMember(726)]
            public Inner726 Value726 { get; set; }
            [ProtoMember(727)]
            public Inner727 Value727 { get; set; }
            [ProtoMember(728)]
            public Inner728 Value728 { get; set; }
            [ProtoMember(729)]
            public Inner729 Value729 { get; set; }
            [ProtoMember(730)]
            public Inner730 Value730 { get; set; }
            [ProtoMember(731)]
            public Inner731 Value731 { get; set; }
            [ProtoMember(732)]
            public Inner732 Value732 { get; set; }
            [ProtoMember(733)]
            public Inner733 Value733 { get; set; }
            [ProtoMember(734)]
            public Inner734 Value734 { get; set; }
            [ProtoMember(735)]
            public Inner735 Value735 { get; set; }
            [ProtoMember(736)]
            public Inner736 Value736 { get; set; }
            [ProtoMember(737)]
            public Inner737 Value737 { get; set; }
            [ProtoMember(738)]
            public Inner738 Value738 { get; set; }
            [ProtoMember(739)]
            public Inner739 Value739 { get; set; }
            [ProtoMember(740)]
            public Inner740 Value740 { get; set; }
            [ProtoMember(741)]
            public Inner741 Value741 { get; set; }
            [ProtoMember(742)]
            public Inner742 Value742 { get; set; }
            [ProtoMember(743)]
            public Inner743 Value743 { get; set; }
            [ProtoMember(744)]
            public Inner744 Value744 { get; set; }
            [ProtoMember(745)]
            public Inner745 Value745 { get; set; }
            [ProtoMember(746)]
            public Inner746 Value746 { get; set; }
            [ProtoMember(747)]
            public Inner747 Value747 { get; set; }
            [ProtoMember(748)]
            public Inner748 Value748 { get; set; }
            [ProtoMember(749)]
            public Inner749 Value749 { get; set; }
            [ProtoMember(750)]
            public Inner750 Value750 { get; set; }
            [ProtoMember(751)]
            public Inner751 Value751 { get; set; }
            [ProtoMember(752)]
            public Inner752 Value752 { get; set; }
            [ProtoMember(753)]
            public Inner753 Value753 { get; set; }
            [ProtoMember(754)]
            public Inner754 Value754 { get; set; }
            [ProtoMember(755)]
            public Inner755 Value755 { get; set; }
            [ProtoMember(756)]
            public Inner756 Value756 { get; set; }
            [ProtoMember(757)]
            public Inner757 Value757 { get; set; }
            [ProtoMember(758)]
            public Inner758 Value758 { get; set; }
            [ProtoMember(759)]
            public Inner759 Value759 { get; set; }
            [ProtoMember(760)]
            public Inner760 Value760 { get; set; }
            [ProtoMember(761)]
            public Inner761 Value761 { get; set; }
            [ProtoMember(762)]
            public Inner762 Value762 { get; set; }
            [ProtoMember(763)]
            public Inner763 Value763 { get; set; }
            [ProtoMember(764)]
            public Inner764 Value764 { get; set; }
            [ProtoMember(765)]
            public Inner765 Value765 { get; set; }
            [ProtoMember(766)]
            public Inner766 Value766 { get; set; }
            [ProtoMember(767)]
            public Inner767 Value767 { get; set; }
            [ProtoMember(768)]
            public Inner768 Value768 { get; set; }
            [ProtoMember(769)]
            public Inner769 Value769 { get; set; }
            [ProtoMember(770)]
            public Inner770 Value770 { get; set; }
            [ProtoMember(771)]
            public Inner771 Value771 { get; set; }
            [ProtoMember(772)]
            public Inner772 Value772 { get; set; }
            [ProtoMember(773)]
            public Inner773 Value773 { get; set; }
            [ProtoMember(774)]
            public Inner774 Value774 { get; set; }
            [ProtoMember(775)]
            public Inner775 Value775 { get; set; }
            [ProtoMember(776)]
            public Inner776 Value776 { get; set; }
            [ProtoMember(777)]
            public Inner777 Value777 { get; set; }
            [ProtoMember(778)]
            public Inner778 Value778 { get; set; }
            [ProtoMember(779)]
            public Inner779 Value779 { get; set; }
            [ProtoMember(780)]
            public Inner780 Value780 { get; set; }
            [ProtoMember(781)]
            public Inner781 Value781 { get; set; }
            [ProtoMember(782)]
            public Inner782 Value782 { get; set; }
            [ProtoMember(783)]
            public Inner783 Value783 { get; set; }
            [ProtoMember(784)]
            public Inner784 Value784 { get; set; }
            [ProtoMember(785)]
            public Inner785 Value785 { get; set; }
            [ProtoMember(786)]
            public Inner786 Value786 { get; set; }
            [ProtoMember(787)]
            public Inner787 Value787 { get; set; }
            [ProtoMember(788)]
            public Inner788 Value788 { get; set; }
            [ProtoMember(789)]
            public Inner789 Value789 { get; set; }
            [ProtoMember(790)]
            public Inner790 Value790 { get; set; }
            [ProtoMember(791)]
            public Inner791 Value791 { get; set; }
            [ProtoMember(792)]
            public Inner792 Value792 { get; set; }
            [ProtoMember(793)]
            public Inner793 Value793 { get; set; }
            [ProtoMember(794)]
            public Inner794 Value794 { get; set; }
            [ProtoMember(795)]
            public Inner795 Value795 { get; set; }
            [ProtoMember(796)]
            public Inner796 Value796 { get; set; }
            [ProtoMember(797)]
            public Inner797 Value797 { get; set; }
            [ProtoMember(798)]
            public Inner798 Value798 { get; set; }
            [ProtoMember(799)]
            public Inner799 Value799 { get; set; }
            [ProtoMember(800)]
            public Inner800 Value800 { get; set; }
        }
        [ProtoContract]
        public class Inner1 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner2 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner3 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner4 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner5 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner6 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner7 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner8 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner9 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner10 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner11 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner12 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner13 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner14 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner15 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner16 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner17 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner18 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner19 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner20 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner21 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner22 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner23 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner24 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner25 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner26 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner27 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner28 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner29 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner30 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner31 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner32 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner33 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner34 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner35 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner36 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner37 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner38 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner39 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner40 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner41 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner42 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner43 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner44 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner45 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner46 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner47 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner48 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner49 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner50 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner51 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner52 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner53 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner54 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner55 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner56 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner57 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner58 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner59 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner60 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner61 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner62 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner63 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner64 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner65 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner66 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner67 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner68 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner69 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner70 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner71 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner72 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner73 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner74 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner75 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner76 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner77 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner78 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner79 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner80 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner81 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner82 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner83 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner84 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner85 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner86 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner87 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner88 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner89 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner90 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner91 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner92 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner93 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner94 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner95 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner96 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner97 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner98 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner99 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner100 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner101 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner102 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner103 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner104 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner105 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner106 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner107 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner108 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner109 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner110 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner111 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner112 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner113 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner114 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner115 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner116 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner117 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner118 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner119 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner120 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner121 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner122 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner123 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner124 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner125 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner126 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner127 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner128 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner129 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner130 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner131 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner132 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner133 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner134 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner135 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner136 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner137 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner138 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner139 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner140 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner141 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner142 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner143 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner144 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner145 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner146 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner147 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner148 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner149 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner150 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner151 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner152 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner153 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner154 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner155 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner156 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner157 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner158 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner159 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner160 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner161 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner162 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner163 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner164 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner165 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner166 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner167 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner168 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner169 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner170 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner171 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner172 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner173 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner174 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner175 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner176 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner177 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner178 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner179 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner180 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner181 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner182 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner183 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner184 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner185 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner186 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner187 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner188 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner189 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner190 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner191 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner192 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner193 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner194 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner195 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner196 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner197 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner198 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner199 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner200 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner201 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner202 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner203 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner204 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner205 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner206 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner207 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner208 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner209 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner210 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner211 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner212 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner213 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner214 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner215 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner216 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner217 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner218 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner219 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner220 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner221 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner222 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner223 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner224 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner225 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner226 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner227 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner228 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner229 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner230 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner231 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner232 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner233 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner234 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner235 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner236 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner237 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner238 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner239 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner240 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner241 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner242 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner243 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner244 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner245 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner246 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner247 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner248 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner249 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner250 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner251 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner252 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner253 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner254 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner255 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner256 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner257 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner258 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner259 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner260 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner261 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner262 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner263 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner264 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner265 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner266 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner267 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner268 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner269 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner270 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner271 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner272 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner273 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner274 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner275 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner276 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner277 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner278 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner279 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner280 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner281 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner282 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner283 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner284 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner285 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner286 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner287 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner288 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner289 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner290 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner291 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner292 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner293 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner294 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner295 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner296 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner297 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner298 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner299 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner300 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner301 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner302 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner303 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner304 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner305 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner306 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner307 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner308 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner309 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner310 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner311 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner312 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner313 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner314 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner315 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner316 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner317 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner318 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner319 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner320 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner321 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner322 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner323 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner324 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner325 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner326 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner327 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner328 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner329 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner330 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner331 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner332 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner333 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner334 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner335 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner336 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner337 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner338 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner339 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner340 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner341 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner342 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner343 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner344 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner345 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner346 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner347 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner348 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner349 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner350 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner351 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner352 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner353 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner354 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner355 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner356 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner357 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner358 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner359 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner360 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner361 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner362 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner363 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner364 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner365 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner366 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner367 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner368 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner369 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner370 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner371 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner372 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner373 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner374 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner375 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner376 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner377 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner378 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner379 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner380 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner381 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner382 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner383 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner384 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner385 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner386 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner387 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner388 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner389 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner390 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner391 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner392 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner393 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner394 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner395 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner396 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner397 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner398 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner399 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner400 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner401 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner402 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner403 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner404 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner405 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner406 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner407 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner408 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner409 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner410 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner411 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner412 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner413 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner414 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner415 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner416 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner417 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner418 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner419 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner420 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner421 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner422 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner423 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner424 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner425 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner426 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner427 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner428 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner429 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner430 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner431 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner432 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner433 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner434 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner435 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner436 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner437 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner438 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner439 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner440 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner441 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner442 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner443 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner444 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner445 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner446 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner447 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner448 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner449 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner450 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner451 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner452 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner453 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner454 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner455 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner456 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner457 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner458 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner459 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner460 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner461 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner462 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner463 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner464 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner465 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner466 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner467 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner468 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner469 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner470 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner471 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner472 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner473 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner474 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner475 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner476 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner477 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner478 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner479 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner480 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner481 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner482 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner483 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner484 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner485 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner486 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner487 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner488 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner489 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner490 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner491 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner492 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner493 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner494 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner495 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner496 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner497 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner498 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner499 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner500 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner501 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner502 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner503 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner504 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner505 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner506 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner507 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner508 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner509 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner510 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner511 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner512 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner513 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner514 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner515 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner516 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner517 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner518 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner519 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner520 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner521 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner522 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner523 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner524 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner525 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner526 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner527 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner528 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner529 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner530 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner531 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner532 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner533 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner534 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner535 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner536 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner537 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner538 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner539 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner540 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner541 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner542 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner543 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner544 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner545 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner546 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner547 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner548 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner549 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner550 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner551 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner552 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner553 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner554 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner555 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner556 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner557 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner558 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner559 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner560 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner561 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner562 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner563 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner564 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner565 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner566 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner567 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner568 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner569 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner570 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner571 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner572 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner573 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner574 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner575 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner576 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner577 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner578 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner579 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner580 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner581 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner582 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner583 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner584 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner585 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner586 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner587 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner588 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner589 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner590 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner591 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner592 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner593 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner594 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner595 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner596 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner597 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner598 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner599 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner600 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner601 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner602 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner603 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner604 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner605 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner606 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner607 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner608 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner609 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner610 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner611 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner612 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner613 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner614 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner615 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner616 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner617 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner618 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner619 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner620 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner621 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner622 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner623 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner624 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner625 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner626 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner627 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner628 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner629 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner630 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner631 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner632 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner633 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner634 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner635 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner636 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner637 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner638 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner639 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner640 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner641 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner642 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner643 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner644 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner645 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner646 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner647 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner648 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner649 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner650 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner651 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner652 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner653 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner654 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner655 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner656 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner657 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner658 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner659 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner660 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner661 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner662 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner663 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner664 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner665 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner666 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner667 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner668 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner669 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner670 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner671 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner672 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner673 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner674 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner675 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner676 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner677 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner678 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner679 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner680 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner681 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner682 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner683 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner684 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner685 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner686 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner687 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner688 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner689 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner690 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner691 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner692 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner693 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner694 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner695 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner696 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner697 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner698 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner699 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner700 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner701 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner702 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner703 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner704 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner705 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner706 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner707 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner708 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner709 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner710 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner711 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner712 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner713 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner714 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner715 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner716 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner717 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner718 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner719 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner720 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner721 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner722 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner723 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner724 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner725 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner726 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner727 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner728 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner729 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner730 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner731 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner732 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner733 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner734 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner735 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner736 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner737 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner738 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner739 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner740 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner741 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner742 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner743 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner744 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner745 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner746 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner747 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner748 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner749 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner750 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner751 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner752 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner753 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner754 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner755 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner756 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner757 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner758 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner759 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner760 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner761 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner762 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner763 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner764 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner765 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner766 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner767 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner768 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner769 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner770 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner771 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner772 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner773 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner774 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner775 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner776 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner777 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner778 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner779 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner780 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner781 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner782 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner783 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner784 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner785 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner786 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner787 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner788 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner789 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner790 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner791 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner792 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner793 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner794 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner795 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner796 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner797 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner798 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner799 { [ProtoMember(1)] public int Value { get; set; } }
        [ProtoContract]
        public class Inner800 { [ProtoMember(1)] public int Value { get; set; } }

    }
}

<|start_filename|>src/Examples/PartialClasses.cs<|end_filename|>
﻿using System;
using Xunit;

namespace ProtoBuf
{
    
    public class PartialClasses
    {


        [Fact]
        public void TestPartial()
        {
            PartialData orig = new PartialData {
                Name = "abcdefghijklmnopqrstuvwxyz",
                Number = 1234,
                When = new DateTime(2008,1,1),
                HowMuchNotSerialized = 123.456M
            },  clone = Serializer.DeepClone(orig);

            Assert.NotNull(orig); //, "original");
            Assert.NotNull(clone); //, "clone");
            Assert.Equal(orig.Name, clone.Name); //, "name");
            Assert.Equal(orig.Number, clone.Number); //, "number");
            Assert.Equal(orig.When, clone.When); //, "when");
            Assert.Equal(0.0M, clone.HowMuchNotSerialized); //, "how much");
        }

        [Fact]
        public void TestSubClass()
        {
            SubClassData orig = new SubClassData
            {
                Name = "abcdefghijklmnopqrstuvwxyz",
                Number = 1234,
                When = new DateTime(2008, 1, 1),
                HowMuchNotSerialized = 123.456M
            }, clone = (SubClassData)Serializer.DeepClone<PartialData>(orig);

            Assert.NotNull(orig); //, "original");
            Assert.NotNull(clone); //, "clone");
            Assert.Equal(orig.Name, clone.Name); //, "name");
            Assert.Equal(orig.Number, clone.Number); //, "number");
            Assert.Equal(orig.When, clone.When); //, "when");
            Assert.Equal(0.0M, clone.HowMuchNotSerialized); //, "how much");
        }
    }

    public partial class PartialData
    {
        public int Number { get; set; }
        public string Name { get; set; }
        public DateTime When { get; set; }
        public decimal HowMuchNotSerialized { get; set; }
    }


    [ProtoPartialMember(1, "Number")]
    [ProtoPartialMember(2, "Name")]
    [ProtoPartialMember(3, "When")]
    [ProtoContract]
    [ProtoInclude(4, typeof(SubClassData))]
    public partial class PartialData
    {
    }

    [ProtoContract]
    public class SubClassData : PartialData
    {
    }

}


<|start_filename|>src/protobuf-net.Core/Internal/DynamicallyAccessedMembersAttribute.cs<|end_filename|>
﻿#if PLAT_DYNAMIC_ACCESS_ATTR
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
// forwards, just to make it explicit that we mean the same
[assembly: TypeForwardedTo(typeof(DynamicallyAccessedMembersAttribute))]
[assembly: TypeForwardedTo(typeof(DynamicallyAccessedMemberTypes))]
#endif

namespace ProtoBuf.Internal
{
    using System.Diagnostics.CodeAnalysis;
    internal sealed class DynamicAccess
    {
        internal const DynamicallyAccessedMemberTypes ContractType
            = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor // construction
            | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties // annotated properties
            | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields // annotated fields and get-only accessors
            | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods; // callbacks

        internal const DynamicallyAccessedMemberTypes Serializer
            = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor;
    }
}

#if !PLAT_DYNAMIC_ACCESS_ATTR
// internalized version of https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs
// and https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Diagnostics.CodeAnalysis
{
    /// <summary>
    /// Indicates that certain members on a specified <see cref="Type"/> are accessed dynamically,
    /// for example through <see cref="System.Reflection"/>.
    /// </summary>
    /// <remarks>
    /// This allows tools to understand which members are being accessed during the execution
    /// of a program.
    ///
    /// This attribute is valid on members whose type is <see cref="Type"/> or <see cref="string"/>.
    ///
    /// When this attribute is applied to a location of type <see cref="string"/>, the assumption is
    /// that the string represents a fully qualified type name.
    ///
    /// If the attribute is applied to a method it's treated as a special case and it implies
    /// the attribute should be applied to the "this" parameter of the method. As such the attribute
    /// should only be used on instance methods of types assignable to System.Type (or string, but no methods
    /// will use it there).
    /// </remarks>
    [AttributeUsage(
        AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
        AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method,
        Inherited = false)]
    internal sealed class DynamicallyAccessedMembersAttribute : Attribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicallyAccessedMembersAttribute"/> class
        /// with the specified member types.
        /// </summary>
        /// <param name="memberTypes">The types of members dynamically accessed.</param>
        public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
        {
            MemberTypes = memberTypes;
        }

        /// <summary>
        /// Gets the <see cref="DynamicallyAccessedMemberTypes"/> which specifies the type
        /// of members dynamically accessed.
        /// </summary>
        public DynamicallyAccessedMemberTypes MemberTypes { get; }
    }

    /// <summary>
    /// Specifies the types of members that are dynamically accessed.
    ///
    /// This enumeration has a <see cref="FlagsAttribute"/> attribute that allows a
    /// bitwise combination of its member values.
    /// </summary>
    [Flags]
    internal enum DynamicallyAccessedMemberTypes
    {
        /// <summary>
        /// Specifies no members.
        /// </summary>
        None = 0,

        /// <summary>
        /// Specifies the default, parameterless public constructor.
        /// </summary>
        PublicParameterlessConstructor = 0x0001,

        /// <summary>
        /// Specifies all public constructors.
        /// </summary>
        PublicConstructors = 0x0002 | PublicParameterlessConstructor,

        /// <summary>
        /// Specifies all non-public constructors.
        /// </summary>
        NonPublicConstructors = 0x0004,

        /// <summary>
        /// Specifies all public methods.
        /// </summary>
        PublicMethods = 0x0008,

        /// <summary>
        /// Specifies all non-public methods.
        /// </summary>
        NonPublicMethods = 0x0010,

        /// <summary>
        /// Specifies all public fields.
        /// </summary>
        PublicFields = 0x0020,

        /// <summary>
        /// Specifies all non-public fields.
        /// </summary>
        NonPublicFields = 0x0040,

        /// <summary>
        /// Specifies all public nested types.
        /// </summary>
        PublicNestedTypes = 0x0080,

        /// <summary>
        /// Specifies all non-public nested types.
        /// </summary>
        NonPublicNestedTypes = 0x0100,

        /// <summary>
        /// Specifies all public properties.
        /// </summary>
        PublicProperties = 0x0200,

        /// <summary>
        /// Specifies all non-public properties.
        /// </summary>
        NonPublicProperties = 0x0400,

        /// <summary>
        /// Specifies all public events.
        /// </summary>
        PublicEvents = 0x0800,

        /// <summary>
        /// Specifies all non-public events.
        /// </summary>
        NonPublicEvents = 0x1000,

        /// <summary>
        /// Specifies all members.
        /// </summary>
        All = ~None
    }
}
#endif

<|start_filename|>src/protobuf-net/Internal/Serializers/ExternalSerializer.cs<|end_filename|>
﻿using ProtoBuf.Compiler;
using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using System;

namespace ProtoBuf.Internal.Serializers
{
    internal class ExternalSerializer
    {
        internal static IProtoTypeSerializer Create(Type target, Type serializer)
        {
            return (IProtoTypeSerializer)Activator.CreateInstance(
                typeof(ExternalSerializer<,>).MakeGenericType(serializer, target), nonPublic: true);
        }
    }

    interface IExternalSerializer
    {
        object Service { get; }
    }

    internal sealed class ExternalSerializer<TProvider, T>
        : IRuntimeProtoSerializerNode, IExternalSerializer,
        ICompiledSerializer, // just to prevent it constantly being checked for compilation
        IProtoTypeSerializer // needed to make some internal bits happy
        where TProvider : class
    {
        object IExternalSerializer.Service => Serializer;
        private static ISerializer<T> Serializer => SerializerCache<TProvider, T>.InstanceField;

        public Type ExpectedType => typeof(T);

        bool IRuntimeProtoSerializerNode.RequiresOldValue => true;

        bool IRuntimeProtoSerializerNode.ReturnsValue => true;

        public ExternalSerializer() { }

        void IRuntimeProtoSerializerNode.Write(ref ProtoWriter.State state, object value)
            => Serializer.Write(ref state, TypeHelper<T>.FromObject(value));

        object IRuntimeProtoSerializerNode.Read(ref ProtoReader.State state, object value)
            => Serializer.Read(ref state, TypeHelper<T>.FromObject(value));

        SerializerFeatures IProtoTypeSerializer.Features => Serializer.Features;


        Type IProtoTypeSerializer.BaseType => ExpectedType;

        bool IProtoTypeSerializer.CanCreateInstance() => Serializer is IFactory<T>;

        object IProtoTypeSerializer.CreateInstance(ISerializationContext context)
            => Serializer is not IFactory<T> factory ? null : (object)factory.Create(context);

        void IProtoTypeSerializer.Callback(object value, TypeModel.CallbackType callbackType, ISerializationContext context)
        { }

        bool IProtoTypeSerializer.ShouldEmitCreateInstance => false;
        bool IProtoTypeSerializer.HasCallbacks(TypeModel.CallbackType callbackType) => false;

        bool IProtoTypeSerializer.HasInheritance => false;
        bool IProtoTypeSerializer.IsSubType => false;

        void IProtoTypeSerializer.EmitCreateInstance(CompilerContext ctx, bool callNoteObject)
            => ThrowHelper.ThrowNotSupportedException();
        void IProtoTypeSerializer.EmitCallback(CompilerContext ctx, Local valueFrom, TypeModel.CallbackType callbackType)
            => ThrowHelper.ThrowNotSupportedException();

        void IProtoTypeSerializer.EmitReadRoot(CompilerContext ctx, Local entity)
            => ThrowHelper.ThrowNotSupportedException();
        void IProtoTypeSerializer.EmitWriteRoot(CompilerContext ctx, Local entity)
            => ThrowHelper.ThrowNotSupportedException();

        void IRuntimeProtoSerializerNode.EmitWrite(CompilerContext ctx, Local valueFrom)
        {
            // SerializerCache.Get<TProvider, T>().Write(ref state, value);
            // if TProvider is public, or
            // state.GetSerializer<T>().Write(ref state, value);
            using var loc = ctx.GetLocalWithValue(typeof(T), valueFrom);

            // get the serializer
            if (ctx.NonPublic || RuntimeTypeModel.IsFullyPublic(typeof(TProvider)))
            {
                ctx.EmitCall(typeof(SerializerCache).GetMethod(nameof(SerializerCache.Get)).MakeGenericMethod(typeof(TProvider), typeof(T)));
            }
            else
            {
                ctx.LoadState();
                ctx.EmitCall(typeof(ProtoWriter.State).GetMethod(nameof(ProtoWriter.State.GetSerializer)).MakeGenericMethod(typeof(T)));
            }

            // invoke Write
            ctx.LoadState();
            ctx.LoadValue(loc); // value
            ctx.EmitCall(typeof(ISerializer<T>).GetMethod(nameof(ISerializer<T>.Write)));
        }

        void IRuntimeProtoSerializerNode.EmitRead(CompilerContext ctx, Local entity)
        {
            // entity = SerializerCache.Get<TProvider, T>().Read(ref state, value);
            // if TProvider is public, or
            // entity = state.GetSerializer<T>().Read(ref state, value);
            using var loc = ctx.GetLocalWithValue(typeof(T), entity);

            // get the serializer
            if (ctx.NonPublic || RuntimeTypeModel.IsFullyPublic(typeof(TProvider)))
            {
                ctx.EmitCall(typeof(SerializerCache).GetMethod(nameof(SerializerCache.Get)).MakeGenericMethod(typeof(TProvider), typeof(T)));
            }
            else
            {
                ctx.LoadState();
                ctx.EmitCall(typeof(ProtoReader.State).GetMethod(nameof(ProtoReader.State.GetSerializer)).MakeGenericMethod(typeof(T)));
            }

            // invoke Read
            ctx.LoadState();
            ctx.LoadValue(loc);
            ctx.EmitCall(typeof(ISerializer<T>).GetMethod(nameof(ISerializer<T>.Read)));

            // store back
            ctx.StoreValue(entity);
        }
    }
}

<|start_filename|>src/protobuf-net/Internal/Serializers/IRuntimeProtoTypeSerializer.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using System;

namespace ProtoBuf.Internal.Serializers
{
    internal interface IProtoTypeSerializer : IRuntimeProtoSerializerNode
    {
        Type BaseType { get; }
        bool HasCallbacks(TypeModel.CallbackType callbackType);
        bool CanCreateInstance();
        object CreateInstance(ISerializationContext context);
        void Callback(object value, TypeModel.CallbackType callbackType, ISerializationContext context);

        void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType);
        void EmitCreateInstance(Compiler.CompilerContext ctx, bool callNoteObject = true);
        bool ShouldEmitCreateInstance { get; }

        void EmitReadRoot(Compiler.CompilerContext ctx, Compiler.Local entity);
        void EmitWriteRoot(Compiler.CompilerContext ctx, Compiler.Local entity);

        bool HasInheritance { get; }

        bool IsSubType { get; }

        SerializerFeatures Features { get; }
    }
}

<|start_filename|>assorted/demo-rpc-server-mvc/Controllers/NorthwindController.cs<|end_filename|>
using demo_rpc_server_mvc.Models;
using Protobuf.Web.Mvc;

namespace demo_rpc_server_mvc.Controllers
{
    public class NorthwindController : ProtoController
    {
        public NorthwindController()
        {
            Add<INorthwind, Northwind>();
        }

    }
}


<|start_filename|>src/protobuf-net.Test/Meta/FieldOffset.cs<|end_filename|>
﻿using System;
using Xunit;

namespace ProtoBuf.Meta
{
    public class FieldOffset
    {
        [Fact]
        public void ZeroOffsetIsFineEvenWhenCompiled()
        {
            var model = RuntimeTypeModel.Create();
            var mt = model.Add(typeof(Foo), true);
            model.CompileInPlace();
            mt.ApplyFieldOffset(0); // fine because no-op

            var proto = model.GetSchema(typeof(Foo), ProtoSyntax.Proto3);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Meta;

message Bar {
   int32 X = 1;
   string Y = 2;
}
message Foo {
   int32 A = 5;
   string B = 6;
   oneof subtype {
      Bar Bar = 42;
   }
}
", proto, ignoreLineEndingDifferences: true);
        }

        [Fact]
        public void NonZeroOffsetFailsWhenCompiled()
        {
            var model = RuntimeTypeModel.Create();
            var mt = model.Add(typeof(Foo), true);
            model.CompileInPlace();
            Assert.Throws<InvalidOperationException>(() => mt.ApplyFieldOffset(1));
        }

        [Fact]
        public void NegativeOffsetFailsIfMakesInvalid()
        {
            var model = RuntimeTypeModel.Create();
            var mt = model.Add(typeof(Foo), true);
            Assert.Throws<ArgumentOutOfRangeException>(() => mt.ApplyFieldOffset(-10));
        }

        [Fact]
        public void NegativeOffsetIsFineWhenLeavesValid()
        {
            var model = RuntimeTypeModel.Create();
            var mt = model.Add(typeof(Foo), true);
            mt.ApplyFieldOffset(-4); // leaves everything +ve

            var proto = model.GetSchema(typeof(Foo), ProtoSyntax.Proto3);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Meta;

message Bar {
   int32 X = 1;
   string Y = 2;
}
message Foo {
   int32 A = 1;
   string B = 2;
   oneof subtype {
      Bar Bar = 38;
   }
}
", proto, ignoreLineEndingDifferences: true);
        }

        [Fact]
        public void PositiveOffsetIsFineWhenLeavesValid()
        {
            var model = RuntimeTypeModel.Create();
            var mt = model.Add(typeof(Foo), true);
            mt.ApplyFieldOffset(4);

            var proto = model.GetSchema(typeof(Foo), ProtoSyntax.Proto3);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Meta;

message Bar {
   int32 X = 1;
   string Y = 2;
}
message Foo {
   int32 A = 9;
   string B = 10;
   oneof subtype {
      Bar Bar = 46;
   }
}
", proto, ignoreLineEndingDifferences: true);
        }
    }

    [ProtoContract]
    [ProtoInclude(42, typeof(Bar))]
    public class Foo
    {
        [ProtoMember(5)]
        public int A { get; set; }
        [ProtoMember(6)]
        public string B { get; set; }
    }
    [ProtoContract]
    public class Bar : Foo
    {
        [ProtoMember(1)]
        public int X { get; set; }
        [ProtoMember(2)]
        public string Y { get; set; }
    }
}

<|start_filename|>src/protobuf-net.Test/Issues/SO60842788.cs<|end_filename|>
﻿using System;
using System.IO;
using Xunit;
using Xunit.Abstractions;

namespace ProtoBuf.Test.Issues
{
    public class SO60842788
    {
        private readonly ITestOutputHelper _log;
        public SO60842788(ITestOutputHelper log) => _log = log;
        private void Log(string message) => _log?.WriteLine(message);

        static readonly bool IsCoreFX = typeof(int).Assembly.GetName().Name == "mscorlib", IsNet5 = typeof(string).Assembly.GetName().Version >= new Version(5,0);

        [Fact]
        public void CanRoundTripWrapped()
        {
            string EXPECTED = IsCoreFX
                ? @"0A-59-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-12-5A-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-12-5A-53-79-73-74-65-6D-2E-55-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39"
                : IsNet5 // Net5 hanges the Version token in the AQN
                ? @"0A-67-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-35-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65-12-68-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-35-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65-12-68-53-79-73-74-65-6D-2E-55-49-6E-74-33-32-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-35-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65"
                : @"0A-67-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65-12-68-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65-12-68-53-79-73-74-65-6D-2E-55-49-6E-74-33-32-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65";

            var data = new Wrapped { Single = typeof(int), Vector = new[] { typeof(string), typeof(uint) } };
            using var ms = new MemoryStream();
            Serializer.Serialize(ms, data);
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Log(hex);
            Assert.Equal(EXPECTED, hex);
            ms.Position = 0;
            var clone = Serializer.Deserialize<Wrapped>(ms);
            Assert.Same(typeof(int), clone.Single);
            Assert.Equal(2, clone.Vector.Length);
            Assert.Equal(typeof(string), clone.Vector[0]);
            Assert.Equal(typeof(uint), clone.Vector[1]);
        }

        [Fact]
        public void CanRoundTripVector()
        {
            string EXPECTED = IsCoreFX
                ? @"0A-5A-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-0A-5A-53-79-73-74-65-6D-2E-55-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39"
                : IsNet5 // Net5 hanges the Version token in the AQN
                ? @"0A-68-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-35-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65-0A-68-53-79-73-74-65-6D-2E-55-49-6E-74-33-32-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-35-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65"
                : @"0A-68-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65-0A-68-53-79-73-74-65-6D-2E-55-49-6E-74-33-32-2C-20-53-79-73-74-65-6D-2E-50-72-69-76-61-74-65-2E-43-6F-72-65-4C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-34-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-37-63-65-63-38-35-64-37-62-65-61-37-37-39-38-65";

            var data = new[] { typeof(string), typeof(uint) };
            using var ms = new MemoryStream();
            Serializer.Serialize(ms, data);
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Log(hex);
            Assert.Equal(EXPECTED, hex);
            ms.Position = 0;
            var clone = Serializer.Deserialize<Type[]>(ms);
            Assert.Equal(2, clone.Length);
            Assert.Equal(typeof(string), clone[0]);
            Assert.Equal(typeof(uint), clone[1]);
        }

        [Fact]
        public void WrappedAndVectorAreSame()
        {
            var data = new[] { typeof(string), typeof(uint) };
            using var ms = new MemoryStream();
            Serializer.Serialize(ms, data);
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Log(hex);
            
            ms.Position = 0;
            var clone = Serializer.Deserialize<WrappedBasic>(ms).Vector;
            Assert.Equal(2, clone.Length);
            Assert.Equal(typeof(string), clone[0]);
            Assert.Equal(typeof(uint), clone[1]);
        }
    }

    [ProtoContract]
    public class Wrapped
    {
        [ProtoMember(1)]
        public Type Single { get; set; }
        [ProtoMember(2)]
        public Type[] Vector { get; set; }
    }

    [ProtoContract]
    public class WrappedBasic
    {
        [ProtoMember(1)]
        public Type[] Vector { get; set; }
    }
}


<|start_filename|>src/Examples/Issues/Issue228.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ProtoBuf;
using ProtoBuf.Meta;
using Xunit;

namespace Examples.Issues
{
    public class Issue228
    {
        [ProtoContract]
        public class BaseModel<T>
        {
            [ProtoMember(1, IsRequired = true),]
            public int Timestamp { get; set; }

            [ProtoMember(2, IsRequired = true)]
            public T Data { get; set; }
        }

        [ProtoContract]
        public class IdName
        {
            [ProtoMember(1)]
            public int Id { get; set; }

            [ProtoMember(2)]
            public string Name { get; set; }
        }

        [Fact]
        public void ShouldHandleGenerics()
        {
            var protoFile = Serializer.GetProto<BaseModel<List<IdName>>>(ProtoSyntax.Proto2);
            Assert.Equal(@"syntax = ""proto2"";
package Examples.Issues;

message BaseModel_List_IdName {
   required int32 Timestamp = 1;
   repeated IdName Data = 2;
}
message IdName {
   optional int32 Id = 1 [default = 0];
   optional string Name = 2;
}
", protoFile, ignoreLineEndingDifferences: true);
        }
    }
}


<|start_filename|>src/protobuf-net.Test/Issues/Issue381.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using Xunit;

namespace ProtoBuf.Issues
{
    public class Issue381
    {
        [Fact]
        public void CheckCompilerAvailable()
        {
            Assert.True(RuntimeTypeModel.EnableAutoCompile());
        }
    }
}


<|start_filename|>assorted/SqlClr/MyUdt.cs<|end_filename|>
﻿using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System;
using ProtoBuf;

namespace SqlClr
{
    [ProtoContract]
    [SqlUserDefinedTypeAttribute(Format.UserDefined, IsByteOrdered=true,
        IsFixedLength = false, MaxByteSize=1024)]
    public sealed class MyProtoUdt : INullable, IBinarySerialize
    {
        public bool IsNull { get { return false; } }
        public static MyProtoUdt Null() { return null; }

        public static MyProtoUdt Parse(string value) {
            throw new NotImplementedException();
        }

        void IBinarySerialize.Read(System.IO.BinaryReader r) {
            Serializer.Merge<MyProtoUdt>(r.BaseStream, this);
        }

        void IBinarySerialize.Write(System.IO.BinaryWriter w) {
            Serializer.Serialize<MyProtoUdt>(w.BaseStream, this);
        }
        [ProtoMember(3)]
        public int ShoeSize { get; set; }
        [ProtoMember(4)]
        public DateTime DateOfBirth { get; set; }
        [ProtoMember(5)]
        public bool IsActive { get; set; }
        [ProtoMember(6)]
        public decimal Balance { get; set; }
        [ProtoMember(7)]
        public float Ratio { get; set; }
    }


    [ProtoContract]
    [SqlUserDefinedTypeAttribute(Format.Native, IsByteOrdered = true)]
    public sealed class MyBasicUdt : INullable
    {
        public bool IsNull { get { return false; } }
        public static MyBasicUdt Null() { return null; }

        public static MyBasicUdt Parse(string value)
        {
            throw new NotImplementedException();
        }

        public int ShoeSize { get; set; }
        public DateTime DateOfBirth { get; set; }
        public bool IsActive { get; set; }
        public decimal Balance { get; set; }
        public float Ratio { get; set; }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/TagDecorator.cs<|end_filename|>
﻿using System;
using System.Diagnostics;
using ProtoBuf.Meta;
using ProtoBuf.Serializers;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class TagDecorator : ProtoDecoratorBase, IProtoTypeSerializer
    {
        SerializerFeatures IProtoTypeSerializer.Features => wireType.AsFeatures();
        bool IProtoTypeSerializer.IsSubType => Tail is IProtoTypeSerializer pts && pts.IsSubType;
        public bool HasCallbacks(TypeModel.CallbackType callbackType) => Tail is IProtoTypeSerializer pts && pts.HasCallbacks(callbackType);

        public bool CanCreateInstance() => Tail is IProtoTypeSerializer pts && pts.CanCreateInstance();

        public object CreateInstance(ISerializationContext source) => ((IProtoTypeSerializer)Tail).CreateInstance(source);

        public void Callback(object value, TypeModel.CallbackType callbackType, ISerializationContext context)
            => (Tail as IProtoTypeSerializer)?.Callback(value, callbackType, context);
            
        public void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType)
        {
            // we only expect this to be invoked if HasCallbacks returned true, so implicitly Tail
            // **must** be of the correct type
            ((IProtoTypeSerializer)Tail).EmitCallback(ctx, valueFrom, callbackType);
        }

        public void EmitCreateInstance(Compiler.CompilerContext ctx, bool callNoteObject)
        {
            ((IProtoTypeSerializer)Tail).EmitCreateInstance(ctx, callNoteObject);
        }

        bool IProtoTypeSerializer.ShouldEmitCreateInstance => Tail is IProtoTypeSerializer pts && pts.ShouldEmitCreateInstance;

        public override Type ExpectedType => Tail.ExpectedType;
        Type IProtoTypeSerializer.BaseType => ExpectedType;

        public TagDecorator(int fieldNumber, WireType wireType, bool strict, IRuntimeProtoSerializerNode tail)
            : base(tail)
        {
            this.fieldNumber = fieldNumber;
            this.wireType = wireType;
            this.strict = strict;
        }

        public override bool RequiresOldValue => Tail.RequiresOldValue;

        public override bool ReturnsValue => Tail.ReturnsValue;

        private readonly bool strict;
        private readonly int fieldNumber;
        private readonly WireType wireType;

        private bool NeedsHint => ((int)wireType & ~7) != 0;

        public override object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(fieldNumber == state.FieldNumber);
            if (strict) { state.Assert(wireType); }
            else if (NeedsHint) { state.Hint(wireType); }
            return Tail.Read(ref state, value);
        }

        public override void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteFieldHeader(fieldNumber, wireType);
            Tail.Write(ref state, value);
        }

        bool IProtoTypeSerializer.HasInheritance => false;

        void IProtoTypeSerializer.EmitReadRoot(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
            => EmitRead(ctx, valueFrom);

        void IProtoTypeSerializer.EmitWriteRoot(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
            => EmitWrite(ctx, valueFrom);

        protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            if (Tail is IDirectWriteNode dw && dw.CanEmitDirectWrite(wireType))
            {
                dw.EmitDirectWrite(fieldNumber, wireType, ctx, valueFrom);
            }
            else
            {
                ctx.LoadState();
                ctx.LoadValue((int)fieldNumber);
                ctx.LoadValue((int)wireType);
                ctx.EmitCall(typeof(ProtoWriter.State).GetMethod(nameof(ProtoWriter.State.WriteFieldHeader)));
                Tail.EmitWrite(ctx, valueFrom);
            }
        }

        public bool CanEmitDirectWrite()
            => Tail is IDirectWriteNode dw && dw.CanEmitDirectWrite(wireType);

        public void EmitDirectWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
            => ((IDirectWriteNode)Tail).EmitDirectWrite(fieldNumber, wireType, ctx, valueFrom);

        protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            if (strict || NeedsHint)
            {
                ctx.LoadState();
                ctx.LoadValue((int)wireType);
                string name = strict ? nameof(ProtoReader.State.Assert) : nameof(ProtoReader.State.Hint);
                ctx.EmitCall(typeof(ProtoReader.State).GetMethod(name, new[] { typeof(WireType) }));
            }
            Tail.EmitRead(ctx, valueFrom);
        }
    }
}

<|start_filename|>src/Benchmark/Codegen/protogen_pooled.cs<|end_filename|>
﻿//#if NEW_API
//// This file was generated by a tool; you should avoid making direct changes.
//// Consider using 'partial classes' to extend these types
//// Input: my.proto

//#pragma warning disable CS1591, CS0612, CS3021, IDE1006
//using ProtoBuf.Collections;
//using System;

//namespace protogen.pooled
//{

//    [global::ProtoBuf.ProtoContract()]
//    public partial class Database : global::ProtoBuf.IExtensible, IDisposable
//    {
//        void IDisposable.Dispose()
//        {
//            PooledList.Dispose(ref _orders, true);
//        }

//        private global::ProtoBuf.IExtension __pbn__extensionData;
//        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
//            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

//        [global::ProtoBuf.ProtoMember(1)]
//        public PooledList<Order> Orders => PooledList.Create(ref _orders);
//        public bool ShouldSerializeOrders() => _orders.ShouldSerialize();
//        private PooledList<Order> _orders;
//    }

//    [global::ProtoBuf.ProtoContract()]
//    public partial class Order : global::ProtoBuf.IExtensible, IDisposable
//    {
//        void IDisposable.Dispose()
//        {
//            PooledList.Dispose(ref _lines, true);
//        }

//        private global::ProtoBuf.IExtension __pbn__extensionData;
//        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
//            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

//        [global::ProtoBuf.ProtoMember(1)]
//        public int OrderID { get; set; }

//        [global::ProtoBuf.ProtoMember(2)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string CustomerID { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(3)]
//        public int EmployeeID { get; set; }

//        [global::ProtoBuf.ProtoMember(4, DataFormat = global::ProtoBuf.DataFormat.WellKnown)]
//        public global::System.DateTime? OrderDate { get; set; }

//        [global::ProtoBuf.ProtoMember(5, DataFormat = global::ProtoBuf.DataFormat.WellKnown)]
//        public global::System.DateTime? RequiredDate { get; set; }

//        [global::ProtoBuf.ProtoMember(6, DataFormat = global::ProtoBuf.DataFormat.WellKnown)]
//        public global::System.DateTime? ShippedDate { get; set; }

//        [global::ProtoBuf.ProtoMember(7)]
//        public int ShipVia { get; set; }

//        [global::ProtoBuf.ProtoMember(8)]
//        public double Freight { get; set; }

//        [global::ProtoBuf.ProtoMember(9)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string ShipName { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(10)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string ShipAddress { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(11)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string ShipCity { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(12)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string ShipRegion { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(13)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string ShipPostalCode { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(14)]
//        [global::System.ComponentModel.DefaultValue("")]
//        public string ShipCountry { get; set; } = "";

//        [global::ProtoBuf.ProtoMember(15)]
//        public PooledList<OrderLine> Lines => PooledList.Create(ref _lines);
//        public bool ShouldSerializeLines() => _lines.ShouldSerialize();
//        private PooledList<OrderLine> _lines;

//    }

//    [global::ProtoBuf.ProtoContract()]
//    public partial class OrderLine : global::ProtoBuf.IExtensible, IDisposable
//    {
//        void IDisposable.Dispose() { }

//        private global::ProtoBuf.IExtension __pbn__extensionData;
//        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
//            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

//        [global::ProtoBuf.ProtoMember(1)]
//        public int OrderID { get; set; }

//        [global::ProtoBuf.ProtoMember(2)]
//        public int ProductID { get; set; }

//        [global::ProtoBuf.ProtoMember(3)]
//        public double UnitPrice { get; set; }

//        [global::ProtoBuf.ProtoMember(4, DataFormat = global::ProtoBuf.DataFormat.ZigZag)]
//        public int Quantity { get; set; }

//        [global::ProtoBuf.ProtoMember(5)]
//        public float Discount { get; set; }

//    }

//}

//#pragma warning restore CS1591, CS0612, CS3021, IDE1006

//#endif

<|start_filename|>src/Examples/Issues/SO10115538.cs<|end_filename|>
﻿#if !NO_WCF
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using ProtoBuf.ServiceModel;

namespace Examples.Issues
{
    
    public class SO10115538
    {
        public class MyService : IMyService
        {
            public string Test(Member member)
            {
                return "from svc: " + member.ToString();
            }
        }
        [ServiceContract]
        public interface IMyService
        {
            [OperationContract]
            string Test(Member member);
        }
        ServiceHost host;

        public IMyService GetService()
        {
            var endpoint =
                new ServiceEndpoint(
                ContractDescription.GetContract(typeof(IMyService)), new NetTcpBinding(SecurityMode.None),
                new EndpointAddress("net.tcp://localhost:89/MyService/svc"));
            endpoint.Behaviors.Add(new ProtoEndpointBehavior());
            return new ChannelFactory<IMyService>(endpoint).CreateChannel();
            
            //ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(new NetTcpBinding(SecurityMode.None), "net.tcp://localhost:89/MyService/svc");
            //var client = factory.CreateChannel();
            //return client;
        }
        [TestFixtureSetUp]
        public void StartServer()
        {
            try
            {
                StopServer();
                host = new ServiceHost(typeof(MyService),
                    new Uri("net.tcp://localhost:89/MyService"));
                host.AddServiceEndpoint(typeof (IMyService), new NetTcpBinding(SecurityMode.None),
                                        "net.tcp://localhost:89/MyService/svc").Behaviors.Add(
                                            new ProtoEndpointBehavior());
                host.Open();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.GetType().FullName);
                Console.WriteLine(ex.Message);
                throw;
            }
        }

        [TestFixtureTearDown]
        public void StopServer()
        {
            if (host != null)
            {
                host.Close();
                host = null;
            }
        }


        Member InventMember()
        {
            Member m = new Member();
            m.FirstName = "Mike";
            m.LastName = "Hanrahan";
            m.UserId = new Guid("467c231f-f692-4432-ab1b-342c237b3ca9");
            m.AccountStatus = MemberAccountStatus.Blocked;
            m.EnteredBy = "qwertt";

            return m;
        }
        [Fact]
        public void TestUsingMemoryStream()
        {
            Base.PrepareMetaDataForSerialization();
            var m = InventMember();
            Assert.Equal("<NAME>, 467c231f-f692-4432-ab1b-342c237b3ca9, Blocked, qwertt", m.ToString());
            using (var ms = new MemoryStream())
            {
                Serializer.Serialize<Member>(ms, m);
                Console.WriteLine(ms.Length.ToString());
                ms.Position = 0;
                var member2 = Serializer.Deserialize<Member>(ms);
                Assert.Equal("qwertt", member2.EnteredBy);
                Assert.Equal("Mike", member2.FirstName);

                Assert.Equal("<NAME>, 467c231f-f692-4432-ab1b-342c237b3ca9, Blocked, qwertt",
                                member2.ToString());
            }
        }


        [Fact]
        public void TestUsingWcf()
        {
            Base.PrepareMetaDataForSerialization();
            var m = InventMember();
            var client = GetService();
            string s = client.Test(m);
            Assert.Equal("from svc: Mike Hanrahan, 467c231f-f692-4432-ab1b-342c237b3ca9, Blocked, qwertt", s);
        }

        /// <summary>
        /// This entity represents a member or user of the site.
        /// </summary>
        [DataContract]
        [Serializable]
        public class Member : User
        {
            public override string ToString()
            {
                return string.Format("{0} {1}, {2}, {3}, {4}", FirstName, LastName, UserId, AccountStatus, EnteredBy);
            }
            public Member()
                : base()
            {
                EntityType = EntityType.Member;
            }

            [DataMember(Order = 20)]
            public int Id { get; set; }

            [DataMember(Order = 21)]
            public string MemberName { get; set; }

            
            [DataMember(Order = 23)]
            public MemberAccountStatus AccountStatus { get; set; }

            #region static

            public static readonly string CacheCollectionKey = "MemberCollection";

            private static readonly string CacheItemKeyPrefix = "Member:";

            public static string GetCacheItemKey(int id)
            {
                return CacheItemKeyPrefix + id.ToString();
            }

            #endregion
        }
         /// <summary>
        /// This class represents a user in the system.  For example, a user could be a member or a merchant user.
        /// </summary>
        [DataContract]
        [Serializable]
        public class User: Base
        {
            public User()
                :base()
            {
                EntityType = EntityType.User;
            }

            [DataMember(Order = 10)]
            public Guid UserId { get; set; }

            [DataMember(Order = 11, Name = "First Name")]
            public string FirstName { get; set; }

            [DataMember(Order = 12, Name = "Last Name")]
            public string LastName { get; set; }

            }
        /// <summary>
        /// This is the base class for all entities involved in the request/response pattern of our services
        /// </summary>
        /// <remarks>
        /// The objects derived from this class are used to transfer data from our service classes to our UIs and back again and they should 
        /// not contain any logic.
        /// </remarks>
        [DataContract]
        [Serializable]
        public abstract class Base
        {
            public Base()
            {
                //Set some defaults for this
                EnteredBy = System.Environment.UserName;
                EnteredSource = System.Environment.MachineName;
            }

            /// <summary>
            /// This is the record timestamp
            /// </summary>
            [DataMember(Order = 2)]
            public DateTime RecordTimeStamp { get; set; }

            /// <summary>
            /// This is the name of the user who last edited the entity
            /// </summary>
            [DataMember(Order = 3)]
            public string EnteredBy { get; set; }

            /// <summary>
            /// This is the source of the last edited entity
            /// </summary>
            [DataMember(Order = 4)]
            public string EnteredSource { get; set; }

            /// <summary>
            /// Flag denoting if the record is a new record or not.
            /// </summary>
            /// <remarks>
            /// To flag an entity as an existing record call the "FlagAsExistingReport()" method.
            /// </remarks>
            public bool IsNewRecord
            {
                get
                {
                    return _isNewRecord;
                }
            }

            [DataMember(Order = 6)]
            protected bool _isNewRecord = true;
            /// <summary>
            /// Flags the entity as a record that already exists in the database
            /// </summary>
            /// <remarks>
            /// This is a method rather than a field to demonstrait that this should be called with caution (as opposed to inadvertantly setting a flag!)
            /// <para>
            /// Note that this method should only need to be called on object creation if the entity has a composite key.  Otherwise the flag is
            /// set when the id is being set.  It should always be called on saving an entity.
            /// </para>
            /// </remarks>
            public void FlagAsExistingRecord()
            {
                _isNewRecord = false;
            }


            /// <summary>
            /// This is the type of entity we are working with
            /// </summary>
            [DataMember(Order = 7)]
            private EntityType _entityType = EntityType.Unknown;
            public EntityType EntityType
            {
                get
                {
                    return _entityType;
                }
                protected set
                {
                    _entityType = value;
                }
            }


            /// <summary>
            /// Flag to say if the id generated for this class need to be int64 in size.
            /// </summary>
            [DataMember(Order = 9)]
            public bool IdRequiresInt64 { get; protected set; }

            /// <summary>
            /// This method tells us if the database id has been assigned.  Note that this does
            /// not mean the entity has been saved, only if the id has been assigned (so the id could be greater than 0, but the
            /// entity could still be a NewRecord
            /// </summary>
            /// <returns></returns>
            [DataMember(Order = 8)]
            public bool HasDbIdBeenAssigned { get; protected set; }

            private Guid _validationId = Guid.NewGuid();
            public Guid EntityValidationId
            {
                get
                {
                    return _validationId;
                }
            }

            /// <summary>
            /// Returns all known child types
            /// </summary>
            public IEnumerable<Type> GetAllTypes()
            {
                Assembly current = Assembly.GetCallingAssembly();
                List<Type> derivedTypes = new List<Type>();
                var allTypes = current.GetTypes();
                foreach (var t in allTypes)
                {
                    if (t.IsAssignableFrom(typeof(Base)))
                    {
                        derivedTypes.Add(t);
                    }
                }
                return derivedTypes;
            }

            #region Static Methods


            private static object _metaLock = new object();
            private static bool _metaDataPrepared = false;
            /// <summary>
            /// Creates protobuf type models from the entities in this assembly
            /// </summary>
            public static void PrepareMetaDataForSerialization()
            {
                lock (_metaLock)
                {
                    if (_metaDataPrepared) { return; }

                    Assembly current = Assembly.GetExecutingAssembly();
                    var allTypes = current.GetTypes();
                    foreach (var t in allTypes.Where(t => t.IsNested && t.DeclaringType == typeof(SO10115538)))
                    {
                        Console.WriteLine("Checking type: " + t.Name);
                        checkType(t);
                    }

                    _metaDataPrepared = true;
                }
            }

            private static void checkType(Type type)
            {
                Assembly current = Assembly.GetExecutingAssembly();
                var allTypes = current.GetTypes();
                int key = 1000;
                foreach (var t in allTypes)
                {
                    if (t.IsSubclassOf(type) && t.BaseType == type)
                    {
                        Console.WriteLine("Adding sub-type " + t.Name + " with key " + key);
                        RuntimeTypeModel.Default[type].AddSubType(key, t);
                        key++;
                    }
                }
            }

            #endregion
        }
        public enum EntityType
        {
            Unknown, Member, User
        }
        public enum MemberAccountStatus
        {
            Blocked
        }
        }

}
#endif

<|start_filename|>assorted/SilverlightExtended/Nuxleus.MetaData/Label.cs<|end_filename|>
using System;
using System.Collections.Generic;
using System.Text;

namespace Nuxleus.MetaData {

    [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)]
    public class LabelAttribute : Attribute {

        public readonly string Label;

        public LabelAttribute(string message) {
            Label = message;
        }

        public static string FromMember (object o) {
            return ((LabelAttribute)
            o.GetType().GetMember(o.ToString())[0].GetCustomAttributes(typeof(LabelAttribute), false)[0]).Label;
        }

        public static string FromType (object o) {
            return ((LabelAttribute)
            o.GetType().GetCustomAttributes(typeof(LabelAttribute), false)[0]).Label;
        }
    }
}



<|start_filename|>src/BuildToolsUnitTests/AnalyzerTestBase.cs<|end_filename|>
﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using ProtoBuf.BuildTools.Analyzers;
using ProtoBuf.BuildTools.Internal;
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Xunit.Abstractions;

namespace BuildToolsUnitTests
{
    public abstract class AnalyzerTestBase<TAnalyzer> where TAnalyzer : DiagnosticAnalyzer
    {
        // utility anaylzer data, with thanks to <NAME>
        private readonly ITestOutputHelper? _testOutputHelper;
        protected AnalyzerTestBase(ITestOutputHelper? testOutputHelper = null) => _testOutputHelper = testOutputHelper;

        protected virtual TAnalyzer Analyzer
        {
            get
            {
                var obj = Activator.CreateInstance<TAnalyzer>();
                if (obj is ILoggingAnalyzer logging && _testOutputHelper is not null)
                {
                    logging.Log += s => _testOutputHelper.WriteLine(s);
                }
                return obj;
            }
        }

        protected virtual bool ReferenceProtoBuf => true;

        protected virtual Project SetupProject(Project project) => project;

        protected Task<ICollection<Diagnostic>> AnalyzeAsync(string? sourceCode = null, [CallerMemberName] string? callerMemberName = null, bool ignoreCompatibilityLevelAdvice = true, bool ignorePreferAsyncAdvice = true) =>
            AnalyzeAsync(project => string.IsNullOrWhiteSpace(sourceCode) ? project : project.AddDocument(callerMemberName + ".cs", sourceCode).Project, callerMemberName, ignoreCompatibilityLevelAdvice, ignorePreferAsyncAdvice);

        protected async Task<ICollection<Diagnostic>> AnalyzeAsync(Func<Project, Project> projectModifier, [CallerMemberName] string? callerMemberName = null, bool ignoreCompatibilityLevelAdvice = true, bool ignorePreferAsyncAdvice = true)
        {
            _ = callerMemberName;
            var (project, compilation) = await ObtainProjectAndCompilationAsync(projectModifier);
            var analyzers = project.AnalyzerReferences.SelectMany(x => x.GetAnalyzers(project.Language)).ToImmutableArray();
            var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions);
            var diagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync();
            if (ignoreCompatibilityLevelAdvice)
            {
                diagnostics = diagnostics.RemoveAll(x => x.Descriptor == DataContractAnalyzer.MissingCompatibilityLevel);
            }
            if (ignorePreferAsyncAdvice)
            {
                diagnostics = diagnostics.RemoveAll(x => x.Descriptor == ServiceContractAnalyzer.PreferAsync);
            }
            if (_testOutputHelper is object)
            {
                foreach (var d in diagnostics)
                {
                    _testOutputHelper.WriteLine(d.ToString());
                }
            }
            return diagnostics;
        }

        protected async Task<(Project Project, Compilation Compilation)> ObtainProjectAndCompilationAsync(Func<Project, Project>? projectModifier = null, [CallerMemberName] string? callerMemberName = null)
        {
            _ = callerMemberName;
            var workspace = new AdhocWorkspace();
            var project = workspace.AddProject("protobuf-net.BuildTools.AnalyzerTests", LanguageNames.CSharp);
            project = project
                .WithCompilationOptions(project.CompilationOptions!.WithOutputKind(OutputKind.DynamicallyLinkedLibrary))
                .AddMetadataReference(MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location))
                .AddAnalyzerReference(new AnalyzerImageReference(ImmutableArray.Create<DiagnosticAnalyzer>(Analyzer)));
            project = SetupProject(project);

            if (ReferenceProtoBuf)
            {
                project = project
                    .AddMetadataReference(MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=<KEY>").Location))
                    .AddMetadataReference(MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location))
                    .AddMetadataReference(MetadataReference.CreateFromFile(typeof(TypeModel).Assembly.Location));
            }

            project = projectModifier?.Invoke(project) ?? project;

            var compilation = await project.GetCompilationAsync();
            return (project, compilation!);
        }
    }
}


<|start_filename|>src/protobuf-net.MessagePipes/MessagePipe.cs<|end_filename|>
﻿using Pipelines.Sockets.Unofficial;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace ProtoBuf.MessagePipes
{
    /// <summary>
    /// Provides basic message-pipe functionality over a stream or pipeline; the caller is responsible
    /// for all security etc aspects of securing the transport if necessary
    /// </summary>
    public static class MessagePipe
    {
        private static async IAsyncEnumerable<T> AsAsyncEnumerable<T>(
            ChannelReader<T> reader,
            [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            while (await reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
            {
                while (reader.TryRead(out T item))
                {
                    yield return item;
                }
            }
        }

        private static async ValueTask WriteToChannelAsync<T>(
            IAsyncEnumerable<T> source, ChannelWriter<T> destination, CancellationToken cancellationToken, bool markComplete)
        {
            await foreach (var item in source.WithCancellation(cancellationToken).ConfigureAwait(false))
            {
                await destination.WriteAsync(item, cancellationToken).ConfigureAwait(false);
            }
            if (markComplete) destination.TryComplete();
        }

        static readonly Action<Exception, object> s_ReaderCompleted = (ex, state) =>
        {
            var typed = (TaskCompletionSource<object>)state;
            if (ex != null) typed.TrySetException(ex);
            else typed.TrySetResult(null);
        };

        /// <summary>
        /// Send multiple messages over a stream
        /// </summary>
        public static async ValueTask SendAsync<T>(Stream destination, IAsyncEnumerable<T> source, MessagePipeOptions options = default)
        {
            var writer = StreamConnection.GetWriter(destination, options.PipeOptions);
            var tcs = new TaskCompletionSource<object>();

#pragma warning disable CS0618 // this *is* a Pipe; this is fine
            writer.OnReaderCompleted(s_ReaderCompleted, tcs); // attach to detect when the pipe is drained
#pragma warning restore CS0618

            await SendAsync<T>(writer, source, options.Without(MessagePipeFlags.LeaveOpen)).ConfigureAwait(false); // send the data
            await tcs.Task.ConfigureAwait(false); // wait for the pipe to drain
            await destination.FlushAsync().ConfigureAwait(false); // flush the stream
        }

        /// <summary>
        /// Send multiple messages over a pipe
        /// </summary>
        public static async ValueTask SendAsync<T>(PipeWriter destination, IAsyncEnumerable<T> source, MessagePipeOptions options = default)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));

            options = options.Normalize();
            await foreach (var message in source.WithCancellation(options.CancellationToken).ConfigureAwait(false))
            {
                options.OnLog("SendAsync writing...");
                options.Write(destination, message);
                options.OnLog("SendAsync flushing...");
                CheckFlushResult(await destination.FlushAsync(options.CancellationToken).ConfigureAwait(false));
                options.OnLog("SendAsync flushed");
            }
            if (options.MarkComplete) await destination.CompleteAsync().ConfigureAwait(false);
        }

        /// <summary>
        /// Send multiple messages over a stream
        /// </summary>
        public static ValueTask SendAsync<T>(Stream destination, ChannelReader<T> source, MessagePipeOptions options = default)
            => SendAsync<T>(destination, AsAsyncEnumerable<T>(source, options.CancellationToken), options);

        /// <summary>
        /// Send multiple messages over a pipe
        /// </summary>
        public static ValueTask SendAsync<T>(PipeWriter destination, ChannelReader<T> source, MessagePipeOptions options = default)
            => SendAsync<T>(destination, AsAsyncEnumerable<T>(source, options.CancellationToken), options);

        static void CheckFlushResult(FlushResult flush)
        {
            if (flush.IsCompleted) ThrowOutputCompletedWithOutstandingMessages();
            if (flush.IsCanceled) ThrowCancelled();
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void ThrowOutputCompletedWithOutstandingMessages() => throw new EndOfStreamException("The output writer was completed, but there were outstanding messages to send");

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void ThrowCancelled() => throw new TaskCanceledException();

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void ThrowInputCompletedWithPartialPayload() => throw new EndOfStreamException("The input reader was completed, but there was an incomplete message in the buffer");

        /// <summary>
        /// Receive multiple messages from a stream
        /// </summary>
        public static IAsyncEnumerable<T> ReceiveAsync<T>(Stream source, MessagePipeOptions options = default)
            => ReceiveAsync<T>(StreamConnection.GetReader(source, options.PipeOptions), options);

        /// <summary>
        /// Receive multiple messages from a stream
        /// </summary>
        public static ValueTask ReceiveAsync<T>(Stream source, ChannelWriter<T> destination, MessagePipeOptions options = default)
            => WriteToChannelAsync(ReceiveAsync<T>(source, options), destination, options.CancellationToken, options.MarkComplete);

        /// <summary>
        /// Receive multiple messages from a pipe
        /// </summary>
        public static ValueTask ReceiveAsync<T>(PipeReader source, ChannelWriter<T> destination, MessagePipeOptions options = default)
            => WriteToChannelAsync(ReceiveAsync<T>(source, options), destination, options.CancellationToken, options.MarkComplete);

        /// <summary>
        /// Receive multiple messages from a pipe
        /// </summary>
        public static async IAsyncEnumerable<T> ReceiveAsync<T>(PipeReader source, MessagePipeOptions options = default)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));
            options = options.Normalize();

            while (true)
            {
                // obtain the next buffer
                options.OnLog("ReceiveAsync obtaining buffer...");
                if (!source.TryRead(out var result)) result = await source.ReadAsync(options.CancellationToken).ConfigureAwait(false);
                if (result.IsCanceled) ThrowCancelled();

                // consume the buffer
                var buffer = result.Buffer;
                options.OnLog($"ReceiveAsync got {buffer.Length} bytes");
                int processed = 0;
                while (options.TryRead<T>(ref buffer, out var item))
                {
                    processed++;
                    yield return item;
                }

                if (processed == 0 && result.IsCompleted) // check for termination
                {
                    // we have everything, and there will never be any more; was it clean?
                    if (!buffer.IsEmpty) ThrowInputCompletedWithPartialPayload();
                    break;
                }

                // mark what we consumed (the "ref buffer" means we've sliced it already)
                source.AdvanceTo(buffer.Start, buffer.End);
            }
            if (options.MarkComplete) await source.CompleteAsync().ConfigureAwait(false);
            options.OnLog("ReceiveAsync completed successfully");
        }

        static Channel<T> CreateChannel<T>(object options)
            => options switch
            {
                BoundedChannelOptions bounded => Channel.CreateBounded<T>(bounded),
                UnboundedChannelOptions unbounded => Channel.CreateUnbounded<T>(unbounded),
                _ => Channel.CreateBounded<T>(16), // reasonable default
            };

        /// <summary>
        /// Create a duplex channel over a pipe
        /// </summary>
        /// <remarks><paramref name="receiveChannelOptions"/> and <paramref name="receiveChannelOptions"/> can be <see cref="BoundedChannelOptions"/> or <see cref="UnboundedChannelOptions"/>, otherwise a default bounded channel is used</remarks>
        public static DuplexChannel<TWrite, TRead> DuplexAsync<TWrite, TRead>(IDuplexPipe transport, MessagePipeOptions options = default,
            object sendChannelOptions = null, object receiveChannelOptions = null)
        {
            var send = CreateChannel<TWrite>(sendChannelOptions);
            var receive = CreateChannel<TRead>(receiveChannelOptions);

            // start the read and write flows
            _ = Task.Run(() => SendAsync(transport.Output, send.Reader, options), options.CancellationToken);
            _ = Task.Run(() => ReceiveAsync(transport.Input, receive.Writer, options), options.CancellationToken);

            return new DuplexChannel<TWrite, TRead>(send, receive
#if DEBUG
                , options.Log
#endif
                );
        }

        /// <summary>
        /// Create a duplex channel over a pipe
        /// </summary>
        /// <remarks><paramref name="receiveChannelOptions"/> and <paramref name="receiveChannelOptions"/> can be <see cref="BoundedChannelOptions"/> or <see cref="UnboundedChannelOptions"/>, otherwise a default bounded channel is used</remarks>
        public static DuplexChannel<TWrite, TRead> DuplexAsync<TWrite, TRead>(Stream transport, MessagePipeOptions options = default,
            object sendChannelOptions = null, object receiveChannelOptions = null)
            => DuplexAsync<TWrite, TRead>(StreamConnection.GetDuplex(transport, options.PipeOptions), options, sendChannelOptions, receiveChannelOptions);
    }
}


<|start_filename|>src/Examples/Issues/Issue218.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;

namespace Examples.Issues
{
    
    public class Issue218
    {
        [ProtoContract]
        public class Test
        {
            [ProtoMember(1)]
            public byte[] BackgroundImageToUpload { get; set; }

            [ProtoMember(2)]
            public string Title { get; set; }
        }
        [Fact]
        public void Execute()
        {

            var typeModel = RuntimeTypeModel.Create();
            typeModel.AutoCompile = true;
            var obj = new Test() {Title = "MyTitle", BackgroundImageToUpload = new byte[0]};

            var clone = (Test)typeModel.DeepClone(obj);
            Assert.NotNull(clone.BackgroundImageToUpload); //, "Runtime");
            Assert.Empty(clone.BackgroundImageToUpload); //, "Runtime");
            Assert.Equal("MyTitle", clone.Title); //, "Runtime");

            typeModel.CompileInPlace();
            clone = (Test)typeModel.DeepClone(obj);
            Assert.NotNull(clone.BackgroundImageToUpload); //, "CompileInPlace");
            Assert.Empty(clone.BackgroundImageToUpload); //, "CompileInPlace");
            Assert.Equal("MyTitle", clone.Title); //, "CompileInPlace");

            clone = (Test)typeModel.Compile().DeepClone(obj);
            Assert.NotNull(clone.BackgroundImageToUpload); //, "Compile");
            Assert.Empty(clone.BackgroundImageToUpload); //, "Compile");
            Assert.Equal("MyTitle", clone.Title); //, "Compile");

        }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/ParseableSerializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;
using System.Reflection;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class ParseableSerializer : IRuntimeProtoSerializerNode
    {
        private readonly MethodInfo parse;
        public static ParseableSerializer TryCreate(Type type)
        {
            if (type is null) throw new ArgumentNullException(nameof(type));
            MethodInfo method = type.GetMethod(nameof(int.Parse),
                BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly,
                null, new Type[] { typeof(string) }, null);
            if (method is object && method.ReturnType == type)
            {
                if (type.IsValueType)
                {
                    MethodInfo toString = GetCustomToString(type);
                    if (toString is null || toString.ReturnType != typeof(string)) return null; // need custom ToString, fools
                }
                return new ParseableSerializer(method);
            }
            return null;
        }
        private static MethodInfo GetCustomToString(Type type)
        {
            return type.GetMethod(nameof(object.ToString), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                        null, Type.EmptyTypes, null);
        }

        private ParseableSerializer(MethodInfo parse)
        {
            this.parse = parse;
        }

        public Type ExpectedType => parse.DeclaringType;

        bool IRuntimeProtoSerializerNode.RequiresOldValue { get { return false; } }
        bool IRuntimeProtoSerializerNode.ReturnsValue { get { return true; } }

        public object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return parse.Invoke(null, new object[] { state.ReadString() });
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteString(value.ToString());
        }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            Type type = ExpectedType;
            using var loc = ctx.GetLocalWithValue(ExpectedType, valueFrom);
            ctx.LoadState();
            ctx.LoadAddress(loc, type);
            if (type.IsValueType)
            {   // note that for structs, we've already asserted that a custom ToString
                // exists; no need to handle the box/callvirt scenario

                // force it to a variable if needed, so we can take the address
                ctx.EmitCall(GetCustomToString(type));
            }
            else
            {
                ctx.EmitCall(typeof(object).GetMethod(nameof(object.ToString)));
            }
            ctx.LoadNullRef(); // map
            ctx.EmitCall(typeof(ProtoWriter.State).GetMethod(nameof(ProtoWriter.State.WriteString), BindingFlags.Instance | BindingFlags.Public,
                null, new[] { typeof(string), typeof(StringMap) }, null));
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            ctx.LoadState();
            ctx.LoadNullRef(); // map
            ctx.EmitCall(typeof(ProtoReader.State).GetMethod(nameof(ProtoReader.State.ReadString), BindingFlags.Instance | BindingFlags.Public,
                null, new[] { typeof(StringMap) }, null));
            ctx.EmitCall(parse);
        }
    }
}

<|start_filename|>src/protobuf-net.BuildTools/Internal/ILoggingAnalyzer.cs<|end_filename|>
﻿#nullable enable
using System;

namespace ProtoBuf.BuildTools.Internal
{
    internal interface ILoggingAnalyzer
    {
        event Action<string>? Log;
    }
}


<|start_filename|>src/protobuf-net.Core/TypeResolver.cs<|end_filename|>
﻿using System;

namespace ProtoBuf
{
    /// <summary>
    /// Maps a field-number to a type
    /// </summary>
    public delegate Type TypeResolver(int fieldNumber);
}


<|start_filename|>src/Examples/Issues/SO6407130.cs<|end_filename|>
﻿using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using System;

namespace Examples.Issues
{
    
    public class SO6407130
    {
        public class A
        {
            public int X { get; private set; }
            public A(int x)
            {
                X = x;
            }

            public static implicit operator ASurrogate(A a)
            {
                return a == null ? null : new ASurrogate { X = a.X };
            }
            public static implicit operator A(ASurrogate a)
            {
                return a == null ? null : new A(a.X);
            }
        }

        [ProtoContract]
        public abstract class ASurrogateBase
        {
            public abstract int X { get; set; }

            [OnDeserializing]
            public virtual void OnDeserializing(StreamingContext context) { }

            [OnDeserialized]
            public virtual void OnDeserialized(StreamingContext context) { }
            [OnSerializing]
            public virtual void OnSerializing(StreamingContext context) { }

            [OnSerialized]
            public virtual void OnSerialized(StreamingContext context) { }
        }

        [ProtoContract]
        public class ASurrogate : ASurrogateBase
        {
            [ThreadStatic] // just in case...
#pragma warning disable CA2211 // Non-constant fields should not be visible
            public static int HackyFlags;
#pragma warning restore CA2211 // Non-constant fields should not be visible
            
            public override void OnDeserializing(StreamingContext context)
            {
                HackyFlags |= 1;
            }

            
            public override void OnDeserialized(StreamingContext context)
            {
                HackyFlags |= 2;
            }
            
            public override void OnSerializing(StreamingContext context)
            {
                HackyFlags |= 4;
            }

            
            public override void OnSerialized(StreamingContext context)
            {
                HackyFlags |= 8;
            }
            [ProtoMember(1)]
            public override int X { get; set; }
        }

        [ProtoContract]
        public class B
        {
            [ProtoMember(1)]
            public A A { get; set; }
        }
        [Fact]
        public void Execute()
        {
            var ex = Assert.Throws<InvalidOperationException>(() =>
            {
                var m = RuntimeTypeModel.Create();
                m.AutoCompile = false;
                m.Add(typeof(ASurrogateBase), true).AddSubType(1, typeof(ASurrogate));
                m.Add(typeof(A), false).SetSurrogate(typeof(ASurrogate));

                TestModel(m, "Runtime");

                m.CompileInPlace();
                TestModel(m, "CompileInPlace");

                TestModel(m.Compile(), "Compile");

                var compiled = m.Compile("SO6407130", "SO6407130.dll");
                PEVerify.AssertValid("SO6407130.dll");
                TestModel(compiled, "Compiled-dll");
            });
            Assert.Equal("Types with surrogates cannot be used in inheritance hierarchies: Examples.Issues.SO6407130+ASurrogate", ex.Message);
        }
#pragma warning disable IDE0060
        static void TestModel(TypeModel model, string caption)
#pragma warning restore IDE0060
        {
            var b = new B { A = new A(117) };
            ASurrogate.HackyFlags = 0;
            using var ms = new MemoryStream();
            model.Serialize(ms, b);
            Assert.Equal(12, ASurrogate.HackyFlags); //, caption);

            ms.Position = 0;
            ASurrogate.HackyFlags = 0;
#pragma warning disable CS0618
            var b2 = (B)model.Deserialize(ms, null, typeof(B));
#pragma warning restore CS0618
            Assert.Equal(3, ASurrogate.HackyFlags); //, caption);
            Assert.Equal(117, b2.A.X); //, caption);
        }
    }
}


<|start_filename|>src/NativeGoogleTests/Date.cs<|end_filename|>
// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: google/type/date.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Type {

  /// <summary>Holder for reflection information generated from google/type/date.proto</summary>
  public static partial class DateReflection {

    #region Descriptor
    /// <summary>File descriptor for google/type/date.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static DateReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "<KEY>",
            "<KEY>",
            "<KEY>",
            "<KEY>",
            "<KEY>));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Type.Date), global::Google.Type.Date.Parser, new[]{ "Year", "Month", "Day" }, null, null, null, null)
          }));
    }
    #endregion

  }
  #region Messages
  /// <summary>
  /// Represents a whole or partial calendar date, e.g. a birthday. The time of day
  /// and time zone are either specified elsewhere or are not significant. The date
  /// is relative to the Proleptic Gregorian Calendar. This can represent:
  ///
  /// * A full date, with non-zero year, month and day values
  /// * A month and day value, with a zero year, e.g. an anniversary
  /// * A year on its own, with zero month and day values
  /// * A year and month value, with a zero day, e.g. a credit card expiration date
  ///
  /// Related types are [google.type.TimeOfDay][google.type.TimeOfDay] and `google.protobuf.Timestamp`.
  /// </summary>
  public sealed partial class Date : pb::IMessage<Date>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<Date> _parser = new pb::MessageParser<Date>(() => new Date());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<Date> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Type.DateReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Date() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Date(Date other) : this() {
      year_ = other.year_;
      month_ = other.month_;
      day_ = other.day_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Date Clone() {
      return new Date(this);
    }

    /// <summary>Field number for the "year" field.</summary>
    public const int YearFieldNumber = 1;
    private int year_;
    /// <summary>
    /// Year of date. Must be from 1 to 9999, or 0 if specifying a date without
    /// a year.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Year {
      get { return year_; }
      set {
        year_ = value;
      }
    }

    /// <summary>Field number for the "month" field.</summary>
    public const int MonthFieldNumber = 2;
    private int month_;
    /// <summary>
    /// Month of year. Must be from 1 to 12, or 0 if specifying a year without a
    /// month and day.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Month {
      get { return month_; }
      set {
        month_ = value;
      }
    }

    /// <summary>Field number for the "day" field.</summary>
    public const int DayFieldNumber = 3;
    private int day_;
    /// <summary>
    /// Day of month. Must be from 1 to 31 and valid for the year and month, or 0
    /// if specifying a year by itself or a year and month where the day is not
    /// significant.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Day {
      get { return day_; }
      set {
        day_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as Date);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(Date other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Year != other.Year) return false;
      if (Month != other.Month) return false;
      if (Day != other.Day) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Year != 0) hash ^= Year.GetHashCode();
      if (Month != 0) hash ^= Month.GetHashCode();
      if (Day != 0) hash ^= Day.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (Year != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(Year);
      }
      if (Month != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(Month);
      }
      if (Day != 0) {
        output.WriteRawTag(24);
        output.WriteInt32(Day);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (Year != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(Year);
      }
      if (Month != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(Month);
      }
      if (Day != 0) {
        output.WriteRawTag(24);
        output.WriteInt32(Day);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Year != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Year);
      }
      if (Month != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Month);
      }
      if (Day != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Day);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(Date other) {
      if (other == null) {
        return;
      }
      if (other.Year != 0) {
        Year = other.Year;
      }
      if (other.Month != 0) {
        Month = other.Month;
      }
      if (other.Day != 0) {
        Day = other.Day;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 8: {
            Year = input.ReadInt32();
            break;
          }
          case 16: {
            Month = input.ReadInt32();
            break;
          }
          case 24: {
            Day = input.ReadInt32();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 8: {
            Year = input.ReadInt32();
            break;
          }
          case 16: {
            Month = input.ReadInt32();
            break;
          }
          case 24: {
            Day = input.ReadInt32();
            break;
          }
        }
      }
    }
    #endif

  }

  #endregion

}

#endregion Designer generated code


<|start_filename|>assorted/precompile/Program.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using ProtoBuf.Meta;

namespace ProtoBuf.Precompile
{
    class Program
    {
        static int Main(string[] args)
        {
            try
            {
                Console.WriteLine("protobuf-net pre-compiler");
                PreCompileContext ctx;
                if (!CommandLineAttribute.TryParse(args, out ctx))
                {
                    return -1;
                }

                if (ctx.Help)
                {
                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine(ctx.GetUsage());
                    return -1;
                }
                if (!ctx.SanityCheck()) return -1;

                bool allGood = ctx.Execute();
                return allGood ? 0 : -1;
            }
            catch (Exception ex)
            {
                while (ex != null)
                {
                    Console.Error.WriteLine(ex.Message);
                    Console.Error.WriteLine(ex.StackTrace);
                    Console.Error.WriteLine();
                    ex = ex.InnerException;
                }
                return -1;
            }
        }
    }

    /// <summary>
    /// Defines the rules for a precompilation operation
    /// </summary>
    public class PreCompileContext
    {
        /// <summary>
        /// The target framework to use
        /// </summary>
        [CommandLine("f"), CommandLine("framework")]
        public string Framework { get; set; }

        private readonly List<string> probePaths = new List<string>();

        /// <summary>
        /// Locations to check for referenced assemblies
        /// </summary>
        [CommandLine("p"), CommandLine("probe")]
        public List<string> ProbePaths { get { return probePaths; } }

        private readonly List<string> inputs = new List<string>();
        /// <summary>
        /// The paths for assemblies to process
        /// </summary>
        [CommandLine("")]
        public List<string> Inputs { get { return inputs; } }

        /// <summary>
        /// The type name of the serializer to generate
        /// </summary>
        [CommandLine("t"), CommandLine("type")]
        public string TypeName { get; set; }

        /// <summary>
        /// The name of the assembly to generate
        /// </summary>
        [CommandLine("o"), CommandLine("out")]
        public string AssemblyName { get; set; }

        /// <summary>
        /// Show help
        /// </summary>
        [CommandLine("?"), CommandLine("help"), CommandLine("h")]
        public bool Help { get; set; }

        /// <summary>
        /// The accessibility of the generated type
        /// </summary>
        [CommandLine("access")]
        public ProtoBuf.Meta.RuntimeTypeModel.Accessibility Accessibility { get; set; }

        /// <summary>
        /// The path to the file to use to sign the assembly
        /// </summary>
        [CommandLine("keyfile")]
        public string KeyFile { get; set; }
        /// <summary>
        /// The container to use to sign the assembly
        /// </summary>
        [CommandLine("keycontainer")]
        public string KeyContainer { get; set; }
        /// <summary>
        /// The public key (in hexadecimal) to use to sign the assembly
        /// </summary>
        [CommandLine("publickey")]
        public string PublicKey { get; set; }

        /// <summary>
        /// Create a new instance of PreCompileContext
        /// </summary>
        public PreCompileContext()
        {
            Accessibility = ProtoBuf.Meta.RuntimeTypeModel.Accessibility.Public;
        }

        static string TryInferFramework(string path)
        {
            string imageRuntimeVersion = null;
            try
            {
                using (var uni = new IKVM.Reflection.Universe())
                {
                    uni.AssemblyResolve += (s, a) => ((IKVM.Reflection.Universe)s).CreateMissingAssembly(a.Name);
                    var asm = uni.LoadFile(path);
                    imageRuntimeVersion = asm.ImageRuntimeVersion;

                    var attr = uni.GetType("System.Attribute, mscorlib");

                    foreach(var attrib in asm.__GetCustomAttributes(attr, false))
                    {
                        if (attrib.Constructor.DeclaringType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute"
                            && attrib.ConstructorArguments.Count == 1)
                        {
                            var parts = ((string)attrib.ConstructorArguments[0].Value).Split(',');
                            string runtime = null, version = null, profile = null;
                            for (int i = 0; i < parts.Length; i++)
                            {
                                int idx = parts[i].IndexOf('=');
                                if (idx < 0)
                                {
                                    runtime = parts[i];
                                } else
                                {
                                    switch(parts[i].Substring(0,idx))
                                    {
                                        case "Version":
                                            version = parts[i].Substring(idx + 1);
                                            break;
                                        case "Profile":
                                            profile = parts[i].Substring(idx + 1);
                                            break;
                                    }
                                }
                            }
                            if(runtime != null)
                            {
                                var sb = new StringBuilder(runtime);
                                if(version != null)
                                {
                                    sb.Append(Path.DirectorySeparatorChar).Append(version);
                                }
                                if (profile != null)
                                {
                                    sb.Append(Path.DirectorySeparatorChar).Append("Profile").Append(Path.DirectorySeparatorChar).Append(profile);
                                }
                                string targetFramework = sb.ToString();
                                return targetFramework;
                            }
                        }
                    }
                }
            }
            catch (Exception ex) {
                // not really fussed; we could have multiple inputs to try, and the user
                // can always use -f:blah to specify it explicitly
                Debug.WriteLine(ex.Message);
            }

            if (!string.IsNullOrEmpty(imageRuntimeVersion))
            {
                string frameworkPath = Path.Combine(
                    Environment.ExpandEnvironmentVariables(@"%windir%\Microsoft.NET\Framework"),
                    imageRuntimeVersion);
                if (Directory.Exists(frameworkPath)) return frameworkPath;
            }

            return null;
        }
        /// <summary>
        /// Check the context for obvious errrs
        /// </summary>
        public bool SanityCheck()
        {
            bool allGood = true;
            if (inputs.Count == 0)
            {
                Console.Error.WriteLine("No input assemblies");
                allGood = false;
            }
            if (string.IsNullOrEmpty(TypeName))
            {
                Console.Error.WriteLine("No serializer type-name specified");
                allGood = false;
            }
            if (string.IsNullOrEmpty(AssemblyName))
            {
                Console.Error.WriteLine("No output assembly file specified");
                allGood = false;
            }

            if (string.IsNullOrEmpty(Framework))
            {
                foreach (var inp in inputs)
                {
                    string tmp = TryInferFramework(inp);
                    if (tmp != null)
                    {
                        Console.WriteLine("Detected framework: " + tmp);
                        Framework = tmp;
                        break;
                    }
                }
                
            }
            if (string.IsNullOrEmpty(Framework))
            {
                Console.WriteLine("No framework specified; defaulting to " + Environment.Version);
                probePaths.Add(Path.GetDirectoryName(typeof(string).Assembly.Location));
            }
            else
            {
                if (Directory.Exists(Framework))
                { // very clear and explicit
                    probePaths.Add(Framework);
                }
                else
                {
                    string root = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
                    if (string.IsNullOrEmpty(root)) root = Environment.GetEnvironmentVariable("ProgramFiles");
                    root = Path.Combine(root, @"Reference Assemblies\Microsoft\Framework\");
                    if (!Directory.Exists(root))
                    {
                        Console.Error.WriteLine("Framework reference assemblies root folder could not be found");
                        allGood = false;
                    }
                    else
                    {
                        string frameworkRoot = Path.Combine(root, Framework);
                        if (Directory.Exists(frameworkRoot))
                        {
                            // fine
                            probePaths.Add(frameworkRoot);
                        }
                        else
                        {
                            Console.Error.WriteLine("Framework not found: " + Framework);
                            Console.Error.WriteLine("Available frameworks are:");
                            string[] files = Directory.GetFiles(root, "mscorlib.dll", SearchOption.AllDirectories);
                            foreach (var file in files)
                            {
                                string dir = Path.GetDirectoryName(file);
                                if (dir.StartsWith(root)) dir = dir.Substring(root.Length);
                                Console.Error.WriteLine(dir);
                            }
                            allGood = false;
                        }
                    }
                }
            }
            if (!string.IsNullOrEmpty(KeyFile) && !File.Exists(KeyFile))
            {
                Console.Error.WriteLine("Key file not found: " + KeyFile);
                allGood = false;
            }

            foreach (var inp in inputs)
            {
                if(File.Exists(inp)) {
                    string dir = Path.GetDirectoryName(inp);
                    if(!probePaths.Contains(dir)) probePaths.Add(dir);
                }
                else
                {
                    Console.Error.WriteLine("Input not found: " + inp);
                    allGood = false;
                }                
            }
            return allGood;
        }

        IEnumerable<string> ProbeForFiles(string file)
        {
            foreach (var probePath in probePaths)
            {
                string combined = Path.Combine(probePath, file);
                if (File.Exists(combined))
                {
                    yield return combined;
                }
            }
        }
        /// <summary>
        /// Perform the precompilation operation
        /// </summary>
        public bool Execute()
        {
            // model to work with
            var model = TypeModel.Create();

            model.Universe.AssemblyResolve += (sender, args) =>
            {
                string nameOnly = args.Name.Split(',')[0];

                if (nameOnly == "IKVM.Reflection" && args.RequestingAssembly != null && args.RequestingAssembly.FullName.StartsWith("protobuf-net"))
                {
                    throw new InvalidOperationException("This operation needs access to the protobuf-net.dll used by your library, **in addition to** the protobuf-net.dll that is included with the precompiler; the easiest way to do this is to ensure the referenced protobuf-net.dll is in the same folder as your library.");
                }
                var uni = model.Universe;
                foreach (var tmp in uni.GetAssemblies())
                {
                    if (tmp.GetName().Name == nameOnly) return tmp;
                }
                var asm = ResolveNewAssembly(uni, nameOnly + ".dll");
                if(asm != null) return asm;
                asm = ResolveNewAssembly(uni, nameOnly + ".exe");
                if(asm != null) return asm;

                throw new InvalidOperationException("All assemblies must be resolved explicity; did not resolve: " + args.Name);
            };
            bool allGood = true;
            var mscorlib = ResolveNewAssembly(model.Universe, "mscorlib.dll");
            if (mscorlib == null)
            {
                Console.Error.WriteLine("mscorlib.dll not found!");
                allGood = false;
            }
            ResolveNewAssembly(model.Universe, "System.dll"); // not so worried about whether that one exists...
            if (ResolveNewAssembly(model.Universe, "protobuf-net.dll") == null)
            {
                Console.Error.WriteLine("protobuf-net.dll not found!");
                allGood = false;
            }
            if (!allGood) return false;
            var assemblies = new List<IKVM.Reflection.Assembly>();
            MetaType metaType = null;
            foreach (var file in inputs)
            {
                assemblies.Add(model.Load(file));
            }
            // scan for obvious protobuf types
            var attributeType = model.Universe.GetType("System.Attribute, mscorlib");
            var toAdd = new List<IKVM.Reflection.Type>();
            foreach (var asm in assemblies)
            {
                foreach (var type in asm.GetTypes())
                {
                    bool add = false;
                    if (!(type.IsClass || type.IsValueType)) continue;

                    foreach (var attrib in type.__GetCustomAttributes(attributeType, true))
                    {
                        string name = attrib.Constructor.DeclaringType.FullName;
                        switch(name) 
                        {
                            case "ProtoBuf.ProtoContractAttribute":
                                add = true;
                                break;
                        }
                        if (add) break;
                    }
                    if (add) toAdd.Add(type);
                }
            }

            if (toAdd.Count == 0)
            {
                Console.Error.WriteLine("No [ProtoContract] types found; nothing to do!");
                return false;
            }

            // add everything we explicitly know about
            toAdd.Sort((x, y) => string.Compare(x.FullName, y.FullName));            
            foreach (var type in toAdd)
            {
                Console.WriteLine("Adding " + type.FullName + "...");
                var tmp = model.Add(type, true);
                if (metaType == null) metaType = tmp; // use this as the template for the framework version
            }
            // add everything else we can find
            model.Cascade();
            var inferred = new List<IKVM.Reflection.Type>();
            foreach (MetaType type in model.GetTypes())
            {
                if(!toAdd.Contains(type.Type)) inferred.Add(type.Type);
            }
            inferred.Sort((x, y) => string.Compare(x.FullName, y.FullName));
            foreach (var type in inferred)
            {
                Console.WriteLine("Adding " + type.FullName + "...");
            }

            
            // configure the output file/serializer name, and borrow the framework particulars from
            // the type we loaded
            var options = new RuntimeTypeModel.CompilerOptions
            {
                TypeName = TypeName,
                OutputPath = AssemblyName,
                ImageRuntimeVersion = mscorlib.ImageRuntimeVersion,
                MetaDataVersion = 0x20000, // use .NET 2 onwards
                KeyContainer = KeyContainer,
                KeyFile = KeyFile,
                PublicKey = PublicKey
            };
            if (mscorlib.ImageRuntimeVersion == "v1.1.4322")
            { // .NET 1.1-style
                options.MetaDataVersion = 0x10000;
            }
            if (metaType != null)
            {
                options.SetFrameworkOptions(metaType);
            }
            options.Accessibility = this.Accessibility;
            Console.WriteLine("Compiling " + options.TypeName + " to " + options.OutputPath + "...");
            // GO WORK YOUR MAGIC, CRAZY THING!!
            model.Compile(options);
            Console.WriteLine("All done");

            return true;

        }
        
        private IKVM.Reflection.Assembly ResolveNewAssembly(IKVM.Reflection.Universe uni, string fileName)
        {
            foreach (var match in ProbeForFiles(fileName))
            {
                var asm = uni.LoadFile(match);
                if (asm != null)
                {
                    Console.WriteLine("Resolved " + match);
                    return asm;
                }
            }
            return null;
        }

        /// <summary>
        /// Return the syntax guide for the utility
        /// </summary>
        public string GetUsage()
        {
            return
                @"Generates a serialization dll that can be used with just the
(platform-specific) protobuf-net core, allowing fast and efficient
serialization even on light frameworks (CF, SL, SP7, Metro, etc).

The input assembly(ies) is(are) anaylsed for types decorated with
[ProtoContract]. All such types are added to the model, as are any
types that they require.

Note: the compiler must be able to resolve a protobuf-net.dll
that is suitable for the target framework; this is done most simply
by ensuring that the appropriate protobuf-net.dll is next to the
input assembly.

Options:

    -f[ramework]:<framework>
           Can be an explicit path, or a path relative to:
           Reference Assemblies\Microsoft\Framework
    -o[ut]:<file>
           Output dll path
    -t[ype]:<typename>
           Type name of the serializer to generate
    -p[robe]:<path>
           Additional directory to probe for assemblies
    -access:<access>
           Specify accessibility of generated serializer
           to 'Public' or 'Internal'
    -keyfile:<file>
           Sign with the file (snk, etc) specified
    -keycontainer:<container>
           Sign with the container specified
    -publickey:<key>
           Sign with the public key specified (as hex)
    <file>
           Input file to analyse

Example:

    precompile -f:.NETCore\v4.5 MyDtos\My.dll -o:MySerializer.dll
        -t:MySerializer";
        }
    }
    /// <summary>
    /// Defines a mapping from command-line attributes to properties
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class CommandLineAttribute : Attribute
    {
        /// <summary>
        /// Attempt to parse the incoming command-line switches, matching by prefix
        /// onto properties of the specified type
        /// </summary>
        public static bool TryParse<T>(string[] args, out T result) where T : class, new()
        {
            result = new T();
            bool allGood = true;
            var props = typeof(T).GetProperties();

            char[] leadChars = {'/', '+', '-'};
            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i].Trim(), prefix, value;
                if(arg.IndexOfAny(leadChars) == 0)
                {
                    int idx = arg.IndexOf(':');
                    if (idx < 0)
                    {
                        prefix = arg.Substring(1);
                        value = "";
                    }
                    else
                    {
                        prefix = arg.Substring(1,idx - 1);
                        value = arg.Substring(idx + 1);
                    }    
                }
                else
                {
                    prefix = "";
                    value = arg;
                }
                
                System.Reflection.PropertyInfo foundProp = null;

                foreach (var prop in props)
                {
                    foreach (CommandLineAttribute atttib in prop.GetCustomAttributes(typeof(CommandLineAttribute), true))
                    {
                        if (atttib.Prefix == prefix)
                        {
                            foundProp = prop;
                            break;
                        }
                    }
                    if (foundProp != null) break;
                }

                if (foundProp == null)
                {
                    allGood = false;
                    Console.Error.WriteLine("Argument not understood: " + arg);
                }
                else
                {
                    if (foundProp.PropertyType == typeof(string))
                    {
                        foundProp.SetValue(result, value, null);
                    }
                    else if (foundProp.PropertyType == typeof(List<string>))
                    {
                        ((List<string>)foundProp.GetValue(result, null)).Add(value);
                    }
                    else if (foundProp.PropertyType == typeof(bool))
                    {
                        foundProp.SetValue(result, true, null);
                    }
                    else if (foundProp.PropertyType.IsEnum)
                    {
                        object parsedValue;
                        try {
                            parsedValue = Enum.Parse(foundProp.PropertyType, value, true); 
                        } catch {
                            Console.Error.WriteLine("Invalid option for: " + arg);
                            Console.Error.WriteLine("Options: " + string.Join(", ", Enum.GetNames(foundProp.PropertyType)));
                            allGood = false;
                            parsedValue = null;
                        }
                        if (parsedValue != null) foundProp.SetValue(result, parsedValue, null);
                    }
                }
            }

            return allGood;
        }
        private readonly string prefix;
        /// <summary>
        /// Create a new CommandLineAttribute object for the given prefix
        /// </summary>
        public CommandLineAttribute(string prefix) { this.prefix = prefix; }
        /// <summary>
        /// The prefix to recognise this command-line switch
        /// </summary>
        public string Prefix { get { return prefix; } }
    }

}


<|start_filename|>src/protobuf-net.Reflection.Test/Parsers.cs<|end_filename|>
﻿using Google.Protobuf.Reflection;
using System.IO;
using Xunit;

namespace ProtoBuf
{
    public class Parsers
    {
        [Fact]
        public void EmbeddedImportsWork()
        {
            
            var set = new FileDescriptorSet();
            using (var file = File.OpenText("basic.proto"))
            {
                Assert.True(set.Add("basic.proto", true, file));
            }
            set.Process();
            var err = set.GetErrors();
            Assert.Empty(err);
        }

        [Fact]
        public void BuildTypeHierarchyForServices()
        {

            var set = new FileDescriptorSet();
            using (var file = File.OpenText("basic_service.proto"))
            {
                Assert.True(set.Add("basic_service.proto", true, file));
            }
            set.Process();
            var err = set.GetErrors();
            Assert.Empty(err);

            Assert.Equal(".HelloWorld.HelloService", set.Files[0].Services[0].FullyQualifiedName);
            Assert.Equal(".HelloWorld.HelloService.SayHello", set.Files[0].Services[0].Methods[0].FullyQualifiedName);
        }
    }
}


<|start_filename|>src/Examples/Arrays.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.IO;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using System.Linq;
using Xunit.Abstractions;

namespace Examples
{
    [ProtoContract]
    class Node
    {
        [ProtoMember(1)]
        public int Key { get; set; }

        [ProtoMember(2)]
        public Node[] Nodes { get; set; }
    }

    [ProtoContract]
    class Prim
    {
        [ProtoMember(1)]
        public string[] Values { get; set; }
    }

    [ProtoContract]
    class ArrayArray
    {
        [ProtoMember(1)]
        public string[][] Values { get; set; }
    }

    [ProtoContract]
    class ArrayList
    {
        [ProtoMember(1)]
        public List<string>[] Values { get; set; }
    }
    [ProtoContract]
    class ListArray
    {
        [ProtoMember(1)]
        public List<string[]> Values { get; set; }
    }
    [ProtoContract]
    class ListList
    {
        [ProtoMember(1)]
        public List<List<string>> Values { get; set; }
    }

    [ProtoContract]
    class MultiDim
    {
        [ProtoMember(1)]
        public int[,] Values { get; set; }
    }

    [ProtoContract(SkipConstructor=false)]
    public class WithAndWithoutOverwrite
    {
        [ProtoMember(1, OverwriteList=false)]
        public int[] Append = { 1, 2, 3 };

        [ProtoMember(2, OverwriteList=true)]
        public int[] Overwrite = { 4, 5, 6 };
    }
    [ProtoContract(SkipConstructor=true)]
    public class WithSkipConstructor
    {
        [ProtoMember(1)]
        public int[] Values = { 1, 2, 3 };
    }

    
    public class ArrayTests
    {
        private ITestOutputHelper Log { get; }
        public ArrayTests(ITestOutputHelper _log) => Log = _log;

        [ProtoContract]
        class Foo { }
        [Fact]
        public void DeserializeNakedArray()
        {
            var arr = new Foo[0];
            var model = RuntimeTypeModel.Create();
            Foo[] foo = (Foo[])model.DeepClone(arr);
            Assert.Empty(foo);
        }

        [Fact]
        public void DeserializeBusyArray_Untyped()
        {
            var arr = new Foo[3] { new Foo(), new Foo(), new Foo() };
            var model = RuntimeTypeModel.Create();
            Foo[] foo = (Foo[])model.DeepClone((object)arr);
            Assert.Equal(3, foo.Length);
        }

        [Fact]
        public void DeserializeBusyArray_Typed()
        {
            var arr = new Foo[3] { new Foo(), new Foo(), new Foo() };
            var model = RuntimeTypeModel.Create();
            Foo[] foo = (Foo[])model.DeepClone<Foo[]>(arr);
            Assert.Equal(3, foo.Length);
        }

        [Fact]
        public void PEVerifyWithAndWithoutOverwrite()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(WithAndWithoutOverwrite));
            model.Compile("PEVerifyWithAndWithoutOverwrite", "PEVerifyWithAndWithoutOverwrite.dll");
            PEVerify.AssertValid("PEVerifyWithAndWithoutOverwrite.dll");
        }

        [Fact]
        public void TestOverwriteVersusAppend()
        {
            var orig = new WithAndWithoutOverwrite { Append = new[] {7,8}, Overwrite = new[] { 9,10}};
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            model.Add(typeof(WithAndWithoutOverwrite), true);

            var clone = (WithAndWithoutOverwrite)model.DeepClone(orig);
            Assert.True(clone.Overwrite.SequenceEqual(new[] { 9, 10 }), "Overwrite, Runtime");
            Assert.True(clone.Append.SequenceEqual(new[] { 1, 2, 3, 7, 8 }), "Append, Runtime");

            model.CompileInPlace();
            clone = (WithAndWithoutOverwrite)model.DeepClone(orig);
            Assert.True(clone.Overwrite.SequenceEqual(new[] { 9, 10 }), "Overwrite, CompileInPlace");
            Assert.True(clone.Append.SequenceEqual(new[] { 1, 2, 3, 7, 8 }), "Append, CompileInPlace");

            clone = (WithAndWithoutOverwrite)model.Compile("TestOverwriteVersusAppendTypeModel", "TestOverwriteVersusAppend.dll").DeepClone(orig);
            Assert.True(clone.Overwrite.SequenceEqual(new[] { 9, 10 }), "Overwrite, CompileToFile");
            Assert.True(clone.Append.SequenceEqual(new[] { 1, 2, 3, 7, 8 }), "Append, CompileToFile");

            clone = (WithAndWithoutOverwrite)(model.Compile()).DeepClone(orig);
            Assert.True(clone.Overwrite.SequenceEqual(new[] { 9, 10 }), "Overwrite, Compile");
            Assert.True(clone.Append.SequenceEqual(new[] { 1, 2, 3, 7, 8 }), "Append, Compile");
        }

        [Fact]
        public void TestDirectSkipConstructor()
        {
            var obj = new SkipCtorType();
            Assert.Equal(42, obj.Value);

            obj = (SkipCtorType)BclHelpers.GetUninitializedObject(typeof(SkipCtorType));
            Assert.Equal(0, obj.Value);
        }
        public class SkipCtorType
        {
            public int Value { get; set; } = 42;
        }

        [Fact]
        public void TestSkipConstructor()
        {
            var orig = new WithSkipConstructor { Values = new[] { 4, 5 } };
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            model.Add(typeof(WithSkipConstructor), true);

            var clone = (WithSkipConstructor)model.DeepClone(orig);
            Assert.True(clone.Values.SequenceEqual(new[] { 4, 5 }), "Runtime");

            model.CompileInPlace();
            clone = (WithSkipConstructor)model.DeepClone(orig);
            Assert.True(clone.Values.SequenceEqual(new[] { 4, 5 }), "CompileInPlace");

            clone = (WithSkipConstructor)(model.Compile()).DeepClone(orig);
            Assert.True(clone.Values.SequenceEqual(new[] { 4, 5 }), "Compile");
        }

        [Fact]
        public void TestPrimativeArray()
        {
            Prim p = new Prim { Values = new[] { "abc", "def", "ghi", "jkl" } },
                clone = Serializer.DeepClone(p);

            string[] oldArr = p.Values, newArr = clone.Values;
            Assert.Equal(oldArr.Length, newArr.Length);
            for (int i = 0; i < oldArr.Length; i++)
            {
                Assert.Equal(oldArr[i], newArr[i]); //, "Item " + i.ToString());
            }
        }

        [Fact]
        public void TestMultidimArray()
        {
            Assert.Throws<NotSupportedException>(() =>
            {
                MultiDim md = new MultiDim { Values = new int[1, 2] { { 3, 4 } } };
                Serializer.DeepClone(md);
            });
        }

        [Fact]
        public void TestArrayArray()
        {
            Assert.Throws<NotSupportedException>(() =>
            {
                Serializer.DeepClone(new ArrayArray { Values = new string[1][] });
            });
        }
        [Fact]
        public void TestArrayList()
        {
            Assert.Throws<NotSupportedException>(() =>
            {
                Serializer.DeepClone(new ArrayList());
            });
        }
        [Fact]
        public void TestListArray()
        {
            Assert.Throws<NotSupportedException>(() =>
            {
                Serializer.DeepClone(new ListArray());
            });
        }
        [Fact]
        public void TestListList()
        {
            Assert.Throws<NotSupportedException>(() => {
                Serializer.DeepClone(new ListList());
            });
        }


        [Fact]
        public void TestObjectArray()
        {
            Node node = new Node
            {
                Key = 27,
                Nodes = new[] {
                    new Node { Key = 1 },
                    new Node { Key = 3 } }
            };
            VerifyNodeTree(node);
        }

#pragma warning disable xUnit1004 // Test methods should not be skipped
        [Fact(Skip = "known variation")]
#pragma warning restore xUnit1004 // Test methods should not be skipped
        public void TestEmptyArray()
        {
            Node node = new Node
            {
                Key = 27,
                Nodes = new Node[0]
            };
            VerifyNodeTree(node);
        }

        [Fact]
        public void TestNullArray()
        {
            Node node = new Node
            {
                Key = 27,
                Nodes = null
            };
            VerifyNodeTree(node);
        }

        [Fact]
        public void TestDuplicateNonRecursive()
        {
            Node child = new Node { Key = 17 };
            Node parent = new Node { Nodes = new[] { child, child, child } };
            VerifyNodeTree(parent);
        }

        [Fact]
        public void TestDuplicateRecursive()
        {
            Assert.Throws<ProtoException>(() =>
            {
                Node child = new Node { Key = 17 };
                Node parent = new Node { Nodes = new[] { child, child, child } };
                child.Nodes = new[] { parent };
                VerifyNodeTree(parent);
            });
        }

        [Fact]
        public void TestNestedArray()
        {
            Node node = new Node
            {
                Key = 27,
                Nodes = new[] {
                    new Node {
                        Key = 19,
                        Nodes = new[] {
                            new Node {Key = 1},
                            new Node {Key = 14},
                        },
                    },
                    new Node {
                        Key = 3
                    },
                    new Node {
                        Key = 3,
                        Nodes = new[] {
                            new Node {Key = 234}
                        }
                    }
                }
            };
            VerifyNodeTree(node);
        }

        [Fact]
        public void TestStringArray()
        {
            var foo = new List<string> { "abc", "def", "ghi" };

            using var ms = new MemoryStream();
            Serializer.Serialize(ms, foo);
            var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
            Assert.Equal("0A-03-61-62-63-0A-03-64-65-66-0A-03-67-68-69", hex);
            ms.Position = 0;
            var clone = (List<string>)Serializer.Deserialize(foo.GetType(), ms);
            Assert.Equal(3, clone.Count);

            clone = Serializer.DeepClone(foo);
            Assert.Equal(3, clone.Count);
        }

        [ProtoContract]
        internal class Tst
        {
            [ProtoMember(1)]
            public int ValInt
            {
                get;
                set;
            }

            [ProtoMember(2)]
            public byte[] ArrayData
            {
                get;
                set;
            }

            [ProtoMember(3)]
            public string Str1
            {
                get;
                set;
            }
        }
        [Fact]
        public void TestEmptyArrays()
        {
            Tst t = new Tst();
            t.ValInt = 128;
            t.Str1 = "SOme string text value ttt";
            t.ArrayData = new byte[] { };

            MemoryStream stm = new MemoryStream();
            Serializer.Serialize(stm, t);
            Log.WriteLine(stm.Length.ToString());
        }
        static void VerifyNodeTree(Node node) {
            Node clone = Serializer.DeepClone(node);
            bool eq = AreEqual(node, clone, out string msg);
            Assert.True(eq, msg);
        }

        static bool AreEqual(Node x, Node y, out string msg)
        {
            // compare core
            if (ReferenceEquals(x, y)) { msg = ""; return true; }
            if (x == null || y == null) { msg = "1 node null"; return false; }
            if (x.Key != y.Key) { msg = "key"; return false; }

            Node[] xNodes = x.Nodes, yNodes = y.Nodes;
            if (ReferenceEquals(xNodes,yNodes))
            { // trivial
            }
            else
            {
                if (xNodes == null || yNodes == null) { msg = "1 Nodes null"; return false; }
                if (xNodes.Length != yNodes.Length) { msg = "Nodes length"; return false; }
                for (int i = 0; i < xNodes.Length; i++)
                {
                    bool eq = AreEqual(xNodes[i], yNodes[i], out msg);
                    if (!eq)
                    {
                        msg = i.ToString() + "; " + msg;
                        return false;
                    }
                }
            }
            // run out of things to be different!
            msg = "";
            return true;

        }
    }
}


<|start_filename|>src/protobuf-net.ServiceModel/Properties/AssemblyInfo.cs<|end_filename|>
﻿
using System.Runtime.CompilerServices;

#if PLAT_SKIP_LOCALS_INIT
[module: SkipLocalsInit]
#endif

<|start_filename|>src/Examples/Issues/Issue304.cs<|end_filename|>
﻿using System.ComponentModel;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;

namespace Examples.Issues
{

    public class Issue304
    {
        [Fact]
        public void DefaultValuesForBoolMustBeLowerCase()
        {
            Assert.Equal(@"syntax = ""proto2"";
package Examples.Issues;

message Foo {
   optional bool Bar = 1 [default = true];
}
",

        Serializer.GetProto<Foo>(ProtoSyntax.Proto2), ignoreLineEndingDifferences: true

        );
        }
        [ProtoContract]
        public class Foo
        {
            [DefaultValue(true), ProtoMember(1)]
            public bool Bar { get; set; }
        }
    }
}


<|start_filename|>assorted/ProtoBufGenerator/ProtoBufTool.cs<|end_filename|>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using VSLangProj;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Text;

namespace ProtoBufGenerator
{
    [ComVisible(true)]
    [DefaultRegistryRoot(@"Software\Microsoft\VisualStudio\9.0")]
    [PackageRegistration(UseManagedResourcesOnly=true, RegisterUsing=RegistrationMethod.CodeBase)]
    [InstalledProductRegistration(false,"#102","#103","1.0", IconResourceID=100)]
    [ProvideLoadKey("Standard", "1.0", "protobuf-net", "<NAME>",101)]
    [Guid("3128D6BC-FF6D-4b39-98F4-681146FD7623")]
    [CustomToolRegistration("ProtoBufTool", typeof(ProtoBufTool), FileExtension=".proto")]
    [ProvideObject(typeof(ProtoBufTool))]
    public class ProtoBufTool : CustomToolBase
    {
        public ProtoBufTool()
        {
            // Listen for generate events
            this.OnGenerateCode += GenerationHandler; 
        }
        static string installPath;
        public static string GetInstallPath(string filename)
        {            
            if (installPath == null)
            {
                installPath = Path.GetDirectoryName(typeof(ProtoBufTool).Assembly.Location);
            }
            return string.IsNullOrEmpty(filename) ? installPath : Path.Combine(installPath, filename);
        }
        const string PBNETDLL = "protobuf-net.dll";

        static string[] GetProtoGenArgs(string inputPath, string outputPath, string language, string namespaceOptions)
        {
            List<string> args = new List<string>();
            switch(language) {
                case ".cs":
                    language = "csharp"; 
                    break;
                default:
                    language = language.TrimStart('.');
                    break;
            }
            args.Add("-writeErrors"); // include error output in outputPath
            args.Add("-i:" + inputPath); // input
            args.Add("-w:" + Path.GetDirectoryName(inputPath)); // working path
            args.Add("-t:" + language); // template
            args.Add("-o:" + outputPath); // output
            args.Add("-q"); // quiet
            string[] parts = namespaceOptions.Split(';');
            if(parts.Length > 0) args.Add("-ns:" + parts[0]); // default namespace
            for(int i = 1 ; i < parts.Length ; i++)
            {
                args.Add("-p:" + parts[i]); // parameter
            }
            return args.ToArray();
        }
        public void GenerationHandler(object s, GenerationEventArgs e)
        {
            // Fail on any error
            e.FailOnError = true;
            
            string tmp = Path.GetTempFileName();
            try
            {
                string[] args = GetProtoGenArgs(e.InputFilePath, tmp, e.OutputFileExtension, e.Namespace);
                bool writeWhatWeDid = true;
                string root = GetInstallPath(null), app = GetInstallPath("protogen.exe");
                if (!File.Exists(app))
                {
                    e.GenerateError("Missing: " + app);
                    return;
                }

                int result;

                ProcessStartInfo psi = new ProcessStartInfo(app);
                psi.CreateNoWindow = true;
                psi.WorkingDirectory = root;
                StringBuilder sb = new StringBuilder();
                foreach (string arg in args)
                {
                    sb.Append("\"" + arg + "\" ");
                }
                psi.Arguments = sb.ToString();
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                using (Process proc = Process.Start(psi))
                {
                    proc.WaitForExit();
                    result = proc.ExitCode;
                }

                /*AppDomain ad = AppDomain.CreateDomain("protogen", null, root, "", false);
                
                try
                {
                    result = ad.ExecuteAssembly(app, null, args);
                    writeWhatWeDid = result != 0;
                }
                finally
                {
                    AppDomain.Unload(ad);
                }*/

                if (writeWhatWeDid)
                {
#if DEBUG2
                    e.GenerateWarning(app);
                    foreach (string arg in args) e.GenerateWarning(arg);
#endif
                }

                using(var lineReader = File.OpenText(tmp))
                {
                    string line;
                    switch(result)
                    {
                        case 0:
                            while((line = lineReader.ReadLine()) != null) {
                                e.OutputCode.AppendLine(line);
                            }
                            break;
                        default:
                            bool hasErrorText = false;
                            while((line = lineReader.ReadLine()) != null) {
                                GenerateErrorWithPosition(line, e);
                                hasErrorText = true;
                            }
                            if(!hasErrorText) {
                                e.GenerateError("Code generation failed with exit-code " + result);
                            }
                            break;
                    }
                }
                #region ensure protobuf-net.dll is in the project:

                try
                {
                    VSProject project = (VSProject)e.ProjectItem.ContainingProject.Object;
                    bool hasRef = project.References.Cast<Reference>()
                        .Any(r => r != null && string.Equals(r.Name, "protobuf-net", StringComparison.InvariantCultureIgnoreCase));

                    if (!hasRef)
                    {
                        string toolPath = GetInstallPath(PBNETDLL);

                        /* REMOVED: copy dll into local project
                        string projectPath = Path.Combine(
                                Path.GetDirectoryName(e.ProjectItem.ContainingProject.FullName),
                                PBNETDLL);
                        // copy it into the project if needed
                        if(!File.Exists(projectPath))
                        {
                            File.Copy(toolPath, projectPath);
                        }
                         */
                        // add the reference (from the install location)
                        Reference dllRef = project.References.Add(toolPath);
                        dllRef.CopyLocal = true;
                    }
                }
                catch (Exception ex)
                {
                    e.GenerateWarning("Failed to add reference to protobuf-net:" + ex.Message);
                }
                #endregion
            }
            finally
            {
                try { File.Delete(tmp); }
                catch (Exception ex) { e.GenerateWarning(ex.Message); }
            }
        }

        static readonly Regex gccErrorFormat = new Regex(@"\:([0-9]+)\:([0-9]+)\:", RegexOptions.Compiled);
        static void GenerateErrorWithPosition(string line, GenerationEventArgs e)
        {
            Match match = gccErrorFormat.Match(line);
            int row, col;
            if(match.Success && int.TryParse(match.Groups[1].Value, out row)
                && int.TryParse(match.Groups[2].Value, out col)) {
                e.GenerateError(line, row-1, col-1); // note offsets!
            } else {
                e.GenerateError(line);
            }
        }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/Int16Serializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class Int16Serializer : IRuntimeProtoSerializerNode
    {
        private Int16Serializer() { }
        internal static readonly Int16Serializer Instance = new Int16Serializer();

        private static readonly Type expectedType = typeof(short);

        public Type ExpectedType => expectedType;

        bool IRuntimeProtoSerializerNode.RequiresOldValue => false;

        bool IRuntimeProtoSerializerNode.ReturnsValue => true;

        public object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return state.ReadInt16();
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteInt16((short)value);
        }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            ctx.EmitStateBasedWrite(nameof(ProtoWriter.State.WriteInt16), valueFrom);
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            ctx.EmitStateBasedRead(nameof(ProtoReader.State.ReadInt16), ExpectedType);
        }
    }
}

<|start_filename|>src/protobuf-net/Internal/Serializers/StringSerializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;
using System.Reflection;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class StringSerializer : IRuntimeProtoSerializerNode, IDirectWriteNode
    {
        private StringSerializer() { }
        internal static readonly StringSerializer Instance = new StringSerializer();

        private static readonly Type expectedType = typeof(string);

        public Type ExpectedType => expectedType;

        public void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteString((string)value);
        }
        bool IRuntimeProtoSerializerNode.RequiresOldValue => false;

        bool IRuntimeProtoSerializerNode.ReturnsValue => true;

        public object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return state.ReadString();
        }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using var loc = ctx.GetLocalWithValue(typeof(string), valueFrom);
            ctx.LoadState();
            ctx.LoadValue(loc);
            ctx.LoadNullRef(); // map
            ctx.EmitCall(typeof(ProtoWriter.State).GetMethod(nameof(ProtoWriter.State.WriteString), BindingFlags.Instance | BindingFlags.Public,
                null, new[] { typeof(string), typeof(StringMap) }, null));
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            ctx.LoadState();
            ctx.LoadNullRef(); // map
            ctx.EmitCall(typeof(ProtoReader.State).GetMethod(nameof(ProtoReader.State.ReadString), BindingFlags.Instance | BindingFlags.Public,
                null, new[] { typeof(StringMap) }, null));
        }

        bool IDirectWriteNode.CanEmitDirectWrite(WireType wireType) => wireType == WireType.String;

        void IDirectWriteNode.EmitDirectWrite(int fieldNumber, WireType wireType, Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using var loc = ctx.GetLocalWithValue(typeof(string), valueFrom);
            ctx.LoadState();
            ctx.LoadValue(fieldNumber);
            ctx.LoadValue(loc);
            ctx.LoadNullRef(); // map
            ctx.EmitCall(typeof(ProtoWriter.State).GetMethod(nameof(ProtoWriter.State.WriteString), BindingFlags.Instance | BindingFlags.Public,
                null, new[] { typeof(int), typeof(string), typeof(StringMap) }, null));
        }
    }
}

<|start_filename|>src/protobuf-net.Test/FX11/Class1.cs<|end_filename|>
﻿using System;
#if !FX11
using System.Collections.Generic;
#endif
using System.Text;
using System.Diagnostics;

namespace SampleDto
{
    public class Customer
    {
        private int id;
        public int Id { get { return id; } set { id = value; } }
        public string Name;
#if !FX11
        private double? howMuch;
        public double? HowMuch { get { return howMuch; } set { howMuch = value; } }
        public bool? HasValue;
#endif
        public override string ToString()
        {
            string s = id + ": " + Name;
#if !FX11
            s += "\t" + howMuch + " / " + HasValue;
#endif
            return s;
        }

    }
    public struct CustomerStruct
    {
        private int id;
        public int Id { get { return id; } set { id = value; } }
        public string Name;
#if !FX11
        private double? howMuch;
        public double? HowMuch { get { return howMuch; } set { howMuch = value; } }
        public bool? HasValue;
#endif
        public override string ToString()
        {
            string s = id + ": " + Name;
#if !FX11
            s += "\t" + howMuch + " / " + HasValue;
#endif
            return s;
        }
    }
}


<|start_filename|>src/protobuf-net.BuildTools/Analyzers/ServiceContractAnalyzer.cs<|end_filename|>
﻿#nullable enable
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using ProtoBuf.BuildTools.Internal;
using System;
using System.Collections.Immutable;
using System.Threading;

namespace ProtoBuf.BuildTools.Analyzers
{
    /// <summary>
    /// Inspects service contracts for common code-first gRPC configuration errors
    /// </summary>
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class ServiceContractAnalyzer : DiagnosticAnalyzer, ILoggingAnalyzer
    {
        private event Action<string>? Log;
        event Action<string>? ILoggingAnalyzer.Log
        {
            add => this.Log += value;
            remove => this.Log -= value;
        }

        internal static readonly DiagnosticDescriptor InvalidMemberKind = new(
            id: "PBN2001",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(InvalidMemberKind),
            messageFormat: "This member is not a method; only methods are supported for gRPC services.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor InvalidPayloadType = new(
            id: "PBN2002",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(InvalidPayloadType),
            messageFormat: "The data parameter of a gRPC method must currently be Void, a reference-type data contract, or an async sequence of the same.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor InvalidReturnType = new(
            id: "PBN2003",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(InvalidReturnType),
            messageFormat: "The return value of a gRPC method must currently be Void, a reference-type data contract, or an task / async sequence of the same.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor GenericMethod = new(
            id: "PBN2004",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(GenericMethod),
            messageFormat: "The gRPC method can not be generic.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor GenericService = new(
            id: "PBN2005",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(GenericService),
            messageFormat: "The gRPC service can not be generic.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor InvalidContextType = new(
            id: "PBN2006",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(InvalidContextType),
            messageFormat: "The context parameter of a gRPC method must be CallContext or CancellationToken.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor InvalidParameters = new(
            id: "PBN2007",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(InvalidParameters),
            messageFormat: "Invalid signature; gRPC methods expect a single optional payload and a single optional context.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor PossiblyNotSerializable = new(
            id: "PBN2008",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(PossiblyNotSerializable),
            messageFormat: "gRPC methods require inputs/outputs that can be marshalled with gRPC; this type *may* be usable with gRPC, but it could not be verified.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Warning,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor PreferAsync = new(
            id: "PBN2009",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(PreferAsync),
            messageFormat: "gRPC methods should be async when possible.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Info,
            isEnabledByDefault: true);

        internal static readonly DiagnosticDescriptor StreamingSyncMethod = new(
            id: "PBN2010",
            title: nameof(ServiceContractAnalyzer) + "." + nameof(StreamingSyncMethod),
            messageFormat: "gRPC methods that take streaming parameters cannot be synchronous.",
            category: Literals.CategoryUsage,
            defaultSeverity: DiagnosticSeverity.Error,
            isEnabledByDefault: true);

        private static readonly ImmutableArray<SyntaxKind> s_syntaxKinds =
            ImmutableArray.Create(SyntaxKind.InterfaceDeclaration);

        /// <inheritdoc/>
        public override void Initialize(AnalysisContext ctx)
        {
            ctx.EnableConcurrentExecution();
            ctx.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);
            ctx.RegisterSyntaxNodeAction(context => ConsiderPossibleServiceType(context), s_syntaxKinds);
        }

        private static readonly ImmutableArray<DiagnosticDescriptor> s_SupportedDiagnostics = Utils.GetDeclared(typeof(ServiceContractAnalyzer));

        /// <inheritdoc/>
        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => s_SupportedDiagnostics;

        private void ConsiderPossibleServiceType(SyntaxNodeAnalysisContext context)
        {
            if (context.ContainingSymbol is not INamedTypeSymbol type) return;

            var attribs = type.GetAttributes();
            string? serviceName = null;
            foreach (var attrib in attribs)
            {
                var ac = attrib.AttributeClass;
                if (ac?.Name == "ServiceAttribute" && ac.InNamespace("ProtoBuf","Grpc","Configuration"))
                {
                    attrib.TryGetStringByName("Name", out serviceName);
                    if (string.IsNullOrWhiteSpace(serviceName)) serviceName = GetDefaultName(type);
                    break;
                }
            }
            if (string.IsNullOrWhiteSpace(serviceName)) return;

            Log?.Invoke($"Service detected: '{serviceName}'");

            if (type.IsGenericType)
            {
                context.ReportDiagnostic(Diagnostic.Create(GenericService, Utils.PickLocation(ref context, type)));
            }

            foreach (var member in type.GetMembers())
            {
                if (member is not IMethodSymbol method)
                {
                    context.ReportDiagnostic(Diagnostic.Create(InvalidMemberKind, Utils.PickLocation(ref context, member)));
                    continue;
                }

                if (method.IsGenericMethod)
                {
                    context.ReportDiagnostic(Diagnostic.Create(GenericMethod, Utils.PickLocation(ref context, method)));
                }

                var p = method.Parameters;
                (INamedTypeSymbol? Type, DataTypeFlags Flags) payload;
                ContextKind contextKind;
                switch (p.Length)
                {
                    case 0:
                        contextKind = ContextKind.None;
                        payload = (null, DataTypeFlags.IsEmpty);
                        break;
                    case 1:
                        // single arg could be payload or context
                        if (TryResolveContextKind(p[0].Type, out contextKind))
                        {
                            AssertContext(p[0]);
                            payload = (null, DataTypeFlags.IsEmpty);
                        }
                        else
                        {
                            contextKind = ContextKind.None;
                            payload = ResolveDataType(p[0].Type);
                            AssertPayload(p[0]);
                        }
                        break;
                    case 2:
                        // first arg is expected to be the payload, second arg is expected to be the context
                        payload = ResolveDataType(p[0].Type);
                        AssertPayload(p[0]);
                        if (TryResolveContextKind(p[1].Type, out contextKind))
                        {
                            AssertContext(p[1]);
                        }
                        else
                        {
                            contextKind = ContextKind.None;
                            context.ReportDiagnostic(Diagnostic.Create(InvalidParameters, Utils.PickLocation(ref context, member)));
                        }
                        
                        break;
                    default:
                        payload = (null, DataTypeFlags.InvalidType);
                        contextKind = ContextKind.Invalid;
                        context.ReportDiagnostic(Diagnostic.Create(InvalidParameters, Utils.PickLocation(ref context, member)));
                        break;
                }

                var ret = ResolveDataType(method.ReturnType);
                if ((ret.Flags & DataTypeFlags.InvalidType) != 0)
                {
                    context.ReportDiagnostic(Diagnostic.Create(InvalidReturnType, Utils.PickLocation(ref context, method)));
                }
                else if ((ret.Flags & (DataTypeFlags.DataContract | DataTypeFlags.IsEmpty)) == 0
                    && !SymbolEqualityComparer.Default.Equals(payload.Type, ret.Type)) // don't double report
                {
                    context.ReportDiagnostic(Diagnostic.Create(PossiblyNotSerializable, Utils.PickLocation(ref context, method)));
                }
                else if ((ret.Flags & DataTypeFlags.IsAsync) == 0)
                {
                    if ((payload.Flags & DataTypeFlags.IsStream) != 0)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(StreamingSyncMethod, Utils.PickLocation(ref context, method)));
                    }
                    else
                    {
                        context.ReportDiagnostic(Diagnostic.Create(PreferAsync, Utils.PickLocation(ref context, method)));
                    }
                }

                Log?.Invoke($"Send '{payload.Type?.ToDisplayString()}' ({payload.Flags}), receive '{ret.Type?.ToDisplayString()}' ({ret.Flags}), context: {contextKind}");

                Location? PickLocation(IParameterSymbol parameter)
                {
                    if (!parameter.Locations.IsDefaultOrEmpty) return parameter.Locations[0];
                    return Utils.PickLocation(ref context, method);
                }
                void AssertContext(IParameterSymbol parameter)
                {
                    if (contextKind == ContextKind.Invalid)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(InvalidContextType, PickLocation(parameter)));
                    }
                }
                void AssertPayload(IParameterSymbol parameter)
                {
                    if ((payload.Flags & DataTypeFlags.InvalidType) != 0
                        || (payload.Flags & (DataTypeFlags.IsAsync | DataTypeFlags.IsStream)) == DataTypeFlags.IsAsync) // [Value]Task parameter
                    {
                        context.ReportDiagnostic(Diagnostic.Create(InvalidPayloadType, PickLocation(parameter)));
                    }
                    else if ((payload.Flags & (DataTypeFlags.DataContract | DataTypeFlags.IsEmpty)) == 0)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(PossiblyNotSerializable, PickLocation(parameter)));
                    }
                }
            }

        }

        enum ContextKind
        {
            None,
            CallContext,
            CancellationToken,
            Invalid,
        }

        [Flags]
        enum DataTypeFlags
        {
            None = 0,
            DataContract = 1 << 0,
            InvalidType = 1 << 1,
            IsAsync = 1 << 2,
            IsStream = 1 << 3,
            IsEmpty = 1 << 4,
            IsValueTask = 1 << 8,
        }

        static bool TryResolveContextKind(ITypeSymbol symbol, out ContextKind kind)
        {
            if (symbol is not INamedTypeSymbol named)
            {
                kind = ContextKind.Invalid;
                return false;
            }
            if (named.Name == nameof(CancellationToken) && named.InNamespace("System", "Threading"))
            {
                kind = ContextKind.CancellationToken;
                return true;
            }
            if (named.Name == "CallContext" && named.InNamespace("ProtoBuf", "Grpc"))
            {
                kind = ContextKind.CancellationToken;
                return true;
            }
            if ((named.Name == "ServerCallContext" || named .Name == "CallOptions") && named.InNamespace("Grpc","Core"))
            {
                kind = ContextKind.Invalid; // we don't support these; use CallContext instead
                return true; // but we recognised it!
            }

            kind = ContextKind.None;
            return false;
        }

        static (INamedTypeSymbol? Type, DataTypeFlags Flags) ResolveDataType(ITypeSymbol symbol)
        {
            if (symbol is INamedTypeSymbol named)
            {
                var flags = ResolveDataType(ref named);
                return (named, flags);
            }
            return (null, DataTypeFlags.InvalidType);
        }
        static DataTypeFlags ResolveDataType(ref INamedTypeSymbol symbol)
        {
            if (symbol.SpecialType == SpecialType.System_Void) return DataTypeFlags.IsEmpty;

            // if the compiler recognises it; it isn't a good thing!
            if (symbol.SpecialType != SpecialType.None)
                return DataTypeFlags.InvalidType;

            if (TryResolveContextKind(symbol, out _))
                return DataTypeFlags.InvalidType; // if it is a context kind, it isn't a payload!

            if (symbol.IsValueType)
            {
                if (symbol.Name == "ValueTask" && symbol.InNamespace("System", "Threading", "Tasks"))
                {
                    if (symbol.IsGenericType)
                        return ResolveSimpleSingleGenericParameterKind(ref symbol) | DataTypeFlags.IsAsync | DataTypeFlags.IsValueTask;
                    return DataTypeFlags.IsEmpty | DataTypeFlags.IsAsync | DataTypeFlags.IsValueTask;
                }

                return DataTypeFlags.InvalidType; // don't allow most value-types
            }

            if (symbol.Name == "Task" && symbol.InNamespace("System","Threading","Tasks"))
            {
                if (symbol.IsGenericType)
                    return ResolveSimpleSingleGenericParameterKind(ref symbol) | DataTypeFlags.IsAsync;
                return DataTypeFlags.IsEmpty | DataTypeFlags.IsAsync;
            }

            if (symbol.Name == "IAsyncEnumerable" && symbol.InNamespace("System", "Collections", "Generic"))
            {
                if (symbol.IsGenericType)
                    return ResolveSimpleSingleGenericParameterKind(ref symbol) | DataTypeFlags.IsAsync | DataTypeFlags.IsStream;
            }

            foreach (var attrib in symbol.GetAttributes())
            {
                var ac = attrib.AttributeClass;
                if (ac?.Name == nameof(ProtoContractAttribute) && ac.InProtoBufNamespace())
                    return DataTypeFlags.DataContract;
            }
            return DataTypeFlags.None;
        }

        static DataTypeFlags ResolveSimpleSingleGenericParameterKind(ref INamedTypeSymbol symbol)
        {
            if (symbol.TypeArguments.Length != 1)
                return DataTypeFlags.InvalidType;

            if (symbol.TypeArguments[0] is not INamedTypeSymbol inner)
                return DataTypeFlags.InvalidType;

            var flags = ResolveDataType(ref inner);

            switch (flags)
            {
                case DataTypeFlags.None:
                case DataTypeFlags.DataContract:
                    symbol = inner;
                    return flags; // fine
                default:
                    return DataTypeFlags.InvalidType; // the first T needs to be simple; can't be Task<Task<Foo>> etc

            }
        }

        static string GetDefaultName(ITypeSymbol contractType)
        {   // ported from protobuf-net.Grpc
            var serviceName = contractType.Name;

            if (contractType.TypeKind == TypeKind.Interface && serviceName.StartsWith("I")) serviceName = serviceName.Substring(1); // IFoo => Foo
            serviceName = contractType.ContainingNamespace.Qualified(serviceName);
            serviceName = serviceName.Replace('+', '.'); // nested types

            //int cut;
            //if (contractType.IsGenericType && (cut = serviceName.IndexOf('`')) >= 0)
            //{
            //    var parts = GetGenericParts(contractType);
            //    serviceName = serviceName.Substring(0, cut)
            //        + "_" + string.Join("_", parts);
            //}

            return serviceName ?? "";
        }
    }
}


<|start_filename|>assorted/DataTableSerializer/Program.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using ProtoBuf;

namespace ExperimentalDataTableSerialization
{
    class Program
    {
        static DataTable LoadDataTableFromDatabase()
        {
            DataTable table = new DataTable("Sales.SalesOrderDetail");
            using (var conn = new SqlConnection("Data Source=.;Initial Catalog=AdventureWorks2008R2;Integrated Security=True"))
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "select * from Sales.SalesOrderDetail";
                conn.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    table.Load(reader);
                }
            }
            return table;
        }
        static void ExecuteWithTiming(string caption, Action action)
        {
            CleanupObjectsBeforeTiming();
            var watch = Stopwatch.StartNew();
            action();
            watch.Stop();
            Console.WriteLine("{0}\t{1}ms", caption, watch.ElapsedMilliseconds);
        }
        static T ExecuteWithTiming<T>(string caption, Func<T> func)
        {
            CleanupObjectsBeforeTiming();
            var watch = Stopwatch.StartNew();
            T value = func();
            watch.Stop();
            Console.WriteLine("{0}\t{1}ms", caption, watch.ElapsedMilliseconds);
            return value;
        }
        static void Main()
        {
            var table = ExecuteWithTiming<DataTable>("Load table", LoadDataTableFromDatabase);
            Console.WriteLine("Table loaded\t{0} cols\t{1} rows", table.Columns.Count, table.Rows.Count);
            BinaryFormatter bf = new BinaryFormatter();

            WriteWithTiming("DataTable (xml)", stream => table.WriteXml(stream, XmlWriteMode.WriteSchema), stream =>
            {
                var dt = new DataTable();
                dt.ReadXml(stream);
                CheckTables(table, dt);
            });
            table.RemotingFormat = SerializationFormat.Xml;
            WriteWithTiming("BinaryFormatter (rf:xml)", stream => bf.Serialize(stream, table), stream => CheckTables(table, bf.Deserialize(stream)));
            table.RemotingFormat = SerializationFormat.Binary;
            WriteWithTiming("BinaryFormatter (rf:binary)", stream => bf.Serialize(stream, table), stream => CheckTables(table, bf.Deserialize(stream)));

            WriteWithTiming("protobuf-net v2", stream => ProtoWrite(table, stream), stream => CheckTables(table, ProtoRead(stream)));
        }
        static void CleanupObjectsBeforeTiming()
        {
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            GC.WaitForPendingFinalizers();
        }
        static DataTable ProtoRead(Stream stream)
        {
            DataTable table = new DataTable();
            object[] values = null;
            using (ProtoReader reader = new ProtoReader(stream, null, null))
            {
                int field;
                List<Func<object>> colReaders = new List<Func<object>>();
                SubItemToken token;
                while ((field = reader.ReadFieldHeader()) != 0)
                {
                    switch (field)
                    {
                        case 1:
                            table.TableName = reader.ReadString();
                            break;
                        case 2:
                            string name = null;
                            MappedType mappedType = (MappedType)(-1);
                            token = ProtoReader.StartSubItem(reader);
                            while ((field = reader.ReadFieldHeader()) != 0)
                            {
                                switch (field)
                                {
                                    case 1:
                                        name = reader.ReadString();
                                        break;
                                    case 2:
                                        mappedType = (MappedType)reader.ReadInt32();
                                        break;
                                    default:
                                        reader.SkipField();
                                        break;
                                }
                            }
                            Type type;
                            switch (mappedType)
                            {
                                case MappedType.Int32:
                                    type = typeof(int);
                                    colReaders.Add(() => reader.ReadInt32());
                                    break;
                                case MappedType.Int16:
                                    type = typeof(short);
                                    colReaders.Add(() => reader.ReadInt16());
                                    break;
                                case MappedType.Decimal:
                                    type = typeof(decimal);
                                    colReaders.Add(() => BclHelpers.ReadDecimal(reader));
                                    break;
                                case MappedType.String:
                                    type = typeof(string);
                                    colReaders.Add(() => reader.ReadString());
                                    break;
                                case MappedType.Guid:
                                    type = typeof(Guid);
                                    colReaders.Add(() => BclHelpers.ReadGuid(reader));
                                    break;
                                case MappedType.DateTime:
                                    type = typeof(DateTime);
                                    colReaders.Add(() => BclHelpers.ReadDateTime(reader));
                                    break;
                                default:
                                    throw new NotSupportedException(mappedType.ToString());
                            }
                            ProtoReader.EndSubItem(token, reader);
                            table.Columns.Add(name, type);
                            values = null;
                            break;
                        case 3:
                            if (values == null) values = new object[table.Columns.Count];
                            else Array.Clear(values, 0, values.Length);
                            token = ProtoReader.StartSubItem(reader);
                            while ((field = reader.ReadFieldHeader()) != 0)
                            {
                                if (field > values.Length) reader.SkipField();
                                else
                                {
                                    int i = field - 1;
                                    values[i] = colReaders[i]();
                                }
                            }
                            ProtoReader.EndSubItem(token, reader);
                            table.Rows.Add(values);
                            break;
                        default:
                            reader.SkipField();
                            break;
                    }
                }
            }
            return table;
        }
        static void CheckTables(DataTable x, object other)
        {
            DataTable y = (DataTable)other;
            if (x.TableName != y.TableName) Console.WriteLine("names do not match");
            if (x.Columns.Count != y.Columns.Count) Console.WriteLine("columns do not match");
            if (x.Rows.Count != y.Rows.Count) Console.WriteLine("rows do not match");
        }
        enum MappedType
        {
            Int16, Int32, String, Decimal, Guid, DateTime
        }
        static void ProtoWrite(DataTable table, Stream stream)
        {
            using (var writer = new ProtoWriter(stream, null, null))
            {
                // table name
                if (!string.IsNullOrEmpty(table.TableName))
                {
                    ProtoWriter.WriteFieldHeader(1, WireType.String, writer);
                    ProtoWriter.WriteString(table.TableName, writer);
                }

                // write the schema:
                var cols = table.Columns;
                Action<object>[] colWriters = new Action<object>[cols.Count];
                int i = 0;

                foreach (DataColumn col in cols)
                {
                    // for each, write the name and data type
                    ProtoWriter.WriteFieldHeader(2, WireType.StartGroup, writer);
                    var token = ProtoWriter.StartSubItem(col, writer);
                    ProtoWriter.WriteFieldHeader(1, WireType.String, writer);
                    ProtoWriter.WriteString(col.ColumnName, writer);
                    ProtoWriter.WriteFieldHeader(2, WireType.Variant, writer);
                    MappedType type;
                    switch (Type.GetTypeCode(col.DataType))
                    {
                        case TypeCode.Decimal: type = MappedType.Decimal; break;
                        case TypeCode.Int16: type = MappedType.Int16; break;
                        case TypeCode.Int32: type = MappedType.Int32; break;
                        case TypeCode.String: type = MappedType.String; break;
                        case TypeCode.DateTime: type = MappedType.DateTime; break;
                        default:
                            if (col.DataType == typeof(Guid))
                            {
                                type = MappedType.Guid; break;
                            }
                            throw new NotSupportedException(col.DataType.Name);
                    }
                    ProtoWriter.WriteInt32((int)type, writer);
                    ProtoWriter.EndSubItem(token, writer);
                    int field = i + 1;
                    Action<object> colWriter;
                    switch (type)
                    {
                        case MappedType.String:
                            colWriter = value =>
                            {
                                ProtoWriter.WriteFieldHeader(field, WireType.String, writer);
                                ProtoWriter.WriteString((string)value, writer);
                            };
                            break;
                        case MappedType.Int16:
                            colWriter = value =>
                            {
                                ProtoWriter.WriteFieldHeader(field, WireType.Variant, writer);
                                ProtoWriter.WriteInt16((short)value, writer);
                            };
                            break;
                        case MappedType.Decimal:
                            colWriter = value =>
                            {
                                ProtoWriter.WriteFieldHeader(field, WireType.StartGroup, writer);
                                BclHelpers.WriteDecimal((decimal)value, writer);
                            };
                            break;
                        case MappedType.Int32:
                            colWriter = value =>
                            {
                                ProtoWriter.WriteFieldHeader(field, WireType.Variant, writer);
                                ProtoWriter.WriteInt32((int)value, writer);
                            };
                            break;
                        case MappedType.Guid:
                            colWriter = value =>
                            {
                                ProtoWriter.WriteFieldHeader(field, WireType.StartGroup, writer);
                                BclHelpers.WriteGuid((Guid)value, writer);
                            };
                            break;
                        case MappedType.DateTime:
                            colWriter = value =>
                            {
                                ProtoWriter.WriteFieldHeader(field, WireType.StartGroup, writer);
                                BclHelpers.WriteDateTime((DateTime)value, writer);
                            };
                            break;
                        default:
                            throw new NotSupportedException(col.DataType.Name);
                    }
                    colWriters[i++] = colWriter;
                }
                // write the rows
                foreach (DataRow row in table.Rows)
                {
                    i = 0;
                    ProtoWriter.WriteFieldHeader(3, WireType.StartGroup, writer);
                    var token = ProtoWriter.StartSubItem(row, writer);
                    foreach (DataColumn col in cols)
                    {
                        var value = row[col];
                        if (value == null || value is DBNull) { }
                        else { colWriters[i](value); }
                        i++;
                    }
                    ProtoWriter.EndSubItem(token, writer);
                }
            }
        }
        static void WriteWithTiming(string caption, Action<Stream> serialize, Action<Stream> deserialize)
        {

            using (var ms = new MemoryStream())
            {
                CleanupObjectsBeforeTiming();
                var watch1 = Stopwatch.StartNew();
                serialize(ms);
                watch1.Stop();
                ms.Position = 0;
                CleanupObjectsBeforeTiming();
                var watch2 = Stopwatch.StartNew();
                deserialize(ms);
                watch2.Stop();
                Console.WriteLine("{0} (vanilla)\t{1}ms/{2}ms\t{3:###,###} bytes", caption, watch1.ElapsedMilliseconds, watch2.ElapsedMilliseconds, ms.Length);


            }
            using (var ms = new MemoryStream())
            {
                Stopwatch watch1, watch2;
                using (var gzip = new GZipStream(ms, CompressionMode.Compress, true))
                {
                    CleanupObjectsBeforeTiming();
                    watch1 = Stopwatch.StartNew();
                    serialize(gzip);
                    watch1.Stop();
                    gzip.Close();
                }
                ms.Position = 0;
                using (var gzip = new GZipStream(ms, CompressionMode.Decompress, true))
                {
                    CleanupObjectsBeforeTiming();
                    watch2 = Stopwatch.StartNew();
                    deserialize(gzip);
                    watch2.Stop();
                    gzip.Close();
                }
                Console.WriteLine("{0} (gzip)\t{1}ms/{2}ms\t{3:###,###} bytes", caption, watch1.ElapsedMilliseconds, watch2.ElapsedMilliseconds, ms.Length);
            }
            using (var ms = new MemoryStream())
            {
                Stopwatch watch1, watch2;
                using (var deflate = new DeflateStream(ms, CompressionMode.Compress, true))
                {
                    CleanupObjectsBeforeTiming();
                    watch1 = Stopwatch.StartNew();
                    serialize(deflate);
                    watch1.Stop();
                    deflate.Close();
                }
                ms.Position = 0;
                using (var deflate = new DeflateStream(ms, CompressionMode.Decompress, true))
                {
                    CleanupObjectsBeforeTiming();
                    watch2 = Stopwatch.StartNew();
                    deserialize(deflate);
                    watch2.Stop();
                    deflate.Close();
                }
                Console.WriteLine("{0} (deflate)\t{1}ms/{2}ms\t{3:###,###} bytes", caption, watch1.ElapsedMilliseconds, watch2.ElapsedMilliseconds, ms.Length);
            }

        }

    }
}

<|start_filename|>assorted/demo-rpc-server-mvc/Helpers/ControllerExtensions.cs<|end_filename|>
﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using System.Web.Mvc;

namespace demo_rpc_server_mvc.Controllers
{
    public static class ControllerExtensions
    {
        public static ActionResult Silverlight(this Controller controller,
            string title, string path)
        {
            if (path.IndexOf('.') < 0) path = path + ".xap";
            if(path.IndexOf('/') < 0) path = "~/ClientBin/" + path;

            var viewData = new ViewDataDictionary();
            viewData["Title"] = title;
            viewData["Path"] = path;
            
            var result = new ViewResult();
            result.ViewName = "Silverlight";
            result.ViewData = viewData;
            return result;
        }
    }
}


<|start_filename|>src/protobuf-net/Compiler/CompilerContext.cs<|end_filename|>
﻿//#define DEBUG_COMPILE
using System;
using System.Threading;
using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using System.Diagnostics;
using ProtoBuf.Internal;
using System.Collections;
using System.Linq;
using System.Globalization;
using ProtoBuf.Internal.Serializers;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;

namespace ProtoBuf.Compiler
{
    [StructLayout(LayoutKind.Auto)]
    internal readonly struct CodeLabel
    {
        public readonly Label Value;
        public readonly int Index;
        public CodeLabel(Label value, int index)
        {
            this.Value = value;
            this.Index = index;
        }
    }
    internal sealed class CompilerContext : IDisposable
    {
        public TypeModel Model { get; }

        private readonly DynamicMethod method;
        private static int next;

        internal CodeLabel DefineLabel()
        {
            CodeLabel result = new CodeLabel(il.DefineLabel(), nextLabel++);
            return result;
        }
#if DEBUG_COMPILE
        static readonly string traceCompilePath;
        static CompilerContext()
        {
            traceCompilePath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),
                "TraceCompile.txt");
            Console.WriteLine("DEBUG_COMPILE enabled; writing to " + traceCompilePath);
        }
#endif
        [System.Diagnostics.Conditional("DEBUG_COMPILE")]
#pragma warning disable CA1822 // Mark members as static - it uses state when it has content
        private void TraceCompile(string value)
#pragma warning restore CA1822 // Mark members as static
        {
#if DEBUG_COMPILE
            if (!string.IsNullOrWhiteSpace(value))
            {
                using (System.IO.StreamWriter sw = System.IO.File.AppendText(traceCompilePath))
                {
                    sw.WriteLine(value);
                }
            }
#endif
        }
        internal void MarkLabel(CodeLabel label)
        {
            il.MarkLabel(label.Value);
            TraceCompile("#: " + label.Index);
        }

        public static ProtoSerializer<TActual> BuildSerializer<TActual>(CompilerContextScope scope, IRuntimeProtoSerializerNode head, TypeModel model)
        {
            Type type = head.ExpectedType;
            try
            {
                using CompilerContext ctx = new CompilerContext(scope, type, SignatureType.WriterScope_Input, true, model, typeof(TActual), null);
                ctx.WriteNullCheckedTail(type, head, ctx.InputValue);
                ctx.Emit(OpCodes.Ret);
                return (ProtoSerializer<TActual>)ctx.method.CreateDelegate(
                    typeof(ProtoSerializer<TActual>));
            }
            catch (Exception ex)
            {
                string name = type.FullName;
                if (string.IsNullOrEmpty(name)) name = type.Name;
                throw new InvalidOperationException("It was not possible to prepare a serializer for: " + name, ex);
            }
        }
        /*public static ProtoCallback BuildCallback(IProtoTypeSerializer head)
        {
            Type type = head.ExpectedType;
            using CompilerContext ctx = new CompilerContext(type, true, true);
            using (Local typedVal = new Local(ctx, type))
            {
                ctx.LoadValue(Local.InputValue);
                ctx.CastFromObject(type);
                ctx.StoreValue(typedVal);
                CodeLabel[] jumpTable = new CodeLabel[4];
                for(int i = 0 ; i < jumpTable.Length ; i++) {
                    jumpTable[i] = ctx.DefineLabel();
                }
                ctx.LoadReaderWriter();
                ctx.Switch(jumpTable);
                ctx.Return();
                for(int i = 0 ; i < jumpTable.Length ; i++) {
                    ctx.MarkLabel(jumpTable[i]);
                    if (head.HasCallbacks((TypeModel.CallbackType)i))
                    {
                        head.EmitCallback(ctx, typedVal, (TypeModel.CallbackType)i);
                    }
                    ctx.Return();
                }                
            }
            
            ctx.Emit(OpCodes.Ret);
            return (ProtoCallback)ctx.method.CreateDelegate(
                typeof(ProtoCallback));
        }*/

        public static ProtoSubTypeDeserializer<T> BuildSubTypeDeserializer<T>(CompilerContextScope scope, IRuntimeProtoSerializerNode head, TypeModel model)
            where T : class
        {
            using CompilerContext ctx = new CompilerContext(scope, head.ExpectedType, SignatureType.ReaderScope_Input, true, model, typeof(SubTypeState<T>), typeof(T));
            head.EmitRead(ctx, ctx.InputValue);
            // note that EmitRead will unwrap the T for us on the stack
            ctx.Return();

            return (ProtoSubTypeDeserializer<T>)ctx.method.CreateDelegate(typeof(ProtoSubTypeDeserializer<T>));
        }

        public static ProtoDeserializer<T> BuildDeserializer<T>(CompilerContextScope scope, IRuntimeProtoSerializerNode head, TypeModel model, bool isScalar = false)
        {
            using CompilerContext ctx = new CompilerContext(scope, head.ExpectedType, SignatureType.ReaderScope_Input, true, model, typeof(T), typeof(T));

            head.EmitRead(ctx, ctx.InputValue);
            if (!isScalar) ctx.LoadValue(ctx.InputValue);
            ctx.Return();

            return (ProtoDeserializer<T>)ctx.method.CreateDelegate(typeof(ProtoDeserializer<T>));
        }

        public static Func<ISerializationContext, T> BuildFactory<T>(CompilerContextScope scope, IRuntimeProtoSerializerNode head, TypeModel model)
        {
            if (head is IProtoTypeSerializer pts && pts.ShouldEmitCreateInstance)
            {
                using var ctx = new CompilerContext(scope, head.ExpectedType, SignatureType.Context, true , model, typeof(ISerializationContext), typeof(T));
                pts.EmitCreateInstance(ctx, false);
                ctx.Return();

                return (Func<ISerializationContext, T>)ctx.method.CreateDelegate(typeof(Func<ISerializationContext, T>));
            }
            return null;
        }

        static readonly MethodInfo s_CreateInstance = typeof(ProtoReader.State).GetMethod(nameof(ProtoReader.State.CreateInstance),
            BindingFlags.Public | BindingFlags.Instance);
        internal void CreateInstance<T>()
        {
            // call state.CreateInstance<T>(null)
            LoadState();
            LoadNullRef();
            EmitCall(s_CreateInstance.MakeGenericMethod(typeof(T)));
        }

        internal void Return()
        {
            Emit(OpCodes.Ret);
        }

        private static bool IsObject(Type type)
        {
            return type == typeof(object);
        }

        internal void CastToObject(Type type)
        {
            if (IsObject(type))
            { }
            else if (type.IsValueType)
            {
                il.Emit(OpCodes.Box, type);
                TraceCompile(OpCodes.Box + ": " + type);
            }
            else
            {
                il.Emit(OpCodes.Castclass, typeof(object));
                TraceCompile(OpCodes.Castclass + ": " + type);
            }
        }

        internal void CastFromObject(Type type)
        {
            if (IsObject(type))
            { }
            else if (type.IsValueType)
            {
                il.Emit(OpCodes.Unbox_Any, type);
                TraceCompile(OpCodes.Unbox_Any + ": " + type);
            }
            else
            {
                il.Emit(OpCodes.Castclass, type);
                TraceCompile(OpCodes.Castclass + ": " + type);
            }
        }

        internal bool NonPublic { get; }

        public Local InputValue { get; }

        internal CompilerContext(CompilerContext parent, ILGenerator il, bool isStatic, SignatureType signature, Type inputType, string traceName)
            : this(parent.Scope, il, isStatic, signature, parent.Model, inputType, traceName)
        { }

        internal void ThrowException(Type exceptionType) => il.ThrowException(exceptionType);

        
        internal CompilerContext(CompilerContextScope scope, ILGenerator il, bool isStatic, SignatureType signature,
            TypeModel model, Type inputType, string traceName)
        {
            Scope = scope;

            this.il = il ?? throw new ArgumentNullException(nameof(il));
            // NonPublic = false; <== implicit
            this.Model = model ?? throw new ArgumentNullException(nameof(model));
            if (inputType is object) InputValue = new Local(null, inputType);
            TraceCompile(">> " + traceName);
            _traceName = traceName;
            IsStatic = isStatic;
            _signature = signature;
            GetOpCodes(signature, isStatic, out _state, out _inputArg);
        }

        public bool IsStatic { get; }

        public override string ToString() => _traceName;
        private readonly string _traceName;

        private readonly OpCode _state;
        private readonly byte _inputArg;

        private static void GetOpCodes(SignatureType signature, bool isStatic, out OpCode state, out byte inputArg)
        {
            switch (signature)
            {
                case SignatureType.ReaderScope_Input:
                case SignatureType.WriterScope_Input:
                    state = isStatic ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1;
                    inputArg = (byte)(isStatic ? 1 : 2);
                    break;
                default:
                    state = default;
                    inputArg = (byte)(isStatic ? 0 : 1);
                    break;
            }
            
        }

        internal enum SignatureType
        {
            WriterScope_Input,
            ReaderScope_Input,
            Context,
        }
        private readonly SignatureType _signature;

        internal CompilerContextScope Scope { get; }
        private CompilerContext(CompilerContextScope scope, Type associatedType, SignatureType signature, bool isStatic, TypeModel model, Type inputType, Type returnType)
        {
            Scope = scope;
            Model = model ?? throw new ArgumentNullException(nameof(model));
            NonPublic = true;
            _signature = signature;
            GetOpCodes(signature, isStatic, out _state, out _inputArg);
            var paramTypes = signature switch
            {
                SignatureType.ReaderScope_Input => new Type[] { StateBasedReadMethods.ByRefStateType, inputType },
                SignatureType.WriterScope_Input => new Type[] { WriterUtil.ByRefStateType, inputType },
                _ => new Type[] { inputType },
            };
            int uniqueIdentifier = Interlocked.Increment(ref next);
            method = new DynamicMethod("proto_" + uniqueIdentifier.ToString(CultureInfo.InvariantCulture), returnType ?? typeof(void), paramTypes,
                associatedType.IsInterface ? typeof(object) : associatedType, true);
            this.il = method.GetILGenerator();
            if (inputType is object) InputValue = new Local(null, inputType);
            TraceCompile(">> " + method.Name);
            _traceName = method.Name;
            IsStatic = isStatic;
        }

        public bool IsService => Scope.IsFullEmit && !IsStatic;

        public void LoadSelfAsService<TService, T>(CompatibilityLevel compatibilityLevel, DataFormat dataFormat) where TService : class
        {
            var inbuilt = TypeModel.GetInbuiltSerializer<T>(compatibilityLevel, dataFormat);
            if (IsStatic || inbuilt is object) // don't claim inbuilts
            {
                if (inbuilt is object && typeof(TService) == typeof(ISerializer<T>) && !(inbuilt is PrimaryTypeProvider))
                {
                    // we'll get the call-site to emit TypeModel.GetInbuiltSerializer<T>(compatibilityLevel, dataFormat)
                    LoadValue((int)compatibilityLevel);
                    LoadValue((int)dataFormat);
                    EmitCall(s_GetInbuiltSerializer.MakeGenericMethod(typeof(T)));
                }
                else
                {
                    // no serializer (uses Level200 etc)
                    LoadNullRef();
                }
            }
            else
            {
                Emit(OpCodes.Ldarg_0); // push ourselves
                if (Scope.IsFullEmit && Scope.ImplementsServiceFor<T>(compatibilityLevel))
                { } // yay, we should be fine here
                else
                {
                    // otherwise, we'll use isinst to find
                    // out at runtime, else loading null
                    TryCast(typeof(TService));
                }
            }
        }

        private static readonly MethodInfo s_GetInbuiltSerializer = typeof(TypeModel).GetMethod(nameof(TypeModel.GetInbuiltSerializer), BindingFlags.Static | BindingFlags.Public);

        private readonly ILGenerator il;

        private void Emit(OpCode opcode)
        {
            il.Emit(opcode);
            TraceCompile(opcode.ToString());
        }

        public void LoadValue(string value)
        {
            if (value is null)
            {
                LoadNullRef();
            }
            else
            {
                il.Emit(OpCodes.Ldstr, value);
                TraceCompile(OpCodes.Ldstr + ": " + value);
            }
        }

        public void LoadValue(float value)
        {
            il.Emit(OpCodes.Ldc_R4, value);
            TraceCompile(OpCodes.Ldc_R4 + ": " + value);
        }

        public void LoadValue(double value)
        {
            il.Emit(OpCodes.Ldc_R8, value);
            TraceCompile(OpCodes.Ldc_R8 + ": " + value);
        }

        public void LoadValue(long value)
        {
            il.Emit(OpCodes.Ldc_I8, value);
            TraceCompile(OpCodes.Ldc_I8 + ": " + value);
        }

        public void LoadValue(bool value)
        {
            Emit(value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
        }

        public void LoadValue(int value)
        {
            switch (value)
            {
                case 0: Emit(OpCodes.Ldc_I4_0); break;
                case 1: Emit(OpCodes.Ldc_I4_1); break;
                case 2: Emit(OpCodes.Ldc_I4_2); break;
                case 3: Emit(OpCodes.Ldc_I4_3); break;
                case 4: Emit(OpCodes.Ldc_I4_4); break;
                case 5: Emit(OpCodes.Ldc_I4_5); break;
                case 6: Emit(OpCodes.Ldc_I4_6); break;
                case 7: Emit(OpCodes.Ldc_I4_7); break;
                case 8: Emit(OpCodes.Ldc_I4_8); break;
                case -1: Emit(OpCodes.Ldc_I4_M1); break;
                default:
                    if (value >= -128 && value <= 127)
                    {
                        il.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
                        TraceCompile(OpCodes.Ldc_I4_S + ": " + value);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldc_I4, value);
                        TraceCompile(OpCodes.Ldc_I4 + ": " + value);
                    }
                    break;
            }
        }

        private readonly List<LocalBuilder> locals = new List<LocalBuilder>();

        void IDisposable.Dispose() { }

        internal LocalBuilder GetFromPool(Type type)
        {
            int count = locals.Count;
            for (int i = 0; i < count; i++)
            {
                LocalBuilder item = locals[i];
                if (item is object && item.LocalType == type)
                {
                    locals[i] = null; // remove from pool
                    return item;
                }
            }
            LocalBuilder result = il.DeclareLocal(type);
            TraceCompile("$ " + result + ": " + type);
            return result;
        }

        //
        internal void ReleaseToPool(LocalBuilder value)
        {
            int count = locals.Count;
            for (int i = 0; i < count; i++)
            {
                if (locals[i] is null)
                {
                    locals[i] = value; // released into existing slot
                    return;
                }
            }
            locals.Add(value); // create a new slot
        }

        public void LoadState() => Emit(_state);

        public void StoreValue(Local local)
        {
            if (local == this.InputValue)
            {
                il.Emit(OpCodes.Starg_S, _inputArg);
                TraceCompile(OpCodes.Starg_S + ": $" + _inputArg);
            }
            else if (local is null)
            {
                // just leave it on the top of the stack
            }
            else
            {
                switch (local.Value.LocalIndex)
                {
                    case 0: Emit(OpCodes.Stloc_0); break;
                    case 1: Emit(OpCodes.Stloc_1); break;
                    case 2: Emit(OpCodes.Stloc_2); break;
                    case 3: Emit(OpCodes.Stloc_3); break;
                    default:
                        OpCode code = UseShortForm(local) ? OpCodes.Stloc_S : OpCodes.Stloc;
                        il.Emit(code, local.Value);
                        TraceCompile(code + ": $" + local.Value);
                        break;
                }
            }
        }

        public void LoadValue(Local local)
        {
            if (local is null) { /* nothing to do; top of stack */}
            else if (local == this.InputValue)
            {
                switch(_inputArg)
                {
                    case 0: Emit(OpCodes.Ldarg_0); break;
                    case 1: Emit(OpCodes.Ldarg_1); break;
                    case 2: Emit(OpCodes.Ldarg_2); break;
                    case 3: Emit(OpCodes.Ldarg_3); break;
                    default:
                        il.Emit(OpCodes.Ldarg_S, _inputArg);
                        TraceCompile(OpCodes.Ldarg_S + ": $" + _inputArg);
                        break;
                }
            }
            else
            {
                switch (local.Value.LocalIndex)
                {
                    case 0: Emit(OpCodes.Ldloc_0); break;
                    case 1: Emit(OpCodes.Ldloc_1); break;
                    case 2: Emit(OpCodes.Ldloc_2); break;
                    case 3: Emit(OpCodes.Ldloc_3); break;
                    default:

                        OpCode code = UseShortForm(local) ? OpCodes.Ldloc_S : OpCodes.Ldloc;
                        il.Emit(code, local.Value);
                        TraceCompile(code + ": $" + local.Value);

                        break;
                }
            }
        }

        public Local GetLocalWithValue(Type type, Compiler.Local fromValue)
        {
            if (fromValue is object)
            {
                if (fromValue.Type == type) return fromValue.AsCopy();
                // otherwise, load onto the stack and let the default handling (below) deal with it
                LoadValue(fromValue);
                if (!type.IsValueType && (fromValue.Type is null || !type.IsAssignableFrom(fromValue.Type)))
                { // need to cast
                    Cast(type);
                }
            }
            // need to store the value from the stack
            Local result = new Local(this, type);
            StoreValue(result);
            return result;
        }

        internal static class StateBasedReadMethods
        {
            internal static readonly Type ByRefStateType = typeof(ProtoReader.State).MakeByRefType();
            private static readonly Hashtable s_perTypeCache = new Hashtable();
            private static Dictionary<string, MethodInfo> CreateAndAdd(Type parentType)
            {
                var lookup = new Dictionary<string, MethodInfo>(StringComparer.Ordinal);
                foreach (var method in parentType.GetMethods(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    if (method.IsDefined(typeof(ObsoleteAttribute), true)) continue;

                    var args = method.GetParameters();
                    if (method.IsStatic)
                    {
                        if (args.Length != 1) continue;
                        if (args[0].ParameterType != ByRefStateType) continue;
                    }
                    else
                    {
                        if (args.Length != 0) continue;
                    }
                    lookup.Add(method.Name, method);
                }
                lock(s_perTypeCache)
                {
                    s_perTypeCache[parentType] = lookup;
                }
                return lookup;
            }

            internal static bool Find(Type parentType, string methodName, out MethodInfo method)
            {
                var lookup = ((Dictionary<string, MethodInfo>)s_perTypeCache[parentType]) ?? CreateAndAdd(parentType);

                return lookup.TryGetValue(methodName, out method);
            }
        }

        internal void EmitStateBasedRead(string methodName, Type expectedType)
            => EmitStateBasedRead(typeof(ProtoReader.State), methodName, expectedType);
        internal void EmitStateBasedRead(Type ownerType, string methodName, Type expectedType)
        {
            if (!StateBasedReadMethods.Find(ownerType, methodName, out var method))
            {
                throw new ArgumentException($"No suitable '{methodName}' method found on {ownerType.Name}");
            }
            if (method.ReturnType != expectedType)
            {
                throw new ArgumentException($"Method '{methodName}' has wrong return type; got {method.ReturnType.Name}, expected {expectedType.Name}");
            }
            LoadState();
            EmitCall(method);
        }

        internal void EmitStateBasedWrite(string methodName, Local fromValue, Type type = null, Type argType = null)
        {
            if (string.IsNullOrEmpty(methodName)) throw new ArgumentNullException(nameof(methodName));
            if (type is null) type = typeof(ProtoWriter.State);

            Type foundType;
            MethodInfo foundMethod;
            try
            {
                var found = (from method in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)
                         where method.Name == methodName && !method.IsGenericMethodDefinition
                         && method.ReturnType == typeof(void)
                         let args = method.GetParameters()
                         where args.Length == (method.IsStatic ? 2 : 1)
                         && (!method.IsStatic || args[0].ParameterType == WriterUtil.ByRefStateType)
                         let paramType = args[method.IsStatic ? 1 : 0].ParameterType
                         where argType is null || argType == paramType // if argType specified: must match
                         select new { Method = method, Type = paramType }).Single();
                foundType = found.Type;
                foundMethod = found.Method;
            }
            catch(Exception ex)
            {
                throw new InvalidOperationException($"Unable to uniquely resolve {type.Name}.{methodName}", ex);
            }
            using var tmp = GetLocalWithValue(foundType, fromValue);
            LoadState();
            LoadValue(tmp);
            EmitCall(foundMethod);
        }

        public void EmitCall(MethodInfo method) { EmitCall(method, null); }

        public void EmitCall(MethodInfo method, Type targetType)
        {
            MemberInfo member = method ?? throw new ArgumentNullException(nameof(method));
            CheckAccessibility(ref member);
            OpCode opcode;
            Debug.Assert(method is MethodBuilder || !method.IsDefined(typeof(ObsoleteAttribute), true), "calling an obsolete method: " + method.Name);
            if (method.IsStatic || method.DeclaringType.IsValueType)
            {
                opcode = OpCodes.Call;
            }
            else
            {
                opcode = OpCodes.Callvirt;
                if (targetType is object && targetType.IsValueType && !method.DeclaringType.IsValueType)
                {
                    Constrain(targetType);
                }
            }
            il.EmitCall(opcode, method, null);
            TraceCompile(opcode + ": " + method + " on " + method.DeclaringType + (targetType is null ? "" : (" via " + targetType)));
        }

        /// <summary>
        /// Pushes a null reference onto the stack. Note that this should only
        /// be used to return a null (or set a variable to null); for null-tests
        /// use BranchIfTrue / BranchIfFalse.
        /// </summary>
        public void LoadNullRef()
        {
            Emit(OpCodes.Ldnull);
        }

        private int nextLabel;

        internal void WriteNullCheckedTail(Type type, IRuntimeProtoSerializerNode tail, Compiler.Local valueFrom)
        {
            if (tail is TagDecorator td && td.ExpectedType == type && td.CanEmitDirectWrite())
            {
                td.EmitDirectWrite(this, valueFrom);
            }
            else if (type.IsValueType)
            {
                Type underlyingType = Nullable.GetUnderlyingType(type);

                if (underlyingType is null)
                { // not a nullable T; can invoke directly
                    tail.EmitWrite(this, valueFrom);
                }
                else
                { // nullable T; check HasValue
                    using Compiler.Local valOrNull = GetLocalWithValue(type, valueFrom);
                    LoadAddress(valOrNull, type);
                    LoadValue(type.GetProperty("HasValue"));
                    CodeLabel @end = DefineLabel();
                    BranchIfFalse(@end, false);
                    LoadAddress(valOrNull, type);
                    EmitCall(type.GetMethod("GetValueOrDefault", Type.EmptyTypes));
                    tail.EmitWrite(this, null);
                    MarkLabel(@end);
                }
            }
            else
            { // ref-type; do a null-check
                LoadValue(valueFrom);
                CopyValue();
                CodeLabel hasVal = DefineLabel(), @end = DefineLabel();
                BranchIfTrue(hasVal, true);
                DiscardValue();
                Branch(@end, false);
                MarkLabel(hasVal);
                tail.EmitWrite(this, null);
                MarkLabel(@end);
            }
        }

        internal void ReadNullCheckedTail(Type type, IRuntimeProtoSerializerNode tail, Compiler.Local valueFrom)
        {
            Type underlyingType;

            if (type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) is object)
            {
                if (tail.RequiresOldValue)
                {
                    // we expect the input value to be in valueFrom; need to unpack it from T?
                    using Local loc = GetLocalWithValue(type, valueFrom);
                    LoadAddress(loc, type);
                    EmitCall(type.GetMethod("GetValueOrDefault", Type.EmptyTypes));
                }
                else
                {
                    Debug.Assert(valueFrom is null); // not expecting a valueFrom in this case
                }
                tail.EmitRead(this, null); // either unwrapped on the stack or not provided
                if (tail.ReturnsValue)
                {
                    // now re-wrap the value
                    EmitCtor(type, underlyingType);
                }
                return;
            }

            // either a ref-type of a non-nullable struct; treat "as is", even if null
            // (the type-serializer will handle the null case; it needs to allow null
            // inputs to perform the correct type of subclass creation)
            tail.EmitRead(this, valueFrom);
        }

        public void EmitCtor(Type type)
        {
            EmitCtor(type, Type.EmptyTypes);
        }

        public void EmitCtor(ConstructorInfo ctor)
        {
            if (ctor is null) throw new ArgumentNullException(nameof(ctor));
            MemberInfo ctorMember = ctor;
            CheckAccessibility(ref ctorMember);
            il.Emit(OpCodes.Newobj, ctor);
            TraceCompile(OpCodes.Newobj + ": " + ctor.DeclaringType);
        }

        public void InitLocal(Type type, Compiler.Local target)
        {
            LoadAddress(target, type, evenIfClass: true); // for class, initobj is a load-null, store-indirect
            il.Emit(OpCodes.Initobj, type);
            TraceCompile(OpCodes.Initobj + ": " + type);
        }

        internal ILGenerator IL => il;

        public void EmitCtor(Type type, params Type[] parameterTypes)
        {
            Debug.Assert(type is object);
            Debug.Assert(parameterTypes is object);
            if (type.IsValueType && parameterTypes.Length == 0)
            {
                il.Emit(OpCodes.Initobj, type);
                TraceCompile(OpCodes.Initobj + ": " + type);
            }
            else
            {
                ConstructorInfo ctor = Helpers.GetConstructor(type, parameterTypes, true);
                if (ctor is null) throw new InvalidOperationException("No suitable constructor found for " + type.FullName);
                EmitCtor(ctor);
            }
        }

        private List<Assembly> knownTrustedAssemblies, knownUntrustedAssemblies;

        private bool InternalsVisible(Assembly assembly)
        {
            if (string.IsNullOrEmpty(Scope.AssemblyName)) return false;
            if (knownTrustedAssemblies is object)
            {
                if (knownTrustedAssemblies.IndexOf(assembly) >= 0)
                {
                    return true;
                }
            }
            if (knownUntrustedAssemblies is object)
            {
                if (knownUntrustedAssemblies.IndexOf(assembly) >= 0)
                {
                    return false;
                }
            }
            bool isTrusted = false;
            Type attributeType = typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute);
            if (attributeType is null) return false;
            foreach (System.Runtime.CompilerServices.InternalsVisibleToAttribute attrib in assembly.GetCustomAttributes(attributeType, false))
            {
                if (attrib.AssemblyName == Scope.AssemblyName || attrib.AssemblyName.StartsWith(Scope.AssemblyName + ",", StringComparison.Ordinal))
                {
                    isTrusted = true;
                    break;
                }
            }

            if (isTrusted)
            {
                (knownTrustedAssemblies ??= new List<Assembly>()).Add(assembly);
            }
            else
            {
                (knownUntrustedAssemblies ??= new List<Assembly>()).Add(assembly);
            }
            return isTrusted;
        }

        internal void CheckAccessibility(ref MemberInfo member)
        {
            if (member is null)
            {
                throw new ArgumentNullException(nameof(member));
            }
            Type type;
            if (!NonPublic)
            {
                if (member is FieldInfo && (member.Name.StartsWith("<", StringComparison.Ordinal) & member.Name.EndsWith(">k__BackingField", StringComparison.Ordinal)))
                {
                    var propName = member.Name.Substring(1, member.Name.Length - 17);
                    var prop = member.DeclaringType.GetProperty(propName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                    if (prop is object) member = prop;
                }
                bool isPublic;
                MemberTypes memberType = member.MemberType;
                switch (memberType)
                {
                    case MemberTypes.TypeInfo:
                        // top-level type
                        type = (Type)member;
                        isPublic = type.IsPublic || InternalsVisible(type.Assembly);
                        break;
                    case MemberTypes.NestedType:
                        type = (Type)member;
                        do
                        {
                            isPublic = type.IsNestedPublic || type.IsPublic || ((type.DeclaringType is null || type.IsNestedAssembly || type.IsNestedFamORAssem) && InternalsVisible(type.Assembly));
                        } while (isPublic && (type = type.DeclaringType) is object); // ^^^ !type.IsNested, but not all runtimes have that
                        break;
                    case MemberTypes.Field:
                        FieldInfo field = ((FieldInfo)member);
                        isPublic = field.IsPublic || ((field.IsAssembly || field.IsFamilyOrAssembly) && InternalsVisible(field.DeclaringType.Assembly));
                        break;
                    case MemberTypes.Constructor:
                        ConstructorInfo ctor = ((ConstructorInfo)member);
                        isPublic = ctor.IsPublic || ((ctor.IsAssembly || ctor.IsFamilyOrAssembly) && InternalsVisible(ctor.DeclaringType.Assembly));
                        break;
                    case MemberTypes.Method:
                        MethodInfo method = ((MethodInfo)member);
                        isPublic = method.IsPublic || ((method.IsAssembly || method.IsFamilyOrAssembly) && InternalsVisible(method.DeclaringType.Assembly));
                        if (!isPublic)
                        {
                            // allow calls to TypeModel protected methods, and methods we are in the process of creating
                            if (
                                member is MethodBuilder
                                || member.DeclaringType == typeof(TypeModel))
                            {
                                isPublic = true;
                            }
                        }
                        break;
                    case MemberTypes.Property:
                        isPublic = true; // defer to get/set
                        break;
                    default:
                        throw new NotSupportedException(memberType.ToString());
                }
                if (!isPublic)
                {
                    switch (member)
                    {
                        case FieldBuilder:
                        case TypeBuilder:
                        case PropertyBuilder:
                            // we're building them; 'tis fine
                            break;
                        default:
                            throw memberType switch
                            {
                                MemberTypes.TypeInfo or MemberTypes.NestedType =>
                                    new InvalidOperationException("Non-public type cannot be used with full dll compilation: " + ((Type)member).NormalizeName()),
                                _ =>
                                    new InvalidOperationException("Non-public member cannot be used with full dll compilation: " + member.DeclaringType.NormalizeName() + "." + member.Name),
                            };
                    }
                }
            }
        }

        public void LoadValue(FieldInfo field, bool checkAccessibility = true)
        {
            MemberInfo member = field;
            if (checkAccessibility) CheckAccessibility(ref member);
            if (member is PropertyInfo prop)
            {
                LoadValue(prop);
            }
            else
            {
                OpCode code = field.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld;
                il.Emit(code, field);
                TraceCompile(code + ": " + field + " on " + field.DeclaringType);
            }
        }

        public void StoreValue(FieldInfo field)
        {
            MemberInfo member = field;
            CheckAccessibility(ref member);
            if (member is PropertyInfo prop)
            {
                StoreValue(prop);
            }
            else
            {
                OpCode code = field.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld;
                il.Emit(code, field);
                TraceCompile(code + ": " + field + " on " + field.DeclaringType);
            }
        }

        public void LoadValue(PropertyInfo property)
        {
            MemberInfo member = property;
            CheckAccessibility(ref member);
            EmitCall(Helpers.GetGetMethod(property, true, true));
        }

        public void StoreValue(PropertyInfo property)
        {
            MemberInfo member = property;
            CheckAccessibility(ref member);
            EmitCall(Helpers.GetSetMethod(property, true, true));
        }

        //internal void EmitInstance()
        //{
        //    if (isStatic) throw new InvalidOperationException();
        //    Emit(OpCodes.Ldarg_0);
        //}

        internal static void LoadValue(ILGenerator il, int value)
        {
            switch (value)
            {
                case 0: il.Emit(OpCodes.Ldc_I4_0); break;
                case 1: il.Emit(OpCodes.Ldc_I4_1); break;
                case 2: il.Emit(OpCodes.Ldc_I4_2); break;
                case 3: il.Emit(OpCodes.Ldc_I4_3); break;
                case 4: il.Emit(OpCodes.Ldc_I4_4); break;
                case 5: il.Emit(OpCodes.Ldc_I4_5); break;
                case 6: il.Emit(OpCodes.Ldc_I4_6); break;
                case 7: il.Emit(OpCodes.Ldc_I4_7); break;
                case 8: il.Emit(OpCodes.Ldc_I4_8); break;
                case -1: il.Emit(OpCodes.Ldc_I4_M1); break;
                default:
                    if (value >= -128 && value <= 127)
                    {
                        il.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldc_I4, value);
                    }
                    break;
            }
        }

        private static bool UseShortForm(Local local)
            => local.Value.LocalIndex < 256;

        internal void LoadAddress(Local local, Type type, bool evenIfClass = false)
        {
            if (evenIfClass || type.IsValueType)
            {
                if (local is null)
                {
                    throw new InvalidOperationException("Cannot load the address of the head of the stack");
                }

                if (local == this.InputValue)
                {
                    il.Emit(OpCodes.Ldarga_S, _inputArg);
                    TraceCompile(OpCodes.Ldarga_S + ": $" + _inputArg);
                }
                else
                {
                    OpCode code = UseShortForm(local) ? OpCodes.Ldloca_S : OpCodes.Ldloca;
                    il.Emit(code, local.Value);
                    TraceCompile(code + ": $" + local.Value);
                }
            }
            else
            {   // reference-type; already *is* the address; just load it
                LoadValue(local);
            }
        }

        internal void Branch(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Br_S : OpCodes.Br;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        internal void BranchIfFalse(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Brfalse_S : OpCodes.Brfalse;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        internal void BranchIfTrue(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Brtrue_S : OpCodes.Brtrue;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        internal void BranchIfEqual(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Beq_S : OpCodes.Beq;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        //internal void TestEqual()
        //{
        //    Emit(OpCodes.Ceq);
        //}

        internal void CopyValue()
        {
            Emit(OpCodes.Dup);
        }

        internal void BranchIfGreater(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Bgt_S : OpCodes.Bgt;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        internal void BranchIfLess(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Blt_S : OpCodes.Blt;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        internal void DiscardValue()
        {
            Emit(OpCodes.Pop);
        }

        public void Subtract()
        {
            Emit(OpCodes.Sub);
        }

        public void Switch(CodeLabel[] jumpTable)
        {
            const int MAX_JUMPS = 128;

            if (jumpTable.Length <= MAX_JUMPS)
            {
                // simple case
                Label[] labels = new Label[jumpTable.Length];
                for (int i = 0; i < labels.Length; i++)
                {
                    labels[i] = jumpTable[i].Value;
                }
                TraceCompile(OpCodes.Switch.ToString());
                il.Emit(OpCodes.Switch, labels);
            }
            else
            {
                // too many to jump easily (especially on Android) - need to split up (note: uses a local pulled from the stack)
                using Local val = GetLocalWithValue(typeof(int), null);
                int count = jumpTable.Length, offset = 0;
                int blockCount = count / MAX_JUMPS;
                if ((count % MAX_JUMPS) != 0) blockCount++;

                Label[] blockLabels = new Label[blockCount];
                for (int i = 0; i < blockCount; i++)
                {
                    blockLabels[i] = il.DefineLabel();
                }
                CodeLabel endOfSwitch = DefineLabel();

                LoadValue(val);
                LoadValue(MAX_JUMPS);
                Emit(OpCodes.Div);
                TraceCompile(OpCodes.Switch.ToString());
                il.Emit(OpCodes.Switch, blockLabels);
                Branch(endOfSwitch, false);

                Label[] innerLabels = new Label[MAX_JUMPS];
                for (int blockIndex = 0; blockIndex < blockCount; blockIndex++)
                {
                    il.MarkLabel(blockLabels[blockIndex]);

                    int itemsThisBlock = Math.Min(MAX_JUMPS, count);
                    count -= itemsThisBlock;
                    if (innerLabels.Length != itemsThisBlock) innerLabels = new Label[itemsThisBlock];

                    int subtract = offset;
                    for (int j = 0; j < itemsThisBlock; j++)
                    {
                        innerLabels[j] = jumpTable[offset++].Value;
                    }
                    LoadValue(val);
                    if (subtract != 0) // switches are always zero-based
                    {
                        LoadValue(subtract);
                        Emit(OpCodes.Sub);
                    }
                    TraceCompile(OpCodes.Switch.ToString());
                    il.Emit(OpCodes.Switch, innerLabels);
                    if (count != 0)
                    { // force default to the very bottom
                        Branch(endOfSwitch, false);
                    }
                }
                Debug.Assert(count == 0, "Should use exactly all switch items");
                MarkLabel(endOfSwitch);
            }
        }

        internal void EndFinally()
        {
            il.EndExceptionBlock();
            TraceCompile("EndExceptionBlock");
        }

        internal void BeginFinally()
        {
            il.BeginFinallyBlock();
            TraceCompile("BeginFinallyBlock");
        }

        internal void EndTry(CodeLabel label, bool @short)
        {
            OpCode code = @short ? OpCodes.Leave_S : OpCodes.Leave;
            il.Emit(code, label.Value);
            TraceCompile(code + ": " + label.Index);
        }

        internal CodeLabel BeginTry()
        {
            CodeLabel label = new CodeLabel(il.BeginExceptionBlock(), nextLabel++);
            TraceCompile("BeginExceptionBlock: " + label.Index);
            return label;
        }

        internal void Constrain(Type type)
        {
            il.Emit(OpCodes.Constrained, type);
            TraceCompile(OpCodes.Constrained + ": " + type);
        }

        internal void TryCast(Type type)
        {
            il.Emit(OpCodes.Isinst, type);
            TraceCompile(OpCodes.Isinst + ": " + type);
        }

        internal void Cast(Type type)
        {
            il.Emit(OpCodes.Castclass, type);
            TraceCompile(OpCodes.Castclass + ": " + type);
        }

        public IDisposable Using(Local local)
        {
            return new UsingBlock(this, local);
        }

        private sealed class UsingBlock : IDisposable
        {
            private Local local;
            private CompilerContext ctx;
            private CodeLabel label;

            /// <summary>
            /// <para>
            /// Creates a new "using" block (equivalent) around a variable;
            /// the variable must exist, and note that (unlike in C#) it is
            /// the variables *final* value that gets disposed. If you need
            /// *original* disposal, copy your variable first.
            /// </para>
            /// <para>
            /// It is the callers responsibility to ensure that the variable's
            /// scope fully-encapsulates the "using"; if not, the variable
            /// may be re-used (and thus re-assigned) unexpectedly.
            /// </para>
            /// </summary>
            public UsingBlock(CompilerContext ctx, Local local)
            {
                if (local is null) throw new ArgumentNullException(nameof(local));

                Type type = local.Type;
                // check if **never** disposable
                if ((type.IsValueType || type.IsSealed)
                    && !typeof(IDisposable).IsAssignableFrom(type))
                {
                    return; // nothing to do! easiest "using" block ever
                    // (note that C# wouldn't allow this as a "using" block,
                    // but we'll be generous and simply not do anything)
                }
                this.local = local;
                this.ctx = ctx ?? throw new ArgumentNullException(nameof(ctx));
                label = ctx.BeginTry();
            }
            public void Dispose()
            {
                if (local is null || ctx is null) return;

                ctx.EndTry(label, false);
                ctx.BeginFinally();
                Type disposableType = typeof(IDisposable);
                MethodInfo dispose = disposableType.GetMethod("Dispose");
                Type type = local.Type;
                // remember that we've already (in the .ctor) excluded the case
                // where it *cannot* be disposable
                if (type.IsValueType)
                {
                    ctx.LoadAddress(local, type);
                    ctx.Constrain(type);
                    ctx.EmitCall(dispose);
                }
                else
                {
                    Compiler.CodeLabel @null = ctx.DefineLabel();
                    if (disposableType.IsAssignableFrom(type))
                    {   // *known* to be IDisposable; just needs a null-check                            
                        ctx.LoadValue(local);
                        ctx.BranchIfFalse(@null, true);
                        ctx.LoadAddress(local, type);
                    }
                    else
                    {   // *could* be IDisposable; test via "as"
                        using Compiler.Local disp = new Compiler.Local(ctx, disposableType);
                        ctx.LoadValue(local);
                        ctx.TryCast(disposableType);
                        ctx.CopyValue();
                        ctx.StoreValue(disp);
                        ctx.BranchIfFalse(@null, true);
                        ctx.LoadAddress(disp, disposableType);
                    }
                    ctx.EmitCall(dispose);
                    ctx.MarkLabel(@null);
                }
                ctx.EndFinally();
                this.local = null;
                this.ctx = null;
                label = new CodeLabel(); // default
            }
        }

        internal void Add()
        {
            Emit(OpCodes.Add);
        }

        internal void LoadLength(Local arr, bool zeroIfNull)
        {
            Debug.Assert(arr.Type.IsArray && arr.Type.GetArrayRank() == 1);

            if (zeroIfNull)
            {
                Compiler.CodeLabel notNull = DefineLabel(), done = DefineLabel();
                LoadValue(arr);
                CopyValue(); // optimised for non-null case
                BranchIfTrue(notNull, true);
                DiscardValue();
                LoadValue(0);
                Branch(done, true);
                MarkLabel(notNull);
                Emit(OpCodes.Ldlen);
                Emit(OpCodes.Conv_I4);
                MarkLabel(done);
            }
            else
            {
                LoadValue(arr);
                Emit(OpCodes.Ldlen);
                Emit(OpCodes.Conv_I4);
            }
        }

        internal void CreateArray(Type elementType, Local length)
        {
            LoadValue(length);
            il.Emit(OpCodes.Newarr, elementType);
            TraceCompile(OpCodes.Newarr + ": " + elementType);
        }

        internal void LoadArrayValue(Local arr, Local i)
        {
            Type type = arr.Type;
            Debug.Assert(type.IsArray && arr.Type.GetArrayRank() == 1);
            type = type.GetElementType();
            Debug.Assert(type is object, "Not an array: " + arr.Type.FullName);
            LoadValue(arr);
            LoadValue(i);
            switch (Helpers.GetTypeCode(type))
            {
                case ProtoTypeCode.SByte: Emit(OpCodes.Ldelem_I1); break;
                case ProtoTypeCode.Int16: Emit(OpCodes.Ldelem_I2); break;
                case ProtoTypeCode.Int32: Emit(OpCodes.Ldelem_I4); break;
                case ProtoTypeCode.Int64: Emit(OpCodes.Ldelem_I8); break;

                case ProtoTypeCode.Byte: Emit(OpCodes.Ldelem_U1); break;
                case ProtoTypeCode.UInt16: Emit(OpCodes.Ldelem_U2); break;
                case ProtoTypeCode.UInt32: Emit(OpCodes.Ldelem_U4); break;
                case ProtoTypeCode.UInt64: Emit(OpCodes.Ldelem_I8); break; // odd, but this is what C# does...

                case ProtoTypeCode.Single: Emit(OpCodes.Ldelem_R4); break;
                case ProtoTypeCode.Double: Emit(OpCodes.Ldelem_R8); break;
                default:
                    if (type.IsValueType)
                    {
                        il.Emit(OpCodes.Ldelema, type);
                        il.Emit(OpCodes.Ldobj, type);
                        TraceCompile(OpCodes.Ldelema + ": " + type);
                        TraceCompile(OpCodes.Ldobj + ": " + type);
                    }
                    else
                    {
                        Emit(OpCodes.Ldelem_Ref);
                    }

                    break;
            }
        }


        internal static void LoadValue(ILGenerator il, Type type)
        {
            il.Emit(OpCodes.Ldtoken, type);
            il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null);
        }
        internal void LoadValue(Type type)
        {
            il.Emit(OpCodes.Ldtoken, type);
            TraceCompile(OpCodes.Ldtoken + ": " + type);
            EmitCall(typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)));
        }

        internal void ConvertToInt32(ProtoTypeCode typeCode, bool uint32Overflow)
        {
            switch (typeCode)
            {
                case ProtoTypeCode.Byte:
                case ProtoTypeCode.SByte:
                case ProtoTypeCode.Int16:
                case ProtoTypeCode.UInt16:
                    Emit(OpCodes.Conv_I4);
                    break;
                case ProtoTypeCode.Int32:
                    break;
                case ProtoTypeCode.Int64:
                    Emit(OpCodes.Conv_Ovf_I4);
                    break;
                case ProtoTypeCode.UInt32:
                    Emit(uint32Overflow ? OpCodes.Conv_Ovf_I4_Un : OpCodes.Conv_Ovf_I4);
                    break;
                case ProtoTypeCode.UInt64:
                    Emit(OpCodes.Conv_Ovf_I4_Un);
                    break;
                default:
                    throw new InvalidOperationException("ConvertToInt32 not implemented for: " + typeCode.ToString());
            }
        }

        internal void ConvertFromInt32(ProtoTypeCode typeCode, bool uint32Overflow)
        {
            switch (typeCode)
            {
                case ProtoTypeCode.SByte: Emit(OpCodes.Conv_Ovf_I1); break;
                case ProtoTypeCode.Byte: Emit(OpCodes.Conv_Ovf_U1); break;
                case ProtoTypeCode.Int16: Emit(OpCodes.Conv_Ovf_I2); break;
                case ProtoTypeCode.UInt16: Emit(OpCodes.Conv_Ovf_U2); break;
                case ProtoTypeCode.Int32: break;
                case ProtoTypeCode.UInt32: Emit(uint32Overflow ? OpCodes.Conv_Ovf_U4 : OpCodes.Conv_U4); break;
                case ProtoTypeCode.Int64: Emit(OpCodes.Conv_I8); break;
                case ProtoTypeCode.UInt64: Emit(OpCodes.Conv_U8); break;
                default: throw new InvalidOperationException();
            }
        }

        internal void LoadValue(decimal value)
        {
            if (value == 0M)
            {
                LoadValue(typeof(decimal).GetField("Zero"));
            }
            else
            {
                int[] bits = decimal.GetBits(value);
                LoadValue(bits[0]); // lo
                LoadValue(bits[1]); // mid
                LoadValue(bits[2]); // hi
                LoadValue((int)(((uint)bits[3]) >> 31)); // isNegative (bool, but int for CLI purposes)
                LoadValue((bits[3] >> 16) & 0xFF); // scale (byte, but int for CLI purposes)

                EmitCtor(typeof(decimal), new Type[] { typeof(int), typeof(int), typeof(int), typeof(bool), typeof(byte) });
            }
        }

        internal void LoadValue(Guid value)
        {
            if (value == Guid.Empty)
            {
                LoadValue(typeof(Guid).GetField("Empty"));
            }
            else
            { // note we're adding lots of shorts/bytes here - but at the IL level they are I4, not I1/I2 (which barely exist)
                byte[] bytes = value.ToByteArray();
                int i = (bytes[0]) | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
                LoadValue(i);
                short s = (short)((bytes[4]) | (bytes[5] << 8));
                LoadValue(s);
                s = (short)((bytes[6]) | (bytes[7] << 8));
                LoadValue(s);
                for (i = 8; i <= 15; i++)
                {
                    LoadValue(bytes[i]);
                }
                EmitCtor(typeof(Guid), new Type[] { typeof(int), typeof(short), typeof(short),
                            typeof(byte), typeof(byte), typeof(byte), typeof(byte), typeof(byte), typeof(byte), typeof(byte), typeof(byte) });
            }
        }

        //internal void LoadValue(bool value)
        //{
        //    Emit(value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
        //}

        internal void LoadSerializationContext(Type asType) // old api = SerializationContext; new api = ISerializationContext
        {
            LoadState();
            switch (_signature)
            {
                case SignatureType.WriterScope_Input:
                    LoadValue(typeof(ProtoWriter.State).GetProperty(nameof(ProtoWriter.State.Context)));
                    break;
                case SignatureType.ReaderScope_Input:
                    LoadValue(typeof(ProtoReader.State).GetProperty(nameof(ProtoReader.State.Context)));
                    break;
                case SignatureType.Context:
                    LoadValue(InputValue);
                    break;
                default:
                    ThrowHelper.ThrowInvalidOperationException($"Cannot load context for {_signature}");
                    break;
            }
            if (asType == typeof(ISerializationContext))
            {
                // fine, done
            }
            else if (asType == typeof(SerializationContext))
            {
                EmitCall(typeof(SerializationContext).GetMethod(nameof(SerializationContext.AsSerializationContext)));
            }
            else if (asType == typeof(StreamingContext))
            {
                EmitCall(typeof(SerializationContext).GetMethod(nameof(SerializationContext.AsStreamingContext)));
            }
            else
            {
                ThrowHelper.ThrowArgumentException($"Unexpected context type: {asType.NormalizeName()}");
            }
        }

        internal bool AllowInternal(PropertyInfo property)
        {
            return NonPublic || InternalsVisible(property.DeclaringType.Assembly);
        }
    }
}

<|start_filename|>src/Examples/Issues/SO64101495.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using ProtoBuf.Serializers;
using ProtoBuf.WellKnownTypes;
using System;
using System.IO;
using System.Net;
using Xunit;
using Xunit.Abstractions;

namespace ProtoBuf.Issues
{
    public class SO64101495
    {
        /*
         Verify 4 different ways of mapping a type to a primitive

        1. via AllowParseableTypes (let the engine handle the parse/format)
        2. via SetSurrogate (explicitly provide the conversion)
        3. via SerializerType (write our own serializer)
        4. via a separate DTO that matches what we want to serialize (baseline)
        */

        public SO64101495(ITestOutputHelper log)
            => Log = log;
        private readonly ITestOutputHelper Log;

        [Fact]
        public void RoundTripIPAddessViaParseable()
        {
            var model = RuntimeTypeModel.Create();
            model.AllowParseableTypes = true;

            var schema = model.GetSchema(typeof(Example));
            Log?.WriteLine(schema);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Issues;
import ""google/protobuf/timestamp.proto"";

message Example {
   .google.protobuf.Timestamp Date = 1;
   string Ip = 2;
   string ExampleDescription = 3;
}
", schema, ignoreLineEndingDifferences: true);

            var obj = new Example { Date = When, Ip = IPAddress.Parse(TestIPAddress), ExampleDescription = "foo" };
            Assert.Equal(ExpectedHex, GetHex(model, obj));
            var clone = model.DeepClone(obj);
            Assert.NotSame(obj, clone);
            Assert.Equal(obj.Date, clone.Date);
            Assert.Equal(obj.Ip, clone.Ip);
            Assert.Equal(obj.ExampleDescription, clone.ExampleDescription);
        }

        [Fact]
        public void RoundTripIPAddessViaSurrogate()
        {
            var model = RuntimeTypeModel.Create();
            model.SetSurrogate<IPAddress, string>(IPAddressFormat, IPAddressParse);

            var schema = model.GetSchema(typeof(Example));
            Log?.WriteLine(schema);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Issues;
import ""google/protobuf/timestamp.proto"";

message Example {
   .google.protobuf.Timestamp Date = 1;
   string Ip = 2;
   string ExampleDescription = 3;
}
", schema, ignoreLineEndingDifferences: true);

            var obj = new Example { Date = When, Ip = IPAddress.Parse(TestIPAddress), ExampleDescription = "foo" };
            Assert.Equal(ExpectedHex, GetHex(model, obj));
            var clone = model.DeepClone(obj);
            Assert.NotSame(obj, clone);
            Assert.Equal(obj.Date, clone.Date);
            Assert.Equal(obj.Ip, clone.Ip);
            Assert.Equal(obj.ExampleDescription, clone.ExampleDescription);
        }

        public static string IPAddressFormat(IPAddress value) => value?.ToString();
        public static IPAddress IPAddressParse(string value) => value is null ? null : IPAddress.Parse(value);

        [Fact]
        public void RoundTripIPAddessViaCustomSerializer()
        {
            var model = RuntimeTypeModel.Create();
            var mt = model.Add<IPAddress>(false);
            mt.SerializerType = typeof(IPAddressSerializer);
            mt.Name = "string";

            var schema = model.GetSchema(typeof(Example));
            Log?.WriteLine(schema);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Issues;
import ""google/protobuf/timestamp.proto"";

message Example {
   .google.protobuf.Timestamp Date = 1;
   string Ip = 2;
   string ExampleDescription = 3;
}
", schema, ignoreLineEndingDifferences: true);

            var obj = new Example { Date = When, Ip = IPAddress.Parse(TestIPAddress), ExampleDescription = "foo" };
            Assert.Equal(ExpectedHex, GetHex(model, obj));
            var clone = model.DeepClone(obj);
            Assert.NotSame(obj, clone);
            Assert.Equal(obj.Date, clone.Date);
            Assert.Equal(obj.Ip, clone.Ip);
            Assert.Equal(obj.ExampleDescription, clone.ExampleDescription);
        }

        [Fact]
        public void RoundTripIPAddessEffectiveCompat()
        {
            var model = RuntimeTypeModel.Create();
            var schema = model.GetSchema(typeof(EffectiveExample));
            Log?.WriteLine(schema);
            Assert.Equal(@"syntax = ""proto3"";
package ProtoBuf.Issues;
import ""google/protobuf/timestamp.proto"";

message Example {
   .google.protobuf.Timestamp Date = 1;
   string Ip = 2;
   string ExampleDescription = 3;
}
", schema, ignoreLineEndingDifferences: true);

            var obj = new EffectiveExample { Date = When, Ip = TestIPAddress, ExampleDescription = "foo" };
            var hex = GetHex(model, obj);
            Log?.WriteLine(hex);
            Assert.Equal(ExpectedHex, hex);
            var clone = model.DeepClone(obj);
            Assert.NotSame(obj, clone);
            Assert.Equal(obj.Date, clone.Date);
            Assert.Equal(obj.Ip, clone.Ip);
            Assert.Equal(obj.ExampleDescription, clone.ExampleDescription);
        }

        static string GetHex<T>(TypeModel model, T value)
        {
            using var ms = new MemoryStream();
            model.Serialize(ms, value);
            return BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
        }

        private static readonly DateTime When = new DateTime(2020, 10, 1, 8, 0, 0, DateTimeKind.Utc);
        private const string
            TestIPAddress = "172.16.58.3",
            ExpectedHex = @"0A-06-08-80-99-D6-FB-05-12-0D-31-31-34-2E-34-33-2E-33-32-2E-31-34-35-1A-03-66-6F-6F";

        public sealed class IPAddressSerializer : ISerializer<IPAddress>
        {
            SerializerFeatures ISerializer<IPAddress>.Features => SerializerFeatures.CategoryScalar | SerializerFeatures.WireTypeString;

            IPAddress ISerializer<IPAddress>.Read(ref ProtoReader.State state, IPAddress value)
                => IPAddressParse(state.ReadString());

            void ISerializer<IPAddress>.Write(ref ProtoWriter.State state, IPAddress value)
                => state.WriteString(IPAddressFormat(value));
        }

        [ProtoContract]
        [CompatibilityLevel(CompatibilityLevel.Level300)] // use timestamp.proto for Date
        public class Example
        {
            [ProtoMember(1)]
            public DateTime Date { get; set; }
            [ProtoMember(2)]
            public IPAddress Ip { get; set; }
            [ProtoMember(3)]
            public string ExampleDescription { get; set; }
        }

        [ProtoContract(Name = "Example")]
        public class EffectiveExample
        {
            [ProtoMember(1)]
            public Timestamp Date { get; set; }
            [ProtoMember(2)]
            public string Ip { get; set; }
            [ProtoMember(3)]
            public string ExampleDescription { get; set; }
        }
    }
}


<|start_filename|>src/protobuf-net.Reflection/CustomOptions.cs<|end_filename|>
// <auto-generated>
//   This file was generated by a tool; you should avoid making direct changes.
//   Consider using 'partial classes' to extend these types
//   Input: my.proto
// </auto-generated>

#region Designer generated code
#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
using ProtoBuf.Meta;
using ProtoBuf.Reflection.Internal;

namespace ProtoBuf.Reflection
{

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenFileOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"namespace")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Namespace { get; set; } = "";

        [global::ProtoBuf.ProtoMember(2, Name = @"access")]
        public Access Access { get; set; }

        [global::ProtoBuf.ProtoMember(3, Name = @"extensions")]
        [global::System.ComponentModel.DefaultValue("")]
        public string ExtensionTypeName { get; set; } = "";

        [global::ProtoBuf.ProtoMember(4, Name = @"csharp_langver")]
        [global::System.ComponentModel.DefaultValue("")]
        public string CSharpLanguageVersion { get; set; } = "";

        [global::ProtoBuf.ProtoMember(5, Name = @"requiredDefaults")]
        public bool EmitRequiredDefaults { get; set; }

        [global::ProtoBuf.ProtoMember(6, Name = @"oneofEnum")]
        public bool EmitOneOfEnum { get; set; }

        [global::ProtoBuf.ProtoMember(7, Name = @"vb_langver")]
        [global::System.ComponentModel.DefaultValue("")]
        public string VisualBasicLanguageVersion { get; set; } = "";

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenMessageOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

        [global::ProtoBuf.ProtoMember(2, Name = @"access")]
        public Access Access { get; set; }

        [global::ProtoBuf.ProtoMember(3, Name = @"extensions")]
        [global::System.ComponentModel.DefaultValue("")]
        public string ExtensionTypeName { get; set; } = "";

        [global::ProtoBuf.ProtoMember(4, Name = @"namespace")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Namespace { get; set; } = "";

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenFieldOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

        [global::ProtoBuf.ProtoMember(2, Name = @"access")]
        public Access Access { get; set; }

        [global::ProtoBuf.ProtoMember(3, Name = @"asRef")]
        public bool AsReference { get; set; }

        [global::ProtoBuf.ProtoMember(4, Name = @"dynamicType")]
        public bool DynamicType { get; set; }

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenEnumOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

        [global::ProtoBuf.ProtoMember(2, Name = @"access")]
        public Access Access { get; set; }

        [global::ProtoBuf.ProtoMember(3, Name = @"namespace")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Namespace { get; set; } = "";

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenEnumValueOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenServiceOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

        [global::ProtoBuf.ProtoMember(2, Name = @"access")]
        public Access Access { get; set; }

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenMethodOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

    }

    [global::ProtoBuf.ProtoContract()]
    public partial class ProtogenOneofOptions : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"name")]
        [global::System.ComponentModel.DefaultValue("")]
        public string Name { get; set; } = "";

        [global::ProtoBuf.ProtoMember(2, Name = @"isSubType")]
        public bool IsSubType { get; set; }

    }

    [global::ProtoBuf.ProtoContract()]
    public enum Access
    {
        [global::ProtoBuf.ProtoEnum(Name = @"INHERIT")]
        Inherit = 0,
        [global::ProtoBuf.ProtoEnum(Name = @"PUBLIC")]
        Public = 1,
        [global::ProtoBuf.ProtoEnum(Name = @"PRIVATE")]
        Private = 2,
        [global::ProtoBuf.ProtoEnum(Name = @"INTERNAL")]
        Internal = 3,
    }

    public static partial class Extensions
    {
        private static TypeModel Serializer => CustomProtogenSerializer.Instance;
        public static ProtogenFileOptions GetOptions(this global::Google.Protobuf.Reflection.FileOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenFileOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.FileOptions obj, ProtogenFileOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenFileOptions>(Serializer, obj, 1037, value);

        public static ProtogenMessageOptions GetOptions(this global::Google.Protobuf.Reflection.MessageOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenMessageOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.MessageOptions obj, ProtogenMessageOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenMessageOptions>(Serializer, obj, 1037, value);

        public static ProtogenFieldOptions GetOptions(this global::Google.Protobuf.Reflection.FieldOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenFieldOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.FieldOptions obj, ProtogenFieldOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenFieldOptions>(Serializer, obj, 1037, value);

        public static ProtogenEnumOptions GetOptions(this global::Google.Protobuf.Reflection.EnumOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenEnumOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.EnumOptions obj, ProtogenEnumOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenEnumOptions>(Serializer, obj, 1037, value);

        public static ProtogenEnumValueOptions GetOptions(this global::Google.Protobuf.Reflection.EnumValueOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenEnumValueOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.EnumValueOptions obj, ProtogenEnumValueOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenEnumValueOptions>(Serializer, obj, 1037, value);

        public static ProtogenServiceOptions GetOptions(this global::Google.Protobuf.Reflection.ServiceOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenServiceOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.ServiceOptions obj, ProtogenServiceOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenServiceOptions>(Serializer, obj, 1037, value);

        public static ProtogenMethodOptions GetOptions(this global::Google.Protobuf.Reflection.MethodOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenMethodOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.MethodOptions obj, ProtogenMethodOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenMethodOptions>(Serializer, obj, 1037, value);

        public static ProtogenOneofOptions GetOptions(this global::Google.Protobuf.Reflection.OneofOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<ProtogenOneofOptions>(Serializer, obj, 1037);

        public static void SetOptions(this global::Google.Protobuf.Reflection.OneofOptions obj, ProtogenOneofOptions value)
            => global::ProtoBuf.Extensible.AppendValue<ProtogenOneofOptions>(Serializer, obj, 1037, value);

    }
}

#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
#endregion


<|start_filename|>src/Benchmark/VarintEncodeBenchmarks.cs<|end_filename|>
﻿#if INTRINSICS
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using System;
using System.Numerics;

namespace Benchmark
{
    [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
    [SimpleJob(RuntimeMoniker.Net472), SimpleJob(RuntimeMoniker.NetCoreApp31), SimpleJob(RuntimeMoniker.NetCoreApp50)]
    public class VarintEncodeBenchmarks
    {
        const int LOOP_SIZE = 2048;
        readonly uint[] _values32 = new uint[LOOP_SIZE];
        readonly ulong[] _values64 = new ulong[LOOP_SIZE];

        [GlobalSetup]
        public void Setup()
        {
            var rand = new Random(12345);
            Span<byte> spanLzcnt = stackalloc byte[16];
            Span<byte> spanLoop = stackalloc byte[16];
            for (int i = 0; i < LOOP_SIZE; i++)
            {
                if (i < (LOOP_SIZE / 4))
                {   // 1 byte
                    _values32[i] = (uint)rand.Next(0xFF);
                    _values64[i] = (ulong)rand.Next(0xFF);
                }
                else if (i < (LOOP_SIZE / 2))
                {   // 2 bytes
                    _values32[i] = (uint)rand.Next(0xFFFF);
                    _values64[i] = (ulong)rand.Next(0xFFFF);
                }
                else if (i < ((3 * LOOP_SIZE) / 4))
                {   // non-negative full-width
                    _values32[i] = (uint)rand.Next();
                    _values64[i] = (ulong)(((long)rand.Next()) << 32
                        | (long)rand.Next(int.MinValue, int.MaxValue));
                }
                else
                {
                    // possibly-negative full-width
                    _values32[i] = (uint)rand.Next(int.MinValue, int.MaxValue);
                    _values64[i] = (ulong)(((long)rand.Next(int.MinValue, int.MaxValue)) << 32
                        | (long)rand.Next(int.MinValue, int.MaxValue));
                }

                int lzcnt = ComputeVarintLength32_Lzcnt(_values32[i]);
                int loop = ComputeVarintLength32_Loop(_values32[i]);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"32-len: {_values32[i]}, expected {loop}, got {lzcnt}");

                lzcnt = ComputeVarintLength64_Lzcnt(_values64[i]);
                loop = ComputeVarintLength64_Loop(_values64[i]);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"64-len: {_values64[i]}, expected {loop}, got {lzcnt}");

                lzcnt = WriteVarint32_Lzcnt(_values32[i], spanLzcnt, 4);
                loop = WriteVarint32_Loop(_values32[i], spanLoop, 4);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"32-write: {_values32[i]}, expected {loop}, got {lzcnt}");
                if (!spanLzcnt.Slice(4, lzcnt).SequenceEqual(spanLoop.Slice(4, loop)))
                    throw new InvalidOperationException($"32-write: spans are different");

                loop = WriteVarint32_Loop_Ptr(_values32[i], spanLoop, 4);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"32-write: {_values32[i]}, expected {lzcnt}, got {loop}");
                if (!spanLzcnt.Slice(4, lzcnt).SequenceEqual(spanLoop.Slice(4, loop)))
                    throw new InvalidOperationException($"32-write (ptr): spans are different");

                loop = WriteVarint32_Loop_Ptr_PreNext(_values32[i], spanLoop, 4);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"32-write: {_values32[i]}, expected {lzcnt}, got {loop}");
                if (!spanLzcnt.Slice(4, lzcnt).SequenceEqual(spanLoop.Slice(4, loop)))
                    throw new InvalidOperationException($"32-write (ptr/pre): spans are different");

                loop = WriteVarint32_Loop_PreNext(_values32[i], spanLoop, 4);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"32-write: {_values32[i]}, expected {lzcnt}, got {loop}");
                if (!spanLzcnt.Slice(4, lzcnt).SequenceEqual(spanLoop.Slice(4, loop)))
                    throw new InvalidOperationException($"32-write (pre): spans are different");

                lzcnt = WriteVarint64_Lzcnt(_values64[i], spanLzcnt, 4);
                loop = WriteVarint64_Loop(_values64[i], spanLoop, 4);
                if (lzcnt != loop)
                    throw new InvalidOperationException($"64-write: {_values64[i]}, expected {loop}, got {lzcnt}");
                if (!spanLzcnt.Slice(4, lzcnt).SequenceEqual(spanLoop.Slice(4, loop)))
                    throw new InvalidOperationException($"64-write: spans are different");
            }
        }

        [BenchmarkCategory("Length")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void ComputeVarintLength32_Loop()
        {
            var arr = _values32;
            for (int i = 0; i < arr.Length; i++)
                ComputeVarintLength32_Loop(arr[i]);
        }

        [BenchmarkCategory("Length")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void ComputeVarintLength64_Loop()
        {
            var arr = _values64;
            for (int i = 0; i < arr.Length; i++)
                ComputeVarintLength64_Loop(arr[i]);
        }

        [BenchmarkCategory("Length")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void ComputeVarintLength32_Lzcnt()
        {
            var arr = _values32;
            for (int i = 0; i < arr.Length; i++)
                ComputeVarintLength32_Lzcnt(arr[i]);
        }

        [BenchmarkCategory("Length")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void ComputeVarintLength64_Lzcnt()
        {
            var arr = _values64;
            for (int i = 0; i < arr.Length; i++)
                ComputeVarintLength64_Lzcnt(arr[i]);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode32_Loop()
        {
            var arr = _values32;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint32_Loop(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode32_Loop_PreNext()
        {
            var arr = _values32;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint32_Loop_PreNext(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode32_Loop_Ptr()
        {
            var arr = _values32;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint32_Loop_Ptr(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode32_Loop_Ptr_PreNext()
        {
            var arr = _values32;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint32_Loop_Ptr_PreNext(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode32_Lzcnt()
        {
            var arr = _values32;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint32_Lzcnt(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode32_Lzcnt_Ptr()
        {
            var arr = _values32;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint32_Lzcnt_Ptr(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode64_Loop()
        {
            var arr = _values64;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint64_Loop(arr[i], span, 4);
        }

        [BenchmarkCategory("Encode")]
        [Benchmark(OperationsPerInvoke = LOOP_SIZE)]
        public void Encode64_Lzcnt()
        {
            var arr = _values64;
            Span<byte> span = stackalloc byte[16];
            for (int i = 0; i < arr.Length; i++)
                WriteVarint64_Lzcnt(arr[i], span, 4);
        }

        // deliberately not static/aggressive-inline; in real impl, this
        // is an override on a virtual method
        int ComputeVarintLength32_Lzcnt(uint value)
            => ((31 - BitOperations.LeadingZeroCount(value | 1)) / 7) + 1;

        int ComputeVarintLength32_Loop(uint value)
        {
            int count = 1;
            while ((value >>= 7) != 0)
            {
                count++;
            }
            return count;
        }

        int ComputeVarintLength64_Lzcnt(ulong value)
            => ((63 - BitOperations.LeadingZeroCount(value | 1)) / 7) + 1;

        int ComputeVarintLength64_Loop(ulong value)
        {
            int count = 1;
            while ((value >>= 7) != 0)
            {
                count++;
            }
            return count;
        }

        internal int WriteVarint64_Loop(ulong value, Span<byte> span, int index)
        {
            int count = 0;
            do
            {
                span[index++] = (byte)((value & 0x7F) | 0x80);
                count++;
            } while ((value >>= 7) != 0);
            span[index - 1] &= 0x7F;
            return count;
        }

        internal int WriteVarint32_Loop(uint value, Span<byte> span, int index)
        {
            int origIndex = index;
            do
            {
                span[index++] = (byte)((value & 0x7F) | 0x80);
            } while ((value >>= 7) != 0);
            span[index - 1] &= 0x7F;
            return index - origIndex;
        }

        internal int WriteVarint32_Loop_PreNext(uint value, Span<byte> span, int index)
        {
            int origIndex = index;
            uint next;
            while ((next = value >> 7) != 0)
            {
                span[index++] = (byte)((value & 0x7F) | 0x80);
                value = next;
            }
            span[index] = (byte)value;
            return 1 + index - origIndex;
        }

        internal unsafe int WriteVarint32_Loop_Ptr(uint value, Span<byte> span, int index)
        {
            fixed (byte* spanPtr = span)
            {
                byte* origPtr = spanPtr + index, ptr = origPtr;
                do
                {
                    *ptr++ = (byte)((value & 0x7F) | 0x80);
                } while ((value >>= 7) != 0);
                *(ptr - 1) &= 0x7F;
                return (int)(ptr - origPtr);
            }
        }

        internal unsafe int WriteVarint32_Loop_Ptr_PreNext(uint value, Span<byte> span, int index)
        {
            fixed (byte* spanPtr = span)
            {
                byte* origPtr = spanPtr + index, ptr = origPtr;
                uint next;
                while ((next = value >> 7) != 0)
                {
                    *ptr++ = (byte)((value & 0x7F) | 0x80);
                    value = next;
                }
                *ptr = (byte)value;
                return 1 + (int)(ptr - origPtr);
            }
        }

        internal int WriteVarint32_Lzcnt(uint value, Span<byte> span, int index)
        {
            if ((value & ~(uint)0x7F) == 0)
            {
                span[index] = (byte)value;
                return 1;
            }
            switch ((31 - BitOperations.LeadingZeroCount(value | 1)) / 7)
            {
                case 1:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 7);
                    return 2;
                case 2:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 14);
                    return 3;
                case 3:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 21);
                    return 4;
                default:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 28);
                    return 5;
            }
        }

        internal unsafe int WriteVarint32_Lzcnt_Ptr(uint value, Span<byte> span, int index)
        {
            fixed (byte* spanPtr = span)
            {
                byte* ptr = spanPtr + index;
                switch ((31 - BitOperations.LeadingZeroCount(value | 1)) / 7)
                {
                    case 0:
                        *ptr = (byte)value;
                        return 1;
                    case 1:
                        *ptr++ = (byte)((value & 0x7F) | 0x80);
                        *ptr = (byte)(value >> 7);
                        return 2;
                    case 2:
                        *ptr++ = (byte)((value & 0x7F) | 0x80);
                        *ptr++ = (byte)(((value >> 7) & 0x7F) | 0x80);
                        *ptr = (byte)(value >> 14);
                        return 3;
                    case 3:
                        *ptr++ = (byte)((value & 0x7F) | 0x80);
                        *ptr++ = (byte)(((value >> 7) & 0x7F) | 0x80);
                        *ptr++ = (byte)(((value >> 14) & 0x7F) | 0x80);
                        *ptr = (byte)(value >> 21);
                        return 4;
                    default:
                        *ptr++ = (byte)((value & 0x7F) | 0x80);
                        *ptr++ = (byte)(((value >> 7) & 0x7F) | 0x80);
                        *ptr++ = (byte)(((value >> 14) & 0x7F) | 0x80);
                        *ptr++ = (byte)(((value >> 21) & 0x7F) | 0x80);
                        *ptr = (byte)(value >> 28);
                        return 5;
                }
            }
        }

        internal int WriteVarint64_Lzcnt(ulong value, Span<byte> span, int index)
        {
            switch ((63 - BitOperations.LeadingZeroCount(value | 1)) / 7)
            {
                case 0:
                    span[index] = (byte)value;
                    return 1;
                case 1:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 7);
                    return 2;
                case 2:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 14);
                    return 3;
                case 3:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 21);
                    return 4;
                case 4:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 28);
                    return 5;
                case 5:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 28) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 35);
                    return 6;
                case 6:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 28) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 35) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 42);
                    return 7;
                case 7:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 28) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 35) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 42) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 49);
                    return 8;
                case 8:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 28) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 35) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 42) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 49) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 56);
                    return 9;
                default:
                    span[index++] = (byte)((value & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 7) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 14) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 21) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 28) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 35) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 42) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 49) & 0x7F) | 0x80);
                    span[index++] = (byte)(((value >> 56) & 0x7F) | 0x80);
                    span[index] = (byte)(value >> 63);
                    return 10;
            }
        }
    }
}
#endif

<|start_filename|>src/BuildToolsUnitTests/ServiceContractAnalyzerTests.cs<|end_filename|>
﻿using Microsoft.CodeAnalysis;
using ProtoBuf.BuildTools.Analyzers;
using System.Globalization;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace BuildToolsUnitTests
{
    public class ServiceAnalyzerTests : AnalyzerTestBase<ServiceContractAnalyzer>
    {
        public ServiceAnalyzerTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }

        [Fact]
        public async Task CleanForUnrelatedContract()
        {
            var diagnostics = await AnalyzeAsync(@"
public interface IMyService
{
    public void Bar();
}");
            Assert.Empty(diagnostics);
        }

        protected override Project SetupProject(Project project)
        {
            // add a modified snapshot from https://github.com/protobuf-net/protobuf-net.Grpc/blob/main/src/protobuf-net.Grpc/Configuration/ServiceAttribute.cs
            // since we can't add a project reference without getting into a complete mess
            return project.AddDocument("ServiceAttribute.cs", @"
using System;

namespace ProtoBuf.Grpc.Configuration
{
    /// <summary>
    /// Explicitly indicates that an interface represents a gRPC service
    /// </summary>
    [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
    public sealed class ServiceAttribute : Attribute
    {
        /// <summary>
        /// The name of the service
        /// </summary>
        public string Name { get; }
        /// <summary>
        /// Create a new instance of the attribute
        /// </summary>
        public ServiceAttribute(string name = null)
            => Name = name;
    }
}").Project;
        }

        [Fact]
        public async Task DetectInvalidMethodKind()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
namespace SomeNamespace.Whatever
{
    public static class ContainingType
    {
        [Service]
        public interface IMyService
        {
            Foo Property {get;}
        }
        [ProtoContract]
        public class Foo {}
    }
}");
            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidMemberKind, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("This member is not a method; only methods are supported for gRPC services.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task ValidMethodKindIsClean()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;

[Service]
public interface IMyService
{
    Foo BasicMethod(Foo value);
}
[ProtoContract]
public class Foo {}");

            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task GenericMethodDetected()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;

[Service]
public interface IMyService
{
    Foo BasicMethod<T>(Foo value);
}
[ProtoContract]
public class Foo {}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.GenericMethod, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The gRPC method can not be generic.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task GenericServiceDetected()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;

[Service]
public interface IMyService<T>
{
    Foo BasicMethod(Foo value);
}
[ProtoContract]
public class Foo {}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.GenericService, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The gRPC service can not be generic.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task NestedGenericServiceDetected()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;

public class Foo<T> where T : class
{
    [Service]
    public interface IMyService
    {
        Foo BasicMethod(Foo value);
    }
}
[ProtoContract]
public class Foo {}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.GenericService, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The gRPC service can not be generic.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("int")]
        [InlineData("Task<int>")]
        [InlineData("Task<Task<Foo>>")]
        [InlineData("ValueTask<ValueTask<Foo>>")]
        [InlineData("ValueTask<int>")]
        [InlineData("IAsyncEnumerable<int>")]
        public async Task DetectInvalidReturnTypes(string kind)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Collections.Generic;
using System.Threading.Tasks;

[Service]
public interface IMyService
{{
    {kind} BasicMethod(Foo value);
}}
[ProtoContract]
public class Foo {{}}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidReturnType, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The return value of a gRPC method must currently be Void, a reference-type data contract, or an task / async sequence of the same.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("Foo foo")]
        [InlineData("IAsyncEnumerable<Foo> foos")]
        [InlineData("")]
        public async Task DetectValidParameterKinds(string? kind)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Collections.Generic;
using System.Threading.Tasks;

[Service]
public interface IMyService
{{
    ValueTask<Foo> BasicMethod({kind});
}}
[ProtoContract]
public class Foo {{}}");

            Assert.Empty(diagnostics);
        }

        [Theory]
        [InlineData("ValueTask pending")]
        [InlineData("Task pending")]
        [InlineData("int value")]
        [InlineData("string value")]
        public async Task DetectInvalidParameterKinds(string? kind)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Threading.Tasks;

[Service]
public interface IMyService
{{
    Foo BasicMethod({kind});
}}
[ProtoContract]
public class Foo {{}}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidPayloadType, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The data parameter of a gRPC method must currently be Void, a reference-type data contract, or an async sequence of the same.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("Foo")]
        [InlineData("IAsyncEnumerable<Foo>")]
        [InlineData("void")]
        [InlineData("Task")]
        [InlineData("ValueTask")]
        public async Task DetectValidReturnKinds(string? kind)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Collections.Generic;
using System.Threading.Tasks;

[Service]
public interface IMyService
{{
    {kind} BasicMethod(Foo foo);
}}
[ProtoContract]
public class Foo {{}}");

            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DetectMultipleContext()
        {
            var diagnostics = await AnalyzeAsync(@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using ProtoBuf.Grpc;
using System.Threading.Tasks;
using System.Threading;

[Service]
public interface IMyService
{
    Foo BasicMethod(CancellationToken x, CallContext y);
}
[ProtoContract]
public class Foo {}

// hacking this in
namespace ProtoBuf.Grpc {
    public struct CallContext {}
}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidPayloadType, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The data parameter of a gRPC method must currently be Void, a reference-type data contract, or an async sequence of the same.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DetectMultipleDataParameter_NoContext()
        {
            var diagnostics = await AnalyzeAsync(@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Threading.Tasks;

[Service]
public interface IMyService
{
    Foo BasicMethod(Foo x, Foo y);
}
[ProtoContract]
public class Foo {}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidParameters, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("Invalid signature; gRPC methods expect a single optional payload and a single optional context.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DetectMultipleDataParameter_Context()
        {
            var diagnostics = await AnalyzeAsync(@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Threading.Tasks;
using System.Threading;

[Service]
public interface IMyService
{
    Foo BasicMethod(Foo x, Foo y, CancellationToken token);
}
[ProtoContract]
public class Foo {}");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidParameters, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("Invalid signature; gRPC methods expect a single optional payload and a single optional context.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("CallOptions")]
        [InlineData("ServerCallContext")]
        public async Task DetectInvalidContext(string kind)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using Grpc.Core;
using ProtoBuf;
using System.Threading.Tasks;

[Service]
public interface IMyService
{{
    Foo BasicMethod(Foo x, {kind} ctx);
}}
[ProtoContract]
public class Foo {{}}

// hacking these in
namespace Grpc.Core {{
    public struct CallOptions {{}}
    public class ServerCallContext {{}}
}}
");

            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.InvalidContextType, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("The context parameter of a gRPC method must be CallContext or CancellationToken.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("CancellationToken")]
        [InlineData("CallContext")]
        public async Task DetectValidContext(string kind)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using ProtoBuf.Grpc;
using System.Threading.Tasks;
using System.Threading;

[Service]
public interface IMyService
{{
    Foo BasicMethod(Foo x, {kind} ctx);
}}
[ProtoContract]
public class Foo {{}}

// hacking this in
namespace ProtoBuf.Grpc {{
    public struct CallContext {{}}
}}");

            Assert.Empty(diagnostics);
        }

        [Fact]
        public async Task DetectNonSerializable_Both()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;

[Service]
public interface IMyService
{
    Foo SomeMethod(Foo value);
}
public class Foo {}
");
            var err = Assert.Single(diagnostics); // assert not double-reported
            Assert.Equal(ServiceContractAnalyzer.PossiblyNotSerializable, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Warning, err.Severity);
            Assert.Equal("gRPC methods require inputs/outputs that can be marshalled with gRPC; this type *may* be usable with gRPC, but it could not be verified.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DetectNonSerializable_Payload()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
[Service]
public interface IMyService
{
    Bar SomeMethod(Foo value);
}
public class Foo {}
[ProtoContract]
public class Bar {}
");
            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.PossiblyNotSerializable, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Warning, err.Severity);
            Assert.Equal("gRPC methods require inputs/outputs that can be marshalled with gRPC; this type *may* be usable with gRPC, but it could not be verified.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Fact]
        public async Task DetectNonSerializable_Return()
        {
            var diagnostics = await AnalyzeAsync(@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
[Service]
public interface IMyService
{
    Bar SomeMethod(Foo value);
}
[ProtoContract]
public class Foo {}
public class Bar {}
");
            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.PossiblyNotSerializable, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Warning, err.Severity);
            Assert.Equal("gRPC methods require inputs/outputs that can be marshalled with gRPC; this type *may* be usable with gRPC, but it could not be verified.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("Foo Method();")]
        [InlineData("void Method();")]
        public async Task DetectSync(string signature)
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
[Service]
public interface IMyService
{{
    {signature}
}}
[ProtoContract]
public class Foo {{}}
", ignorePreferAsyncAdvice: false);
            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.PreferAsync, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Info, err.Severity);
            Assert.Equal("gRPC methods should be async when possible.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("Foo Method(IAsyncEnumerable<Foo> foos);")]
        [InlineData("void Method(IAsyncEnumerable<Foo> foos);")]
        public async Task DetectStreamingSync(string signature)
        {
            var diagnostics = await AnalyzeAsync($@"
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Collections.Generic;
[Service]
public interface IMyService
{{
    {signature}
}}
[ProtoContract]
public class Foo {{}}
", ignorePreferAsyncAdvice: false);
            var err = Assert.Single(diagnostics);
            Assert.Equal(ServiceContractAnalyzer.StreamingSyncMethod, err.Descriptor);
            Assert.Equal(DiagnosticSeverity.Error, err.Severity);
            Assert.Equal("gRPC methods that take streaming parameters cannot be synchronous.", err.GetMessage(CultureInfo.InvariantCulture));
        }

        [Theory]
        [InlineData("Task<Foo> Method();")]
        [InlineData("ValueTask<Foo> Method();")]
        [InlineData("IAsyncEnumerable<Foo> Method();")]
        [InlineData("Task<Foo> Method(IAsyncEnumerable<Foo> foos);")]
        [InlineData("ValueTask<Foo> Method(IAsyncEnumerable<Foo> foos);")]
        [InlineData("IAsyncEnumerable<Foo> Method(IAsyncEnumerable<Foo> foos);")]
        [InlineData("Task<Foo> Method(Foo foo);")]
        [InlineData("ValueTask<Foo> Method(Foo foo);")]
        [InlineData("IAsyncEnumerable<Foo> Method(Foo foo);")]
        public async Task DetectAsync(string signature)
        {
            var diagnostics = await AnalyzeAsync($@"
#pragma warning disable CS8019
using ProtoBuf.Grpc.Configuration;
using ProtoBuf;
using System.Threading.Tasks;
using System.Collections.Generic;
[Service]
public interface IMyService
{{
    {signature}
}}
[ProtoContract]
public class Foo {{}}
", ignorePreferAsyncAdvice: false);
            Assert.Empty(diagnostics);
        }
    }
}


<|start_filename|>assorted/Phone_DevRig/foo.cs<|end_filename|>
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// Option: light framework (CF/Silverlight) enabled
    
// Generated from: foo.proto
namespace foo
{
  [global::ProtoBuf.ProtoContract(Name=@"Foo")]
  public partial class Foo : global::ProtoBuf.IExtensible
  {
    public Foo() {}
    

    private int _bar = default(int);
    [global::ProtoBuf.ProtoMember(1, IsRequired = false, Name=@"bar", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
    [global::System.ComponentModel.DefaultValue(default(int))]
    public int bar
    {
      get { return _bar; }
      set { _bar = value; }
    }
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
}


<|start_filename|>src/Examples/Issues/Issue222.cs<|end_filename|>
﻿using System;
using System.Globalization;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;

namespace Examples.Issues
{
    
    public class Issue222
    {
        [Fact]
        public void TestNonNullableDateTimeOffsetViaSurrogate()
        {
            var foo = new Foo {X = DateTimeOffset.Now};
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
            model.AutoCompile = false;
            
            var clone = (Foo)model.DeepClone(foo);
            Assert.Equal(foo.X, clone.X); //, "runtime");

            model.CompileInPlace();
            clone = (Foo)model.DeepClone(foo);
            Assert.Equal(foo.X, clone.X); //, "CompileInPlace");

            clone = (Foo)model.Compile().DeepClone(foo);
            Assert.Equal(foo.X, clone.X); //, "Compile");
        }
        [Fact]
        public void TestNullableDateTimeOffsetViaSurrogate()
        {
            var bar = new Bar { X = DateTimeOffset.Now };
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
            model.AutoCompile = false;

            var clone = (Bar)model.DeepClone(bar);
            Assert.Equal(bar.X, clone.X); //, "runtime");

            model.CompileInPlace();
            clone = (Bar)model.DeepClone(bar);
            Assert.Equal(bar.X, clone.X); //, "CompileInPlace");

            clone = (Bar)model.Compile().DeepClone(bar);
            Assert.Equal(bar.X, clone.X); //, "Compile");
        }
        [ProtoContract]
        public class Foo
        {
            [ProtoMember(1)]
            public DateTimeOffset X { get; set; }
        }
        [ProtoContract]
        public class Bar
        {
            [ProtoMember(1)]
            public DateTimeOffset? X { get; set; }
        }
        [ProtoContract]
        public class DateTimeOffsetSurrogate
        {
          public DateTimeOffsetSurrogate(DateTimeOffset dto)
          {
            Content = dto.ToString("o");
          }
          [ProtoMember(1)]
          public string Content { get; set; }

          public static explicit operator DateTimeOffsetSurrogate(DateTimeOffset dto)
          {
            return new DateTimeOffsetSurrogate(dto);
          }

          public static explicit operator DateTimeOffset(DateTimeOffsetSurrogate dtos)
          {
            return DateTimeOffset.Parse(dtos.Content, null, DateTimeStyles.RoundtripKind);
          }
        }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/FieldDecorator.cs<|end_filename|>
﻿using ProtoBuf.Internal;
using System;
using System.Diagnostics;
using System.Reflection;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class FieldDecorator : ProtoDecoratorBase
    {
        public override Type ExpectedType { get; }

        private readonly FieldInfo field;

        public override bool RequiresOldValue => true;
        public override bool ReturnsValue => false;
        public FieldDecorator(Type forType, FieldInfo field, IRuntimeProtoSerializerNode tail) : base(tail)
        {
            if (tail is null) ThrowHelper.ThrowArgumentNullException(nameof(tail));
            if (field is null) ThrowHelper.ThrowArgumentNullException(nameof(field));
            if (forType is null) ThrowHelper.ThrowArgumentNullException(nameof(forType));
            ExpectedType = forType;
            this.field = field;
        }

        public override void Write(ref ProtoWriter.State state, object value)
        {
            Debug.Assert(value is object);
            value = field.GetValue(value);
            if (value is object) Tail.Write(ref state, value);
        }

        public override object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is object);
            object newValue = Tail.Read(ref state, Tail.RequiresOldValue ? field.GetValue(value) : null);
            if (newValue is object) field.SetValue(value, newValue);
            return null;
        }

        protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            ctx.LoadAddress(valueFrom, ExpectedType);
            ctx.LoadValue(field);
            ctx.WriteNullCheckedTail(field.FieldType, Tail, null);
        }
        protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom);
            if (Tail.RequiresOldValue)
            {
                ctx.LoadAddress(loc, ExpectedType);
                ctx.LoadValue(field);
            }
            // value is either now on the stack or not needed
            ctx.ReadNullCheckedTail(field.FieldType, Tail, null);

            // the field could be a backing field that needs to be raised back to
            // the property if we're doing a full compile
            MemberInfo member = field;
            ctx.CheckAccessibility(ref member);
            bool writeValue = member is FieldInfo;

            if (writeValue)
            {
                if (Tail.ReturnsValue)
                {
                    var localType = PropertyDecorator.ChooseReadLocalType(field.FieldType, Tail.ExpectedType);
                    using Compiler.Local newVal = new Compiler.Local(ctx, localType);
                    ctx.StoreValue(newVal);
                    if (field.FieldType.IsValueType)
                    {
                        ctx.LoadAddress(loc, ExpectedType);
                        ctx.LoadValue(newVal);
                        ctx.StoreValue(field);
                    }
                    else
                    {
                        Compiler.CodeLabel allDone = ctx.DefineLabel();
                        ctx.LoadValue(newVal);
                        ctx.BranchIfFalse(allDone, true); // interpret null as "don't assign"

                        ctx.LoadAddress(loc, ExpectedType);
                        ctx.LoadValue(newVal);

                        // cast if needed (this is mostly for ReadMap/ReadRepeated)
                        if (!field.FieldType.IsValueType && !localType.IsValueType
                            && !field.FieldType.IsAssignableFrom(localType))
                        {
                            ctx.Cast(field.FieldType);
                        }

                        ctx.StoreValue(field);
                        ctx.MarkLabel(allDone);
                    }
                }
            }
            else
            {
                // can't use result
                if (Tail.ReturnsValue)
                {
                    ctx.DiscardValue();
                }
            }
        }
    }
}

<|start_filename|>src/Examples/Issues/Issue48/Issue202.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.IO;
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;

namespace Examples.Issues.Issue48
{
    
    public class Issue202
    {
        [Fact]
        public void TestListsAsFields()
        { 
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            ExecuteTest(model, "runtime");

            model.CompileInPlace();
            ExecuteTest(model, "CompileInPlace");

            ExecuteTest(model.Compile(), "Compile");
        }

#pragma warning disable IDE0060
        void ExecuteTest(TypeModel model, string test)
#pragma warning restore IDE0060
        {
            A a = new A { flags = new List<string> { "abc", "def" } }, c;
            Assert.Equal(2, a.flags.Count); //, test);
            Assert.Equal("abc", a.flags[0]); //, test);
            Assert.Equal("def", a.flags[1]); //, test);

            B b;
            using (var ms = new MemoryStream())
            {
                model.Serialize(ms, a);
                ms.Position = 0;
#pragma warning disable CS0618
                b = (B)model.Deserialize(ms, null, typeof(B));
#pragma warning restore CS0618
            }

            Assert.Equal(2, b.flags.Count); //, test);
            Assert.Equal("abc", b.flags[0]); //, test);
            Assert.Equal("def", b.flags[1]); //, test);

            using (var ms = new MemoryStream())
            {
                model.Serialize(ms, b);
                ms.Position = 0;
#pragma warning disable CS0618
                c = (A)model.Deserialize(ms, null, typeof(A));
#pragma warning restore CS0618
            }

            Assert.Equal(2, c.flags.Count); //, test);
            Assert.Equal("abc", c.flags[0]); //, test);
            Assert.Equal("def", c.flags[1]); //, test);
        }
#pragma warning disable IDE1006 // naming
        [ProtoContract]
        public class A //property version
        {
            [ProtoMember(3)]
            public List<string> flags { get; set; }
        }
        [ProtoContract]
        public class B //field version
        {
            [ProtoMember(3)]
            public List<string> flags;
        }
#pragma warning restore IDE1006

    }
}


<|start_filename|>src/Examples/ProtoGen/searchRequest.cs<|end_filename|>

// Option: data-contract serialization ([DataContract]/[DataMember]) enabled
    
//------------------------------------------------------------------------------
// 
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

// Generated from: searchRequest.proto
// Note: requires additional types generated from: protobuf-net.proto
namespace SearchRequest
{
    [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"searchRequest")]
    [global::System.Runtime.Serialization.DataContract(Name=@"searchRequest")]
    
    public partial class SearchRequest : global::ProtoBuf.IExtensible
    {
      public SearchRequest() {}
      
    private string _query;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"query", DataFormat = global::ProtoBuf.DataFormat.Default)]
    [global::System.Runtime.Serialization.DataMember(Name=@"query", Order = 1, IsRequired = true)]
    
    public string Query
    {
      get { return _query; }
      set { _query = value; }
    }

    private int _pageNumber = default(int);
    [global::ProtoBuf.ProtoMember(2, IsRequired = false, Name=@"page_number", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)][global::System.ComponentModel.DefaultValue(default(int))]
    [global::System.Runtime.Serialization.DataMember(Name=@"page_number", Order = 2, IsRequired = false)]
    
    public int PageNumber
    {
      get { return _pageNumber; }
      set { _pageNumber = value; }
    }

    private int _resultPerPage = (int)10;
    [global::ProtoBuf.ProtoMember(3, IsRequired = false, Name=@"result_per_page", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)][global::System.ComponentModel.DefaultValue((int)10)]
    [global::System.Runtime.Serialization.DataMember(Name=@"result_per_page", Order = 3, IsRequired = false)]
    
    public int ResultPerPage
    {
      get { return _resultPerPage; }
      set { _resultPerPage = value; }
    }

    private SearchRequest.Corpus _corpus1 = SearchRequest.Corpus.Universal;
    [global::ProtoBuf.ProtoMember(4, IsRequired = false, Name=@"corpus1", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)][global::System.ComponentModel.DefaultValue(SearchRequest.Corpus.Universal)]
    [global::System.Runtime.Serialization.DataMember(Name=@"corpus1", Order = 4, IsRequired = false)]
    
    public SearchRequest.Corpus Corpus1
    {
      get { return _corpus1; }
      set { _corpus1 = value; }
    }
    public enum Corpus
    {
      Universal = 0,
    Web = 1,
    Images = 2,
    Local = 3,
    News = 4,
    Products = 5,
    Video = 6
    }
  
      private global::ProtoBuf.IExtension extensionObject;
      global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
        { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
    }
  
}


<|start_filename|>src/protogen/GrpcTools.cs<|end_filename|>
﻿#if GRPC_TOOLS
using Google.Protobuf.Reflection;
using grpc.reflection.v1alpha;
using Grpc.Core;
using Grpc.Net.Client;
using ProtoBuf;
using ProtoBuf.Grpc.Client;
using ProtoBuf.Reflection;
using protogen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace ProtoBuf
{
    internal static class GrpcTools
    {
        enum GrpcMode
        {
            List,
            Get,
        }

        internal static async Task<int> ExecuteAsync(string modeString, string uri, string serviceName,
            CodeGenerator codegen, string outPath, Dictionary<string,string> options)
        {
            
            if (!Enum.TryParse<GrpcMode>(modeString, true, out var mode))
            {
                Console.Error.WriteLine($"Unknown gRPC mode: '{modeString}'");
                return 1;
            }
            if (string.IsNullOrWhiteSpace(outPath) &&
                mode == GrpcMode.Get)
            {
                Console.Error.WriteLine($"Missing output directive; please specify --csharp_out etc");
                return 1;
            }

            switch (mode)
            {
                case GrpcMode.List:
                    Console.WriteLine($"Requesting gRPC service directory from '{uri}'...");
                    break;
                case GrpcMode.Get:
                    Console.WriteLine($"Requesting gRPC '{serviceName}' service from '{uri}'...");
                    break;
                default:
                    Console.Error.WriteLine($"Unexpected mode: {mode}");
                    return 1;
            }
            int errorCount = 0;
            GrpcClientFactory.AllowUnencryptedHttp2 = true;
            using var channel = GrpcChannel.ForAddress(uri);
            var service = channel.CreateGrpcService<IServerReflection>();

            FileDescriptorSet set = null;
            int services = 0;
            try
            {
                await foreach (var reply in service.ServerReflectionInfoAsync(GetRequest()))
                {
                    switch (reply.MessageResponseCase)
                    {
                        case ServerReflectionResponse.MessageResponseOneofCase.ListServicesResponse:
                            foreach (var availableService in reply.ListServicesResponse.Services)
                            {
                                services++;
                                Console.WriteLine($"- {availableService.Name}");
                            }
                            break;
                        case ServerReflectionResponse.MessageResponseOneofCase.FileDescriptorResponse:
                            {
                                var file = reply.FileDescriptorResponse;
                                if (file is null) continue;
                                foreach (byte[] payload in file.FileDescriptorProtoes)
                                {
                                    var proto = Serializer.Deserialize<FileDescriptorProto>(new Span<byte>(payload));
                                    proto.IncludeInOutput = true; // have to assume all

                                    foreach (var dependency in proto.Dependencies)
                                    {
                                        proto.AddImport(dependency, true, default);
                                    }

                                    (set ??= new FileDescriptorSet()).Files.Add(proto);
                                }
                            }
                            break;
                        case ServerReflectionResponse.MessageResponseOneofCase.ErrorResponse:
                            errorCount++;
                            var code = (StatusCode)reply.ErrorResponse.ErrorCode;
                            Console.Error.WriteLine($"{code}: {reply.ErrorResponse.ErrorMessage}");
                            break;
                    }
                }

                switch (mode)
                {
                    case GrpcMode.List:
                        Console.WriteLine($"gRPC services discovered: {services}");
                        break;
                    case GrpcMode.Get:
                        Console.WriteLine($"gRPC descriptors fetched: {set?.Files?.Count ?? 0}");
                        if (set is object)
                        {
                            set.Process();
                            foreach (var error in set.GetErrors())
                            {
                                errorCount++;
                                Console.WriteLine($"{(error.IsError ? "error" : "warning")} {error.ErrorNumber}: {error.Message}");
                            }
                            Program.WriteFiles(codegen.Generate(set, options: options), outPath);
                        }
                        break;
                }
            }
            catch (RpcException fault)
            {
                errorCount++;
                Console.Error.WriteLine($"{fault.StatusCode}: {fault.Status.Detail}");
            }
            return errorCount;

            IAsyncEnumerable<ServerReflectionRequest> GetRequest() => mode switch {
                GrpcMode.List => ListServices(),
                GrpcMode.Get => GetFileContainingSymbol(serviceName),
                _ => Nothing(),
            };
            static async IAsyncEnumerable<ServerReflectionRequest> ListServices()
            {
                if (Never()) await Task.Yield();
                yield return new ServerReflectionRequest { ListServices = "*" };
            }
            static async IAsyncEnumerable<ServerReflectionRequest> GetFileContainingSymbol(string symbol)
            {
                if (Never()) await Task.Yield();
                yield return new ServerReflectionRequest { FileContainingSymbol = symbol };
            }
            static async IAsyncEnumerable<ServerReflectionRequest> Nothing()
            {
                if (Never()) await Task.Yield();
                yield break;
            }
            static bool Never() => false;
        }

    }
}
#endif

<|start_filename|>src/Examples/SimpleStream/NullTypes.cs<|end_filename|>
﻿using ProtoBuf;
using ProtoBuf.Meta;
using System.Runtime.Serialization;
using Xunit;

namespace Examples.SimpleStream
{

    public class NullTypes
    {
        [DataContract]
        public class TypeWithNulls
        {
            [DataMember(Order = 1)]
            public int? Foo { get; set; }
        }
        [Fact]
        public void TestNull()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;

            TypeWithNulls twn = new TypeWithNulls { Foo = null },
                clone = model.DeepClone(twn);
            Assert.Null(twn.Foo);
            Assert.True(Program.CheckBytes(twn, model, new byte[0]));
            Assert.Null(clone.Foo);
            Assert.True(Program.CheckBytes(clone, model, new byte[0]));

            var compiled = model.Compile("TestNull", "TestNull.dll");
            PEVerify.AssertValid("TestNull.dll");
            clone = compiled.DeepClone(twn);
            Assert.True(Program.CheckBytes(twn, compiled, new byte[0]));
            Assert.True(Program.CheckBytes(clone, compiled, new byte[0]));

            model.CompileInPlace();
            clone = model.DeepClone(twn);
            Assert.True(Program.CheckBytes(twn, model, new byte[0]));
            Assert.True(Program.CheckBytes(clone, model, new byte[0]));

            compiled = model.Compile();
            clone = compiled.DeepClone(twn);
            Assert.True(Program.CheckBytes(twn, compiled, new byte[0]));
            Assert.True(Program.CheckBytes(clone, compiled, new byte[0]));
        }
        [Fact]
        public void TestNotNull()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;

            TypeWithNulls twn = new TypeWithNulls { Foo = 150 },
                clone = model.DeepClone(twn);
            Assert.NotNull(twn.Foo);
            Program.CheckBytes(twn, model, "08-96-01");
            Assert.NotNull(clone.Foo);
            Program.CheckBytes(clone, model, "08-96-01");

            var compiled = model.Compile("TestNotNull", "TestNotNull.dll");
            PEVerify.AssertValid("TestNotNull.dll");
            clone = compiled.DeepClone(twn);
            Program.CheckBytes(twn, compiled, "08-96-01");
            Program.CheckBytes(clone, compiled, "08-96-01");

            model.CompileInPlace();
            clone = model.DeepClone(twn);
            Program.CheckBytes(twn, model, "08-96-01");
            Program.CheckBytes(clone, model, "08-96-01");

            compiled = model.Compile();
            clone = compiled.DeepClone(twn);
            Program.CheckBytes(twn, compiled, "08-96-01");
            Program.CheckBytes(clone, compiled, "08-96-01");

        }
    }
}


<|start_filename|>assorted/SampleDto/Order.cs<|end_filename|>
﻿#if !FX11
namespace NETCFClient
{
    public partial class Order
    {
        private int _OrderID;

        private string _CustomerID;

        private System.Nullable<int> _EmployeeID;

        private System.Nullable<System.DateTime> _OrderDate;

        private System.Nullable<System.DateTime> _RequiredDate;

        private System.Nullable<System.DateTime> _ShippedDate;

        private System.Nullable<int> _ShipVia;

        private System.Nullable<decimal> _Freight;

        private string _ShipName;

        private string _ShipAddress;

        private string _ShipCity;

        private string _ShipRegion;

        private string _ShipPostalCode;

        private string _ShipCountry;

        
        public int OrderID
        {
            get
            {
                return this._OrderID;
            }
            set
            {
                if ((this._OrderID != value))
                {
                    this._OrderID = value;
                }
            }
        }

        public string CustomerID
        {
            get
            {
                return this._CustomerID;
            }
            set
            {
                if ((this._CustomerID != value))
                {
                    this._CustomerID = value;
                }
            }
        }

        public System.Nullable<int> EmployeeID
        {
            get
            {
                return this._EmployeeID;
            }
            set
            {
                if ((this._EmployeeID != value))
                {
                    this._EmployeeID = value;
                }
            }
        }

        public System.Nullable<System.DateTime> OrderDate
        {
            get
            {
                return this._OrderDate;
            }
            set
            {
                if ((this._OrderDate != value))
                {
                    this._OrderDate = value;
                }
            }
        }

        public System.Nullable<System.DateTime> RequiredDate
        {
            get
            {
                return this._RequiredDate;
            }
            set
            {
                if ((this._RequiredDate != value))
                {
                    this._RequiredDate = value;
                }
            }
        }

        public System.Nullable<System.DateTime> ShippedDate
        {
            get
            {
                return this._ShippedDate;
            }
            set
            {
                if ((this._ShippedDate != value))
                {
                    this._ShippedDate = value;
                }
            }
        }

        public System.Nullable<int> ShipVia
        {
            get
            {
                return this._ShipVia;
            }
            set
            {
                if ((this._ShipVia != value))
                {
                    this._ShipVia = value;
                }
            }
        }

        public System.Nullable<decimal> Freight
        {
            get
            {
                return this._Freight;
            }
            set
            {
                if ((this._Freight != value))
                {
                    this._Freight = value;
                }
            }
        }

        public string ShipName
        {
            get
            {
                return this._ShipName;
            }
            set
            {
                if ((this._ShipName != value))
                {
                    this._ShipName = value;
                }
            }
        }

        public string ShipAddress
        {
            get
            {
                return this._ShipAddress;
            }
            set
            {
                if ((this._ShipAddress != value))
                {
                    this._ShipAddress = value;
                }
            }
        }

        public string ShipCity
        {
            get
            {
                return this._ShipCity;
            }
            set
            {
                if ((this._ShipCity != value))
                {
                    this._ShipCity = value;
                }
            }
        }

        public string ShipRegion
        {
            get
            {
                return this._ShipRegion;
            }
            set
            {
                if ((this._ShipRegion != value))
                {
                    this._ShipRegion = value;
                }
            }
        }

        public string ShipPostalCode
        {
            get
            {
                return this._ShipPostalCode;
            }
            set
            {
                if ((this._ShipPostalCode != value))
                {
                    this._ShipPostalCode = value;
                }
            }
        }

        public string ShipCountry
        {
            get
            {
                return this._ShipCountry;
            }
            set
            {
                if ((this._ShipCountry != value))
                {
                    this._ShipCountry = value;
                }
            }
        }
    }
}
#endif

<|start_filename|>src/Benchmark/SerializeBenchmarks_NewApi.cs<|end_filename|>
﻿#if NEW_API
using BenchmarkDotNet.Attributes;
using Pipelines.Sockets.Unofficial.Buffers;
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Buffers;
using System.IO;

namespace Benchmark
{
    partial class SerializeBenchmarks
    {
        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void BufferWriter_CIP() => WriteBufferWriter(_cip);

        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void BufferWriter_C() => WriteBufferWriter(_c);

        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void BufferWriter_Auto() => WriteBufferWriter(_auto);

        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void FakeBufferWriter_CIP() => WriteFakeBufferWriter(_cip);

        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void FakeBufferWriter_C() => WriteFakeBufferWriter(_c);

        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void FakeBufferWriter_Auto() => WriteFakeBufferWriter(_auto);

        private void WriteBufferWriter(TypeModel model)
        {
            using var buffer = BufferWriter<byte>.Create(64 * 1024);
            for (int i = 0; i < OperationsPerInvoke; i++)
            {
                var state = ProtoWriter.State.Create(buffer, model);
                try
                {
                    state.SerializeRoot(_database);
                    state.Close();
                }
                finally
                {
                    state.Dispose();
                }
                AssertLength(buffer.Length);
                buffer.Flush().Dispose();
            }
        }

        private void WriteFakeBufferWriter(TypeModel model)
        {
            using var buffer = new FakeBufferWriter();
            for (int i = 0; i < OperationsPerInvoke; i++)
            {
                var state = ProtoWriter.State.Create(buffer, model);
                try
                {
                    state.SerializeRoot(_database);
                    state.Close();
                }
                finally
                {
                    state.Dispose();
                }
                AssertLength(buffer.Reset());
            }
        }

        [Benchmark(OperationsPerInvoke = OperationsPerInvoke)]
        public void MemoryStream_Auto() => MemoryStream_ViaState(_auto);

        private void MemoryStream_ViaState(TypeModel model)
        {
            using var buffer = new MemoryStream();
            for (int i = 0; i < OperationsPerInvoke; i++)
            {
                var state = ProtoWriter.State.Create(buffer, model);
                try
                {
                    state.SerializeRoot(_database);
                    state.Close();
                }
                finally
                {
                    state.Dispose();
                }
                AssertLength(buffer.Length);
                buffer.Position = 0;
                buffer.SetLength(0);
            }
        }

        private sealed class FakeBufferWriter : IBufferWriter<byte>, IDisposable
        {
            public long Length { get; private set; }
            public long Reset()
            {
                var len = Length;
                Length = 0;
                return len;
            }
            private byte[] _arr;

            public FakeBufferWriter(int initialSize = 1024)
                => Resize(initialSize);

            public void Advance(int count) => Length += count;

            public Memory<byte> GetMemory(int sizeHint = 0)
            {
                if (_arr.Length < sizeHint) Resize(sizeHint);
                return _arr;
            }

            public Span<byte> GetSpan(int sizeHint = 0)
            {
                if (_arr.Length < sizeHint) Resize(sizeHint);
                return _arr;
            }

            private void Resize(int sizeHint)
            {
                var arr = _arr;
                _arr = null;
                if (arr != null) ArrayPool<byte>.Shared.Return(arr);

                if (sizeHint > 0)
                    _arr = ArrayPool<byte>.Shared.Rent(sizeHint);
            }

            public void Dispose() => Resize(0);
        }
    }
}

#endif

<|start_filename|>src/Examples/ServiceModel/WcfTest.cs<|end_filename|>
﻿#if NET_3_0
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.ServiceModel;
using Xunit;
using ProtoBuf.ServiceModel;

namespace Examples.ServiceModel
{
    // in case of errors, see: http://msdn.microsoft.com/en-us/library/ms733768.aspx
    // for example: netsh http add urlacl url=http://+:84/MyService user=mydomain\myuser
    [DataContract]
    public class MyData
    {
        public MyData() { SubData = new List<MySubData>(); }
        [DataMember(Order = 1)]
        public List<MySubData> SubData { get; private set; }
    }
    [DataContract]
    public class MySubData
    {
        [DataMember(Order = 1)]
        public string Name { get; set; }
        [DataMember(Order = 2)]
        public int Number { get; set; }
    }

    [ServiceContract]
    interface IMyService
    {
        [OperationContract, ProtoBehavior]
        MyData UsingProtoItem(MyData data);

        [OperationContract]
        MyData RegularWcfItem(MyData data);

        [OperationContract, ProtoBehavior]
        MyData[] UsingProtoList(List<MyData> data);

        [OperationContract]
        MyData[] RegularWcfList(List<MyData> data);

        [OperationContract, ProtoBehavior]
        int ComplexMethod(List<MyData> a, MyData b, MyData c, List<MyData> d);

        [OperationContract]
        bool Ping();

        [OperationContract]
        string SimpleTypesRegular(int value);
        [OperationContract, ProtoBehavior]
        string SimpleTypesProto(int value);
    }
    class MyService : IMyService
    {
        public MyData RegularWcfItem(MyData data) { return data; }
        public MyData UsingProtoItem(MyData data) { return data; }
        public MyData[] RegularWcfList(List<MyData> data) { return data == null ? null : data.ToArray(); }
        public MyData[] UsingProtoList(List<MyData> data) { return data == null ? null : data.ToArray(); }

        public bool Ping() { return true; }

        public string SimpleTypesRegular(int value)
        {
            return value.ToString();
        }
        public string SimpleTypesProto(int value)
        {
            return value.ToString();
        }

        public int ComplexMethod(List<MyData> a, MyData b, MyData c, List<MyData> d)
        {
            int count = 0;
            if (a != null) count += a.Count;
            if (b != null) count++;
            if (c != null) count++;
            if (d != null) count += d.Count;
            return count;
        }
    }


    
    public class WcfTest
    {
        ServiceHost host;
        [TestFixtureSetUp]
        public void StartServer()
        {
            try
            {
                StopServer();
                host = new ServiceHost(typeof(MyService),
                    new Uri("http://localhost:84/MyService"));
                host.Open();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.GetType().FullName);
                Console.WriteLine("You may need to execute (as admin):");
                Console.WriteLine(@"netsh http add urlacl url=http://+:84/MyService/ user=""NT AUTHORITY\Authenticated Users""");
                Console.WriteLine(ex.Message);
                throw;
            }
        }

        [TestFixtureTearDown]
        public void StopServer()
        {
            if (host != null)
            {
                host.Close();
                host = null;
            }
        }

        static WcfProxy<IMyService> GetProxy()
        {
            return new WcfProxy<IMyService>();
        }
        [Fact]
        public void Ping()
        {
            using (var proxy = GetProxy())
            {
                Assert.True(proxy.Service.Ping());
            }
        }

        [Fact]
        public void RoundTripTrivial()
        {
            using(var proxy = GetProxy())
            {
                var data = proxy.Service.UsingProtoItem(new MyData {});
                Assert.NotNull(data);
            }
        }
        [Fact]
        public void SimpleTypesRegular()
        {
            using (var proxy = GetProxy())
            {
                Assert.Equal("27", proxy.Service.SimpleTypesRegular(27));
            }
        }

        [Fact]
        public void SimpleTypesProto()
        {
            using (var proxy = GetProxy())
            {
                Assert.Equal("27", proxy.Service.SimpleTypesProto(27));
            }
        }

        [Fact]
        public void WcfRegularNullToNull()
        {
            using (var proxy = GetProxy())
            {
                Assert.Null(proxy.Service.RegularWcfItem(null));
            }
        }

        [Fact]
        public void WcfProtoNullToNull()
        {
            using (var proxy = GetProxy())
            {
                Assert.Null(proxy.Service.UsingProtoItem(null));
            }
        }

        static List<MyData> GetShortList()
        {
            List<MyData> list = new List<MyData>();
            for (int j = 0; j < 5; j++)
            {
                MyData data = new MyData();
                for (int i = 0; i < 50; i++)
                {
                    data.SubData.Add(new MySubData { Number = i, Name = "item " + i.ToString() });
                }
                list.Add(data);
            }
            return list;
        }
        static void CheckListResult(MyData[] arr)
        {
            Assert.NotNull(arr, "Null");
            Assert.Equal(5, arr.Length, "Length");
            for (int j = 0; j < arr.Length; j++)
            {
                MyData item = arr[j];
                Assert.NotNull(item, "Null: " + j.ToString());
                Assert.NotNull(item.SubData, "SubData Null: " + j.ToString());
                Assert.Equal(50, item.SubData.Count, "SubData Count: " + j.ToString());
                for (int i = 0; i < item.SubData.Count; i++)
                {
                    var subItem = item.SubData[i];
                    Assert.NotNull(subItem, i.ToString());
                    Assert.Equal(i, subItem.Number, "Number: " + i.ToString());
                    Assert.Equal("item " + i.ToString(), subItem.Name, "Name: " + i.ToString());
                }
            }
        }
        [Fact]
        public void RegularWcfList()
        {
            using (var proxy = GetProxy())
            {
                MyData[] arr = proxy.Service.RegularWcfList(GetShortList());
                CheckListResult(arr);
            }
        }
        [Fact]
        public void ProtoList()
        {
            using (var proxy = GetProxy())
            {
                MyData[] arr = proxy.Service.UsingProtoList(GetShortList());
                CheckListResult(arr);
            }
        }

        [Fact]
        public void ProtoListEmpty()
        {
            using (var proxy = GetProxy())
            {
                var emptyList = new List<MyData>();
                MyData[] arr = proxy.Service.UsingProtoList(emptyList);
                Assert.NotNull(arr);
                Assert.Equal(0, arr.Length);
            }
        }

        [Fact]
        public void ProtoItemEmpty()
        {
            using (var proxy = GetProxy())
            {
                var emptyItem = new MyData();
                MyData result = proxy.Service.UsingProtoItem(emptyItem);
                Assert.NotNull(result);
                Assert.Equal(0, result.SubData.Count);
            }
        }

        [Fact]
        public void RunWcfTest()
        {
            // generate some data:
            MyData data = new MyData();
            for (int i = 0; i < 5000; i++)
            {
                data.SubData.Add(new MySubData { Number = i, Name = "item " + i.ToString() });
            }

            using (var proxy = GetProxy())
            {
                // for JIT etc
                proxy.Service.RegularWcfItem(data);
                proxy.Service.UsingProtoItem(data);

                Stopwatch watchProto = Stopwatch.StartNew();
                MyData dataProto = proxy.Service.UsingProtoItem(data);
                watchProto.Stop();
                Console.WriteLine("WCF: Proto took: {0}", watchProto.ElapsedMilliseconds);

                Stopwatch watchRegular = Stopwatch.StartNew();
                MyData dataRegular = proxy.Service.RegularWcfItem(data);
                watchRegular.Stop();
                Console.WriteLine("WCF: Regular took: {0}", watchRegular.ElapsedMilliseconds);

                Assert.Equal(data.SubData.Count, dataProto.SubData.Count, "Proto count");
                Assert.Equal(data.SubData.Count, dataRegular.SubData.Count, "Regular count");
                for (int i = 0; i < data.SubData.Count; i++)
                {
                    Assert.Equal(data.SubData[i].Name, dataProto.SubData[i].Name, "Proto name");
                    Assert.Equal(data.SubData[i].Number, dataProto.SubData[i].Number, "Proto number");
                    Assert.Equal(data.SubData[i].Name, dataRegular.SubData[i].Name, "Regular name");
                    Assert.Equal(data.SubData[i].Number, dataRegular.SubData[i].Number, "Regular number");
                }
                Console.WriteLine(string.Format("Validated: {0}", data.SubData.Count));

                Assert.True(watchProto.ElapsedMilliseconds < watchRegular.ElapsedMilliseconds); //, "Proto should be quicker");
            }
        }

        [Fact]
        public void TestComplexPermutations()
        {
            MyData trivial = new MyData(), nonTrivial = new MyData { SubData = { new MySubData { Number = 12345 } } };
            List<MyData> empty = new List<MyData>(0);
            List<MyData> fourItems = new List<MyData> {trivial, nonTrivial, trivial, nonTrivial};
 
            using (var proxy = GetProxy())
            {
                int i = 0;
                try
                {
                    Assert.Equal(0, proxy.Service.ComplexMethod(null, null, null, null));
                    i++;
                    Assert.Equal(10, proxy.Service.ComplexMethod(fourItems, nonTrivial, nonTrivial, fourItems));
                    i++;
                    Assert.Equal(2, proxy.Service.ComplexMethod(null, trivial, nonTrivial, null));
                    i++;
                    Assert.Equal(1, proxy.Service.ComplexMethod(null, trivial, null, empty));
                    i++;
                    Assert.Equal(5, proxy.Service.ComplexMethod(fourItems, trivial, null, empty));
                    i++;
                    Assert.Equal(9, proxy.Service.ComplexMethod(fourItems, trivial, null, fourItems));
                    i++;
                    Assert.Equal(8, proxy.Service.ComplexMethod(fourItems, null, null, fourItems));
                } catch
                {
                    Debug.WriteLine(i);
                    throw;
                }
            }
        }

    }


    public sealed class WcfProxy<T> : ClientBase<T>, IDisposable
    where T : class
    {
        public T Service { get { return base.Channel; } }
        public void Dispose()
        {
            try
            {
                switch (State)
                {
                    case CommunicationState.Closed:
                        break; // nothing to do
                    case CommunicationState.Faulted:
                        Abort();
                        break;
                    case CommunicationState.Opened:
                        Close();
                        break;
                }
            }
            catch { } // best efforts...
        }
    }
}
#endif

<|start_filename|>src/protobuf-net/Internal/Serializers/ISerializerProxy.cs<|end_filename|>
﻿namespace ProtoBuf.Internal.Serializers
{
    interface ISerializerProxy
    {
        IRuntimeProtoSerializerNode Serializer { get; }
    }
}

<|start_filename|>src/protobuf-net/Internal/Serializers/IRuntimeProtoSerializerNode.cs<|end_filename|>
﻿using System;

namespace ProtoBuf.Internal.Serializers
{
    internal interface IRuntimeProtoSerializerNode
    {
        /// <summary>
        /// The type that this serializer is intended to work for.
        /// </summary>
        Type ExpectedType { get; }

        /// <summary>
        /// Perform the steps necessary to serialize this data.
        /// </summary>
        /// <param name="value">The value to be serialized.</param>
        /// <param name="state">Writer state</param>
        void Write(ref ProtoWriter.State state, object value);

        /// <summary>
        /// Perform the steps necessary to deserialize this data.
        /// </summary>
        /// <param name="value">The current value, if appropriate.</param>
        /// <param name="state">Reader state</param>
        /// <returns>The updated / replacement value.</returns>
        object Read(ref ProtoReader.State state, object value);

        /// <summary>
        /// Indicates whether a Read operation <em>replaces</em> the existing value, or
        /// <em>extends</em> the value. If false, the "value" parameter to Read is
        /// discarded, and should be passed in as null.
        /// </summary>
        bool RequiresOldValue { get; }
        /// <summary>
        /// Not all Read operations return a value (although most do); if false no
        /// value should be expected.
        /// </summary>
        bool ReturnsValue { get; }

        /// <summary>Emit the IL necessary to perform the given actions
        /// to serialize this data.
        /// </summary>
        /// <param name="ctx">Details and utilities for the method being generated.</param>
        /// <param name="valueFrom">The source of the data to work against;
        /// If the value is only needed once, then LoadValue is sufficient. If
        /// the value is needed multiple times, then note that a "null"
        /// means "the top of the stack", in which case you should create your
        /// own copy - GetLocalWithValue.</param>
        void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom);

        /// <summary>
        /// Emit the IL necessary to perform the given actions to deserialize this data.
        /// </summary>
        /// <param name="ctx">Details and utilities for the method being generated.</param>
        /// <param name="entity">For nested values, the instance holding the values; note
        /// that this is not always provided - a null means not supplied. Since this is always
        /// a variable or argument, it is not necessary to consume this value.</param>
        void EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity);
    }
}

<|start_filename|>src/Examples/Issues/Issue509.cs<|end_filename|>
﻿using ProtoBuf.Meta;
using System.IO;
using Xunit;

namespace ProtoBuf.Issues
{
    public class Issue509
    {

        public class Item
        {
            public int Value { get; set; }
            public Item Child1 { get; set; }
            public Item Child2 { get; set; }
        }

        [ProtoContract]
        public class ItemSurrogate
        {
            [ProtoMember(1)]
            public int Value { get; set; }

            [ProtoMember(2)]
            public Item Child1 { get; set; }

            [ProtoMember(3)]
            public Item Child2 { get; set; }

            public static implicit operator Item(ItemSurrogate s)
            {
                return s == null ? null : new Item { Value = s.Value, Child1 = s.Child1, Child2 = s.Child2 };
            }

            public static implicit operator ItemSurrogate(Item i)
            {
                return i == null ? null : new ItemSurrogate { Value = i.Value,  Child1 = i.Child1, Child2 = i.Child2 };
            }
        }


#if FEAT_DYNAMIC_REF
        [Fact]
        public void TestUncompiled() => Test(false);

        [Fact]
        public void TestCompiled() => Test(true);

        private void Test(bool compile)
        { 
            var model = RuntimeTypeModel.Create();
            var item = model.Add(typeof(Item), false);
            item.SetSurrogate(typeof(ItemSurrogate));
            item.AsReferenceDefault = true;
            var typeModel = compile ? model.Compile() : model;

            var item1 = new Item { Value = 1 };
            var item2 = new Item { Value = 2, Child1 = item1, Child2 = item1 };

            MemoryStream ms = new MemoryStream();
            typeModel.Serialize(ms, item2);
            ms.Seek(0, SeekOrigin.Begin);
#pragma warning disable CS0618
            var newItem2 = (Item) typeModel.Deserialize(ms, null, typeof(Item));
#pragma warning restore CS0618
            Assert.Equal(item2.Value, newItem2.Value);
            Assert.Equal(item1.Value, newItem2.Child1.Value);
            Assert.Same(newItem2.Child1, newItem2.Child2);
        }
#endif
    }
}


<|start_filename|>src/protobuf-net.BuildTools/Internal/DataContractContext.cs<|end_filename|>
﻿#nullable enable
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using ProtoBuf.BuildTools.Analyzers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;

namespace ProtoBuf.BuildTools.Internal
{
    internal sealed class DataContractContext
    {
        // Trim handles the UL and LU compound suffixes. We can't trim D or F suffixes on hex literals.
        private static readonly char[] _trimmableNumericSuffixes = new[] { 'L', 'U', 'M', 'l', 'u', 'm', };
        private static readonly char[] _floatNumericSuffixes = new[] { 'D', 'F', 'd', 'f' };
        private static readonly HashSet<string> _nullCharLiterals = new(
            new char[] { '\0', '\u0000', '\x0', '\x00', '\x000', '\x0000' }.Select(ch => $"'{ch}'"));

        private List<Ignore>? _ignores;
        private List<Member>? _members;
        private List<Reservation>? _reservations;
        private List<Include>? _includes;
        private DataContractContextFlags _flags;

        internal void AddReserved(ISymbol blame, AttributeData attrib)
        {
            Reservation reservation;
            if (attrib.TryGetInt32ByName(nameof(ProtoReservedAttribute.From), out var from) && attrib.TryGetInt32ByName(nameof(ProtoReservedAttribute.To), out var to))
            {
                reservation = new Reservation(attrib.GetLocation(blame), from, to);
            }
            else if (attrib.TryGetInt32ByName("field", out from))
            {
                reservation = new Reservation(attrib.GetLocation(blame), from, from);
            }
            else if (attrib.TryGetStringByName("field", out string name))
            {
                reservation = new Reservation(attrib.GetLocation(blame), name);
            }
            else
            {
                return;
            }
            (_reservations ??= new List<Reservation>()).Add(reservation);
        }

        static bool AssertLegalFieldNumber(ref SyntaxNodeAnalysisContext context, int fieldNumber, Location? blame)
        {
            var severity = fieldNumber switch
            {
                < 1 or > 536870911 => DiagnosticSeverity.Error, // legal range
                >= 19000 and <= 19999 => DiagnosticSeverity.Warning, // reserved range; it'll work, but is a bad idea
                _ => DiagnosticSeverity.Hidden,
            };
            if (severity != DiagnosticSeverity.Hidden)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                    descriptor: DataContractAnalyzer.InvalidFieldNumber,
                    location: Utils.PickLocation(ref context, blame),
                    effectiveSeverity: severity,
                    messageArgs: new object[] { fieldNumber },
                    additionalLocations: null,
                    properties: null
                ));
                return false;
            }
            return true;
        }

        internal void ReportProblems(SyntaxNodeAnalysisContext context, ITypeSymbol type)
        {
            HashSet<int>? uniqueFieldNumbers = null;
            HashSet<string>? uniqueFieldNames = null;
            HashSet<string>? coveredMemberNames = null;

            void AssertAvailableNumber(int fieldNumber, Location? blame)
            {
                uniqueFieldNumbers ??= new HashSet<int>();
                if (!uniqueFieldNumbers.Add(fieldNumber))
                {
                    context.ReportDiagnostic(Diagnostic.Create(
                        descriptor: DataContractAnalyzer.DuplicateFieldNumber,
                        location: Utils.PickLocation(ref context, blame),
                        messageArgs: new object[] { fieldNumber },
                        additionalLocations: null,
                        properties: null
                    ));
                }
                if (OverlapsReservation(fieldNumber, out var reservation))
                {
                    context.ReportDiagnostic(Diagnostic.Create(
                        descriptor: DataContractAnalyzer.ReservedFieldNumber,
                        location: Utils.PickLocation(ref context, blame),
                        messageArgs: new object[] { reservation },
                        additionalLocations: null,
                        properties: null
                    ));
                }
            }

            void AssertAvailableName(string name, Location? blame)
            {
                uniqueFieldNames ??= new HashSet<string>();
                if (!uniqueFieldNames.Add(name))
                {
                    context.ReportDiagnostic(Diagnostic.Create(
                        descriptor: DataContractAnalyzer.DuplicateFieldName,
                        location: Utils.PickLocation(ref context, blame),
                        messageArgs: new object[] { name },
                        additionalLocations: null,
                        properties: null
                    ));
                }
                if (OverlapsReservation(name, out var reservation))
                {
                    context.ReportDiagnostic(Diagnostic.Create(
                        descriptor: DataContractAnalyzer.ReservedFieldName,
                        location: Utils.PickLocation(ref context, blame),
                        messageArgs: new object[] { name },
                        additionalLocations: null,
                        properties: null
                    ));
                }
            }

            if (!(_members is not null || _includes is not null || _reservations is not null || _ignores is not null)) return;

            if (!HasFlag(DataContractContextFlags.IsProtoContract))
            {
                context.ReportDiagnostic(Diagnostic.Create(
                    descriptor: DataContractAnalyzer.ShouldBeProtoContract,
                    location: _members.FirstBlame() ?? _includes.FirstBlame()
                        ?? _reservations.FirstBlame() ?? _ignores.FirstBlame()
                        ?? Utils.PickLocation(ref context, type),
                    messageArgs: null,
                    additionalLocations: null,
                    properties: null
                ));;
            }

            if (_reservations is not null)
            {
                int current = 0;
                foreach (var reservation in _reservations)
                {
                    if (reservation.Name is null)
                    {
                        AssertLegalFieldNumber(ref context, reservation.From, reservation.Blame);
                        if (reservation.From != reservation.To)
                            AssertLegalFieldNumber(ref context, reservation.To, reservation.Blame);
                    }

                    for (int i = 0; i < current; i++)
                    {
                        if (reservation.Overlaps(_reservations[i]))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(
                                descriptor: DataContractAnalyzer.DuplicateReservation,
                                location: Utils.PickLocation(ref context, reservation.Blame),
                                messageArgs: new object[] { reservation, _reservations[i] },
                                additionalLocations: null,
                                properties: null
                            ));
                            break;
                        }
                    }
                    current++;
                }
            }

            if (_includes is not null)
            {
                int current = 0;
                foreach (var include in _includes)
                {
                    if (AssertLegalFieldNumber(ref context, include.FieldNumber, include.Blame))
                    {
                        AssertAvailableNumber(include.FieldNumber, include.Blame);
                    }

                    if (!SymbolEqualityComparer.Default.Equals(include.Type.BaseType, type))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(
                            descriptor: DataContractAnalyzer.IncludeNonDerived,
                            location: Utils.PickLocation(ref context, include.Blame),
                            messageArgs: new object[] { include.Type.ToDisplayString() },
                            additionalLocations: null,
                            properties: null
                        ));
                    }

                    for (int i = 0; i < current; i++)
                    {
                        if (SymbolEqualityComparer.Default.Equals(include.Type, _includes[i].Type))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(
                                descriptor: DataContractAnalyzer.DuplicateInclude,
                                location: Utils.PickLocation(ref context, include.Blame),
                                messageArgs: new object[] { include.Type.ToDisplayString() },
                                additionalLocations: null,
                                properties: null
                            ));
                            break;
                        }
                    }
                    current++;
                }
            }

            if (_members is not null)
            {
                foreach (var member in _members)
                {
                    if (AssertLegalFieldNumber(ref context, member.FieldNumber, member.Blame))
                    {
                        AssertAvailableNumber(member.FieldNumber, member.Blame);
                    }
                    AssertAvailableName(member.Name, member.Blame);

                    if (PropertyOrFieldExists(type, member.MemberName))
                    {
                        coveredMemberNames ??= new HashSet<string>();
                        if (!coveredMemberNames.Add(member.MemberName))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(
                                descriptor: DataContractAnalyzer.DuplicateMemberName,
                                location: Utils.PickLocation(ref context, member.Blame),
                                messageArgs: new object[] { member.MemberName },
                                additionalLocations: null,
                                properties: null
                            ));
                        }
                        if (ShouldIgnore(member.MemberName))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(
                                descriptor: DataContractAnalyzer.DeclaredAndIgnored,
                                location: Utils.PickLocation(ref context, member.Blame),
                                messageArgs: new object[] { member.MemberName },
                                additionalLocations: null,
                                properties: null
                            ));
                        }
                        else if (ShouldDeclareDefault(member, out string? defaultValue) && defaultValue != null)
                        {
                            context.ReportDiagnostic(Diagnostic.Create(
                                descriptor: DataContractAnalyzer.ShouldDeclareDefault,
                                location: Utils.PickLocation(ref context, member.Blame),
                                messageArgs: new object[] { member.MemberName, defaultValue },
                                additionalLocations: null,
                                properties: null
                            ));
                        }
                    }
                    else
                    {
                        context.ReportDiagnostic(Diagnostic.Create(
                            descriptor: DataContractAnalyzer.MemberNotFound,
                            location: Utils.PickLocation(ref context, member.Blame),
                            messageArgs: new object[] { member.MemberName },
                            additionalLocations: null,
                            properties: null
                        ));
                    }
                }
            }
            static bool PropertyOrFieldExists(ITypeSymbol type, string name)
            {
                foreach (var member in type.GetMembers())
                {
                    switch (member)
                    {
                        case IFieldSymbol:
                        case IPropertySymbol:
                            if (member.Name == name)
                                return true;
                            break;
                    }
                }
                return false;
            }
        }

        private bool ShouldDeclareDefault(Member member, /*[MaybeNullWhen(false)]*/ out string? defaultValue)
        {
            ITypeSymbol? checkType = member.Symbol switch
            {
                IPropertySymbol propSym when ShouldCheck(propSym.Type) => propSym.Type,
                IFieldSymbol fieldSym when ShouldCheck(fieldSym.Type) => fieldSym.Type,
                _ => null,
            };

            bool ShouldCheck(ITypeSymbol type)
            {
                // Marc mentions [DefaultValue], [ProtoMember(IsRequired)], and ShouldSerializeXxx() as some ways to tell PB to send the value.
                // https://stackoverflow.com/a/3162253/1882616
                if (!member.IsRequired && (IsScalarValueType(type.SpecialType) || type.TypeKind == TypeKind.Enum))
                {
                    bool hasDefaultValueAttrib = member.Symbol.GetAttributes().FirstOrDefault(attrib => attrib.AttributeClass != null
                        && attrib.AttributeClass.Name == nameof(DefaultValueAttribute)
                        && attrib.AttributeClass.InNamespace(nameof(System), nameof(System.ComponentModel))) != null;
                    if (!hasDefaultValueAttrib)
                    {
                        string methodName = "ShouldSerialize" + member.Name;
                        bool hasShouldSerializeMethod = member.Symbol.ContainingType.GetMembers().OfType<IMethodSymbol>()
                            .FirstOrDefault(method => method.Name == methodName
                                && method.ReturnType.SpecialType == SpecialType.System_Boolean) != null;
                        return !hasShouldSerializeMethod;
                    }
                }

                return false;
            }

            bool IsScalarValueType(SpecialType type)
                => type switch
                {
                    SpecialType.System_Boolean or SpecialType.System_Char or SpecialType.System_SByte or SpecialType.System_Byte
                    or SpecialType.System_Int16 or SpecialType.System_UInt16 or SpecialType.System_Int32 or SpecialType.System_UInt32
                    or SpecialType.System_Int64 or SpecialType.System_UInt64 or SpecialType.System_Decimal or SpecialType.System_Single
                    or SpecialType.System_Double or SpecialType.System_IntPtr or SpecialType.System_UIntPtr => true,
                    _ => false,
                };

            if (checkType != null)
            {
                EqualsValueClauseSyntax? equalsValue = null;
                SyntaxNode? memberNode = member.Symbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax();
                if (memberNode != null && (memberNode.IsKind(SyntaxKind.PropertyDeclaration) || memberNode.IsKind(SyntaxKind.VariableDeclarator)))
                {
                    equalsValue = (EqualsValueClauseSyntax?)memberNode.ChildNodes().FirstOrDefault(node => node.IsKind(SyntaxKind.EqualsValueClause));
                }

                SyntaxNode? valueNode = equalsValue?.ChildNodes().LastOrDefault();
                if (valueNode != null)
                {
                    SpecialType specialType = checkType.SpecialType;
                    if (specialType == SpecialType.System_Boolean && valueNode.IsKind(SyntaxKind.TrueLiteralExpression))
                    {
                        defaultValue = "true";
                        return true;
                    }
                    else if (specialType == SpecialType.System_Char && valueNode.IsKind(SyntaxKind.CharacterLiteralExpression))
                    {
                        defaultValue = valueNode.ToString();
                        return !_nullCharLiterals.Contains(defaultValue);
                    }
                    else if (specialType != SpecialType.None
                        && (valueNode.IsKind(SyntaxKind.NumericLiteralExpression) || valueNode.IsKind(SyntaxKind.UnaryMinusExpression)))
                    {
                        defaultValue = valueNode.ToString();

                        string literalValue = defaultValue.TrimEnd(_trimmableNumericSuffixes).Replace("_", string.Empty);
                        if (specialType == SpecialType.System_Single || specialType == SpecialType.System_Double)
                        {
                            literalValue = literalValue.TrimEnd(_floatNumericSuffixes);
                            return double.TryParse(literalValue, out double value) && value != 0;
                        }
                        else if (literalValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase) || literalValue.StartsWith("0b", StringComparison.OrdinalIgnoreCase))
                        {
                            return literalValue.Skip(2).Any(ch => ch != '0');
                        }
                        else if (decimal.TryParse(literalValue, out decimal decimalValue))
                        {
                            return decimalValue != 0;
                        }
                    }
                    else if (checkType.TypeKind == TypeKind.Enum
                        && valueNode is MemberAccessExpressionSyntax access
                        && access.IsKind(SyntaxKind.SimpleMemberAccessExpression)
                        && access.Expression.ToString() == checkType.Name)
                    {
                        string fieldName = access.Name.Identifier.ValueText;
                        IFieldSymbol field = checkType.GetMembers().OfType<IFieldSymbol>().FirstOrDefault(field => field.Name == fieldName);
                        if (field.HasConstantValue && string.Format(CultureInfo.InvariantCulture, "{0}", field.ConstantValue) != "0")
                        {
                            defaultValue = $"{checkType.Name}.{fieldName}";
                            return true;
                        }
                    }
                }
            }

            defaultValue = null;
            return false;
        }

        internal void SetContract(ISymbol blame, AttributeData attrib)
        {
            _ = blame;
            _flags |= DataContractContextFlags.IsProtoContract;
            if (attrib.TryGetBooleanByName(nameof(ProtoContractAttribute.SkipConstructor), out var val) && val)
                _flags |= DataContractContextFlags.SkipConstructor;
            if (attrib.TryGetBooleanByName(nameof(ProtoContractAttribute.IgnoreUnknownSubTypes), out val) && val)
                _flags |= DataContractContextFlags.IgnoreUnknownSubTypes;
        }

        public bool HasFlag(DataContractContextFlags flag)
            => (_flags & flag) != 0;


        private bool ShouldIgnore(string memberName)
        {
            if (_ignores is not null)
            {
                foreach (var ignore in _ignores)
                {
                    if (ignore.MemberName == memberName)
                        return true;
                }
            }
            return false;
        }

        internal void AddInclude(ISymbol blame, AttributeData attrib)
        {
            if (!attrib.TryGetInt32ByName(nameof(ProtoIncludeAttribute.Tag), out var tag)
                || !attrib.TryGetTypeByName(nameof(ProtoIncludeAttribute.KnownType), out var type))
                return;

            (_includes ??= new List<Include>()).Add(new Include(attrib.GetLocation(blame), tag, type));
        }

        internal void AddIgnore(ISymbol blame, AttributeData attrib, string? memberName)
        {
            if (memberName is null)
            {
                if (!(attrib.TryGetStringByName(nameof(ProtoPartialIgnoreAttribute.MemberName), out memberName)))
                    return;
            }
            (_ignores ??= new List<Ignore>()).Add(new Ignore(attrib.GetLocation(blame), memberName));
        }

        internal void AddMember(ISymbol blame, AttributeData attrib, string? memberName)
        {
            if (memberName is null)
            {
                if (!(attrib.TryGetStringByName(nameof(ProtoPartialMemberAttribute.MemberName), out memberName)))
                    return;
            }

            if (!(attrib.TryGetInt32ByName(nameof(ProtoPartialMemberAttribute.Tag), out var tag)))
                return;

            if (!(attrib.TryGetStringByName(nameof(ProtoPartialMemberAttribute.Name), out var name)))
                name = memberName;

            attrib.TryGetBooleanByName(nameof(ProtoPartialMemberAttribute.IsRequired), out bool isRequired);

            (_members ??= new List<Member>()).Add(new Member(attrib.GetLocation(blame), tag, memberName, name, blame, isRequired));
        }

        public bool OverlapsReservation(string name, out Reservation overlap)
        {
            if (_reservations is not null)
            {
                foreach (var existing in _reservations)
                {
                    if (existing.Includes(name))
                    {
                        overlap = existing;
                        return true;
                    }
                }
            }
            overlap = default;
            return false;
        }

        public bool OverlapsReservation(int number, out Reservation overlap)
        {
            if (_reservations is not null)
            {
                foreach (var existing in _reservations)
                {
                    if (existing.Includes(number))
                    {
                        overlap = existing;
                        return true;
                    }
                }
            }
            overlap = default;
            return false;
        }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/BlobSerializer.cs<|end_filename|>
﻿using System;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class BlobSerializer : IRuntimeProtoSerializerNode
    {
        public Type ExpectedType { get { return expectedType; } }

        private static readonly Type expectedType = typeof(byte[]);

        public BlobSerializer(bool overwriteList)
        {
            this.overwriteList = overwriteList;
        }

        private readonly bool overwriteList;

        public object Read(ref ProtoReader.State state, object value)
        {
            return state.AppendBytes(overwriteList ? null : (byte[])value);
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteBytes((byte[])value);
        }

        bool IRuntimeProtoSerializerNode.RequiresOldValue { get { return !overwriteList; } }
        bool IRuntimeProtoSerializerNode.ReturnsValue { get { return true; } }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            ctx.EmitStateBasedWrite(nameof(ProtoWriter.State.WriteBytes), valueFrom, argType: typeof(byte[]));
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            using var tmp = overwriteList ? default : ctx.GetLocalWithValue(typeof(byte[]), entity);
            ctx.LoadState();
            if (overwriteList)
            {
                ctx.LoadNullRef();
            }
            else
            {
                ctx.LoadValue(tmp);
            }
            ctx.EmitCall(typeof(ProtoReader.State)
               .GetMethod(nameof(ProtoReader.State.AppendBytes),
               new[] { typeof(byte[])}));
        }
    }
}

<|start_filename|>src/protobuf-net.Test/Serializers/Collections.cs<|end_filename|>
﻿using System;
using System.Buffers;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using Xunit;

namespace ProtoBuf.Serializers
{
    public class Collections
    {
        [Theory]
        [InlineData(typeof(string), null)]
        [InlineData(typeof(DoubleEnumerable), null)] // ambiguous? you can go without, then!

        [InlineData(typeof(int[]), typeof(VectorSerializer<int>))]
        [InlineData(typeof(List<int>), typeof(ListSerializer<int>))]
        [InlineData(typeof(ListGenericSubclass<int>), typeof(ListSerializer<ListGenericSubclass<int>, int>))]
        [InlineData(typeof(ListNonGenericSubclass), typeof(ListSerializer<ListNonGenericSubclass, int>))]
        [InlineData(typeof(Collection<int>), typeof(EnumerableSerializer<Collection<int>, Collection<int>, int>))]
        [InlineData(typeof(ICollection<int>), typeof(EnumerableSerializer<ICollection<int>, ICollection<int>, int>))]
        [InlineData(typeof(IEnumerable<int>), typeof(EnumerableSerializer<IEnumerable<int>, IEnumerable<int>, int>))]
        [InlineData(typeof(IList<int>), typeof(EnumerableSerializer<IList<int>, IList<int>, int>))]
        [InlineData(typeof(Dictionary<int, string>), typeof(DictionarySerializer<int, string>))]
        [InlineData(typeof(IDictionary<int, string>), typeof(DictionarySerializer<IDictionary<int,string>,int, string>))]
        [InlineData(typeof(ImmutableArray<int>), typeof(ImmutableArraySerializer<int>))]
        [InlineData(typeof(ImmutableDictionary<int, string>), typeof(ImmutableDictionarySerializer<int, string>))]
        [InlineData(typeof(ImmutableSortedDictionary<int, string>), typeof(ImmutableSortedDictionarySerializer<int, string>))]
        [InlineData(typeof(IImmutableDictionary<int, string>), typeof(ImmutableIDictionarySerializer<int, string>))]
        [InlineData(typeof(Queue<int>), typeof(QueueSerializer<Queue<int>, int>))]
        [InlineData(typeof(Stack<int>), typeof(StackSerializer<Stack<int>, int>))]
        [InlineData(typeof(CustomGenericCollection<int>), typeof(EnumerableSerializer<CustomGenericCollection<int>, CustomGenericCollection<int>,int>))]
        [InlineData(typeof(CustomNonGenericCollection), typeof(EnumerableSerializer<CustomNonGenericCollection,CustomNonGenericCollection,bool>))]
        [InlineData(typeof(IReadOnlyCollection<string>), typeof(EnumerableSerializer<IReadOnlyCollection<string>, IReadOnlyCollection<string>, string>))]
        [InlineData(typeof(CustomNonGenericReadOnlyCollection), typeof(EnumerableSerializer<CustomNonGenericReadOnlyCollection, CustomNonGenericReadOnlyCollection, string>))]
        [InlineData(typeof(CustomGenericReadOnlyCollection<string>), typeof(EnumerableSerializer<CustomGenericReadOnlyCollection<string>, CustomGenericReadOnlyCollection<string>, string>))]

        [InlineData(typeof(ImmutableList<string>), typeof(ImmutableListSerializer<string>))]
        [InlineData(typeof(IImmutableList<string>), typeof(ImmutableIListSerializer<string>))]
        [InlineData(typeof(ImmutableHashSet<string>), typeof(ImmutableHashSetSerializer<string>))]
        [InlineData(typeof(ImmutableSortedSet<string>), typeof(ImmutableSortedSetSerializer<string>))]
        [InlineData(typeof(IImmutableSet<string>), typeof(ImmutableISetSerializer<string>))]
        [InlineData(typeof(ImmutableQueue<string>), typeof(ImmutableQueueSerializer<string>))]
        [InlineData(typeof(IImmutableQueue<string>), typeof(ImmutableIQueueSerializer<string>))]
        [InlineData(typeof(ImmutableStack<string>), typeof(ImmutableStackSerializer<string>))]
        [InlineData(typeof(IImmutableStack<string>), typeof(ImmutableIStackSerializer<string>))]

        [InlineData(typeof(ConcurrentBag<string>), typeof(ConcurrentBagSerializer<ConcurrentBag<string>, string>))]
        [InlineData(typeof(ConcurrentStack<string>), typeof(ConcurrentStackSerializer<ConcurrentStack<string>, string>))]
        [InlineData(typeof(ConcurrentQueue<string>), typeof(ConcurrentQueueSerializer<ConcurrentQueue<string>, string>))]
        [InlineData(typeof(IProducerConsumerCollection<string>), typeof(ProducerConsumerSerializer<IProducerConsumerCollection<string>, string>))]

        [InlineData(typeof(CustomEnumerable), typeof(EnumerableSerializer<CustomEnumerable, CustomEnumerable, int>))]
        [InlineData(typeof(Dictionary<int[], int>), typeof(DictionarySerializer<int[], int>))]
        [InlineData(typeof(Dictionary<int, int[]>), typeof(DictionarySerializer<int, int[]>))]
        [InlineData(typeof(Dictionary<int[], int[]>), typeof(DictionarySerializer<int[], int[]>))]

        public void TestWhatProviderWeGet(Type type, Type expected)
        {
            var provider = RepeatedSerializers.TryGetRepeatedProvider(type);
            if (expected == null)
            {
                Assert.Null(provider);
            }
            else
            {
                Assert.NotNull(provider);
                var ser = provider.Serializer;
                Assert.NotNull(ser);
                Assert.Equal(expected, ser.GetType());
            }
        }

        [Theory]
        // these are things we don't expect to support at any point
        [InlineData(typeof(int[,]))]
        [InlineData(typeof(List<int>[]))]
        [InlineData(typeof(List<int[]>))]
        [InlineData(typeof(int[][]))]
        [InlineData(typeof(List<List<int>>))]

        // these are things we'll probably light up later as "repeated",
        [InlineData(typeof(ArraySegment<int>))]
        [InlineData(typeof(Memory<int>))]
        [InlineData(typeof(ReadOnlyMemory<int>))]
        [InlineData(typeof(ReadOnlySequence<int>))]
        [InlineData(typeof(IMemoryOwner<int>))]

        // these are things we'll probably light up later as "bytes",
        [InlineData(typeof(ArraySegment<byte>))]
        [InlineData(typeof(Memory<byte>))]
        [InlineData(typeof(ReadOnlyMemory<byte>))]
        [InlineData(typeof(ReadOnlySequence<byte>))]
        [InlineData(typeof(IMemoryOwner<byte>))]

        public void NotSupportedScenarios(Type type)
        {
            var provider = RepeatedSerializers.TryGetRepeatedProvider(type);
            Assert.NotNull(provider);
            Assert.Throws<NotSupportedException>(() =>
            {
                _ = provider.Serializer;
            });
        }

        // spans a: can't be stored, so the concept of assigning them
        // is bad; and b: can't be used as generics, so can't be expressed
        // as ISerializer<Span<Foo>>, etc; all in all: just nope!
        [Theory]
        [InlineData(typeof(Span<int>))]
        [InlineData(typeof(Span<byte>))]
        [InlineData(typeof(ReadOnlySpan<int>))]
        [InlineData(typeof(ReadOnlySpan<byte>))]
        public void SpansAreReallyReallyNotSupported(Type type)
        {
            var ex = Assert.Throws<NotSupportedException>(() =>
            {
                RepeatedSerializers.TryGetRepeatedProvider(type);
            });
            Assert.Equal("Serialization cannot work with [ReadOnly]Span<T>; [ReadOnly]Memory<T> may be enabled later", ex.Message);
        }

        class CustomEnumerable : IEnumerable<int>, ICollection<int>
        {
            private readonly List<int> items = new List<int>();
            IEnumerator<int> IEnumerable<int>.GetEnumerator() { return items.GetEnumerator(); }
            IEnumerator IEnumerable.GetEnumerator() { return items.GetEnumerator(); }
            public void Add(int value) { items.Add(value); }

            // need ICollection<int> for Add to work
            bool ICollection<int>.IsReadOnly => false;
            void ICollection<int>.Clear() => items.Clear();
            int ICollection<int>.Count => items.Count;
            bool ICollection<int>.Contains(int item) => items.Contains(item);
            bool ICollection<int>.Remove(int item) => items.Remove(item);
            void ICollection<int>.CopyTo(int[] array, int arrayIndex) => items.CopyTo(array, arrayIndex);
        }

        public class ListGenericSubclass<T> : List<T> { }
        public class ListNonGenericSubclass : List<int> { }

        public class CustomNonGenericReadOnlyCollection : IReadOnlyCollection<string>
        {
            int IReadOnlyCollection<string>.Count => throw new NotImplementedException();
            IEnumerator<string> IEnumerable<string>.GetEnumerator() => throw new NotImplementedException();
            IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
        }
        public class CustomGenericReadOnlyCollection<T> : IReadOnlyCollection<T>
        {
            int IReadOnlyCollection<T>.Count => throw new NotImplementedException();
            IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
            IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
        }

        public class CustomGenericCollection<T> : IList<T>
        {
            #region nope
            T IList<T>.this[int index] {
                get => throw new NotImplementedException();
                set => throw new NotImplementedException();
            }
            int ICollection<T>.Count => throw new NotImplementedException();
            bool ICollection<T>.IsReadOnly => throw new NotImplementedException();
            void ICollection<T>.Add(T item) => throw new NotImplementedException();
            void ICollection<T>.Clear() => throw new NotImplementedException();
            bool ICollection<T>.Contains(T item) => throw new NotImplementedException();
            void ICollection<T>.CopyTo(T[] array, int arrayIndex) => throw new NotImplementedException();
            IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
            IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
            int IList<T>.IndexOf(T item) => throw new NotImplementedException();
            void IList<T>.Insert(int index, T item) => throw new NotImplementedException();
            bool ICollection<T>.Remove(T item) => throw new NotImplementedException();
            void IList<T>.RemoveAt(int index) => throw new NotImplementedException();
            #endregion
        }
        public class CustomNonGenericCollection : ICollection<bool>
        {
            #region nope
            int ICollection<bool>.Count => throw new NotImplementedException();
            bool ICollection<bool>.IsReadOnly => throw new NotImplementedException();
            void ICollection<bool>.Add(bool item) => throw new NotImplementedException();
            void ICollection<bool>.Clear() => throw new NotImplementedException();
            bool ICollection<bool>.Contains(bool item) => throw new NotImplementedException();
            void ICollection<bool>.CopyTo(bool[] array, int arrayIndex) => throw new NotImplementedException();
            IEnumerator<bool> IEnumerable<bool>.GetEnumerator() => throw new NotImplementedException();
            IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
            bool ICollection<bool>.Remove(bool item) => throw new NotImplementedException();
            #endregion
        }

        public class DoubleEnumerable : IEnumerable<string>, IEnumerable<int>
        {
            IEnumerator<string> IEnumerable<string>.GetEnumerator() => throw new NotImplementedException();
            IEnumerator<int> IEnumerable<int>.GetEnumerator() => throw new NotImplementedException();
            IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
        }

    }
}


<|start_filename|>src/Examples/Issues/SO13162642.cs<|end_filename|>
﻿#if LONG_RUNNING
using Xunit;
using ProtoBuf;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xunit.Abstractions;

namespace Examples.Issues
{   
    public class SO13162642
    {
        private ITestOutputHelper Log { get; }
        public SO13162642(ITestOutputHelper _log) => Log = _log;

        [Fact]
        public void Execute()
        {
            using (var f = File.Create("Data.protobuf"))
            {
                Serializer.Serialize<IEnumerable<DTO>>(f, GenerateData(1000000));
            }

            using (var f = File.OpenRead("Data.protobuf"))
            {
                var dtos = Serializer.DeserializeItems<DTO>(f, ProtoBuf.PrefixStyle.Base128, 1);
                Log.WriteLine(dtos.Count().ToString());
            }
        }

        [Fact]
        public void ExecuteWorkaround()
        {
            using (var f = File.Create("Data.protobuf"))
            {
                foreach(var obj in GenerateData(1000000))
                {
                    Serializer.SerializeWithLengthPrefix<DTO>(
                        f, obj, PrefixStyle.Base128, Serializer.ListItemTag);
                }
            }

            using (var f = File.OpenRead("Data.protobuf"))
            {
                var dtos = Serializer.DeserializeItems<DTO>(f, ProtoBuf.PrefixStyle.Base128, 1);
                Log.WriteLine(dtos.Count().ToString());
            }
        }

        static IEnumerable<DTO> GenerateData(int count)
        {
            for (int i = 0; i < count; i++)
            {
                // reduce to 1100 to use much less memory
                var dto = new DTO { Data = new byte[1101] };
                for (int j = 0; j < dto.Data.Length; j++)
                {
                    // fill with data
                    dto.Data[j] = (byte)(i + j);
                }
                yield return dto;
            }
        }

        [ProtoContract]
        class DTO
        {
            [ProtoMember(1, DataFormat = ProtoBuf.DataFormat.Group)]
            public byte[] Data { get; set; }
        }
    }
}
#endif

<|start_filename|>src/protobuf-net/Internal/Serializers/ArrayDecorator.cs<|end_filename|>
﻿//using ProtoBuf.Compiler;
//using System;
//using System.Collections.Generic;
//using System.Diagnostics;
//using System.Linq;
//using System.Reflection;

//namespace ProtoBuf.Internal.Serializers
//{
//    internal static class ArrayDecorator
//    {
//        public static IRuntimeProtoSerializerNode Create(Type type, int fieldNumber, SerializerFeatures features)
//        {
//            return (IRuntimeProtoSerializerNode)Activator.CreateInstance(typeof(ArrayDecorator<>).MakeGenericType(type),
//                new object[] { fieldNumber, features });
//        }

//        // look for: public T[] ReadRepeated<T>(SerializerFeatures features, T[] values, ISerializer<T> serializer = null)
//        internal static readonly MethodInfo s_ReadRepeated = (
//            from method in typeof(ProtoReader.State).GetMethods(BindingFlags.Instance | BindingFlags.Public)
//            where method.Name == nameof(ProtoReader.State.ReadRepeated) && method.IsGenericMethodDefinition
//            let targs = method.GetGenericArguments()
//            where targs.Length == 1
//            let args = method.GetParameters()
//            let arrType = targs[0].MakeArrayType()
//            where args.Length == 3
//            && method.ReturnType == arrType
//            && args[0].ParameterType == typeof(SerializerFeatures)
//            && args[1].ParameterType == arrType
//            && args[2].ParameterType == typeof(ISerializer<>).MakeGenericType(targs)
//            select method).SingleOrDefault();
//    }
//    internal sealed class ArrayDecorator<T> : IRuntimeProtoSerializerNode, ICompiledSerializer
//    {
//        static readonly MethodInfo s_ReadRepeated = ArrayDecorator.s_ReadRepeated.MakeGenericMethod(typeof(T));
//        static readonly MethodInfo s_WriteRepeated = ListDecorator.s_WriteRepeated.MakeGenericMethod(typeof(T));

//        private readonly int _fieldNumber;
//        private readonly SerializerFeatures _features;

//        public ArrayDecorator(int fieldNumber, SerializerFeatures features)
//        {
//            Debug.Assert(typeof(T) != typeof(byte), "Should have used BlobSerializer");
//            _fieldNumber = fieldNumber;
//            _features = features;
//        }

//        public Type ExpectedType => typeof(T[]);
//        public bool RequiresOldValue => (_features & SerializerFeatures.OptionClearCollection) == 0;
//        public bool ReturnsValue { get { return true; } }

//        public void Write(ref ProtoWriter.State state, object value)
//            => state.WriteRepeated(_fieldNumber, _features, (T[])value);

//        public object Read(ref ProtoReader.State state, object value)
//            => state.ReadRepeated(_features, RequiresOldValue ? (T[])value : null);

//        public void EmitRead(CompilerContext ctx, Local valueFrom)
//        {
//            using var loc = RequiresOldValue ? ctx.GetLocalWithValue(typeof(T[]), valueFrom) : default;
//            ctx.LoadState();
//            ctx.LoadValue((int)_features);
//            if (loc is null)
//                ctx.LoadNullRef();
//            else
//                ctx.LoadValue(loc);
//            ctx.LoadSelfAsService<ISerializer<T>, T>();
//            ctx.EmitCall(s_ReadRepeated);
//        }

//        public void EmitWrite(CompilerContext ctx, Local valueFrom)
//        {
//            using var loc = ctx.GetLocalWithValue(typeof(T[]), valueFrom);
//            ctx.LoadState();
//            ctx.LoadValue(_fieldNumber);
//            ctx.LoadValue((int)_features);
//            ctx.LoadValue(loc);
//            ctx.LoadSelfAsService<ISerializer<T>, T>();
//            ctx.EmitCall(s_WriteRepeated);
//        }
//    }
//}

<|start_filename|>src/Examples/PEVerify.cs<|end_filename|>
﻿using System;
using System.Diagnostics;
using Xunit;
using System.IO;

namespace Examples
{
    public static class PEVerify
    {
#if !COREFX
        static readonly string exePath;
        static readonly bool unavailable;
        static PEVerify()
        {
            exePath = Environment.ExpandEnvironmentVariables(@"%ProgramFiles(x86)%\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\PEVerify.exe");
            if (!File.Exists(exePath))
            {
                Console.Error.WriteLine("PEVerify not found at " + exePath);
                unavailable = true;
            }
        }
#endif
        public static void AssertValid(string path)
        {
#if COREFX
            return;
#else
            if (unavailable) return;
            if(!File.Exists(path))
            {
                throw new FileNotFoundException(path);
            }
            ProcessStartInfo psi = new ProcessStartInfo(exePath, path);
            psi.CreateNoWindow = true;
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            using (Process proc = Process.Start(psi))
            {
                if (proc.WaitForExit(10000))
                {
                    Assert.Equal(0, proc.ExitCode); //, path);
                    return; // proc.ExitCode == 0;
                }
                else
                {
                    proc.Kill();
                    throw new TimeoutException();
                }
            }
#endif
        }
    }
}


<|start_filename|>src/Examples/Issues/Issue713.cs<|end_filename|>
﻿using Examples;
using ProtoBuf.Meta;
using System;
using System.IO;
using System.Linq;
using Xunit;

namespace ProtoBuf.Issues
{
    public class Issue713
    {
        [Fact]
        public void CanSerializeNullableInt32Array_NoNulls()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            Test(model);
            model.CompileInPlace();
            Test(model);

            var dll = model.Compile(nameof(CanSerializeNullableInt32Array_NoNulls), nameof(CanSerializeNullableInt32Array_NoNulls) + ".dll");
            PEVerify.AssertValid(nameof(CanSerializeNullableInt32Array_NoNulls) + ".dll");
            Test(dll);

            Test(model.Compile());


            static void Test(TypeModel model)
            {
                var orig = new WithInt32 { Values = new int?[] { 0, 1, -2, 3 } };
                using var ms = new MemoryStream();
                model.Serialize(ms, orig);
                var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
                ms.Position = 0;
                var clone = model.Deserialize<WithInt32>(ms);
                Assert.True(Enumerable.SequenceEqual(orig.Values, clone.Values));
            }
        }

        [Fact]
        public void CanNotSerializeNullableInt32Array_WithNulls()
        {
            var orig = new WithInt32 { Values = new int?[] { 0, null, 1, -2, 3, null } };
            using var ms = new MemoryStream();
            var ex = Assert.Throws<NullReferenceException>(() => Serializer.Serialize(ms, orig));
            Assert.Equal("An element of type System.Nullable`1[System.Int32] was null; this might be as contents in a list/array", ex.Message);
        }

        [ProtoContract]
        public class WithInt32
        {
            [ProtoMember(1)]
            public int?[] Values { get; set; }
        }

        [Fact]
        public void CanSerializeNullableSomeEnumArray_NoNulls()
        {
            var model = RuntimeTypeModel.Create();
            model.AutoCompile = false;
            Test(model);
            model.CompileInPlace();
            Test(model);

            var dll = model.Compile(nameof(CanSerializeNullableSomeEnumArray_NoNulls), nameof(CanSerializeNullableSomeEnumArray_NoNulls) + ".dll");
            PEVerify.AssertValid(nameof(CanSerializeNullableInt32Array_NoNulls) + ".dll");
            Test(dll);

            //Test(model.Compile());

            static void Test(TypeModel model)
            {
                var orig = new WithSomeEnum { Values = new SomeEnum?[] { SomeEnum.A, SomeEnum.B, SomeEnum.C, SomeEnum.D } };
                using var ms = new MemoryStream();
                model.Serialize(ms, orig);
                var hex = BitConverter.ToString(ms.GetBuffer(), 0, (int)ms.Length);
                ms.Position = 0;
                var clone = model.Deserialize<WithSomeEnum>(ms);
                Assert.True(Enumerable.SequenceEqual(orig.Values, clone.Values));
            }
        }

        [Fact]
        public void CanNotSerializeNullableSomeEnumArray_WithNulls()
        {
            var orig = new WithSomeEnum { Values = new SomeEnum?[] { SomeEnum.A, null, SomeEnum.B, SomeEnum.C, SomeEnum.D, null } };
            using var ms = new MemoryStream();
            var ex = Assert.Throws<NullReferenceException>(() => Serializer.Serialize(ms, orig));
            Assert.Equal("An element of type System.Nullable`1[ProtoBuf.Issues.Issue713+SomeEnum] was null; this might be as contents in a list/array", ex.Message);
        }

        [ProtoContract]
        public class WithSomeEnum
        {
            [ProtoMember(1)]
            public SomeEnum?[] Values { get; set; }
        }

        public enum SomeEnum
        {
            A = 0,
            B = 1,
            C = -2,
            D = 3,
        }



    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/Int64Serializer.cs<|end_filename|>
﻿using System;
using System.Diagnostics;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class Int64Serializer : IRuntimeProtoSerializerNode
    {
        private Int64Serializer() { }
        internal static readonly Int64Serializer Instance = new Int64Serializer();

        private static readonly Type expectedType = typeof(long);

        public Type ExpectedType => expectedType;

        bool IRuntimeProtoSerializerNode.RequiresOldValue => false;

        bool IRuntimeProtoSerializerNode.ReturnsValue => true;

        public object Read(ref ProtoReader.State state, object value)
        {
            Debug.Assert(value is null); // since replaces
            return state.ReadInt64();
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            state.WriteInt64((long)value);
        }

        void IRuntimeProtoSerializerNode.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            ctx.EmitStateBasedWrite(nameof(ProtoWriter.State.WriteInt64), valueFrom);
        }
        void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity)
        {
            ctx.EmitStateBasedRead(nameof(ProtoReader.State.ReadInt64), ExpectedType);
        }
    }
}

<|start_filename|>src/protobuf-net.Core/Meta/ProtoSyntax.cs<|end_filename|>
﻿using System;

namespace ProtoBuf.Meta
{
    /// <summary>
    /// Indiate the variant of the protobuf .proto DSL syntax to use
    /// </summary>
    public enum ProtoSyntax
    {
        /// <summary>
        /// Use the global default
        /// </summary>
        Default = -1,
        /// <summary>
        /// https://developers.google.com/protocol-buffers/docs/proto
        /// </summary>
        Proto2 = 0,
        /// <summary>
        /// https://developers.google.com/protocol-buffers/docs/proto3
        /// </summary>
        Proto3 = 1,
    }
}

<|start_filename|>src/protobuf-net.AspNetCore/MvcProtoBufNetOptions.cs<|end_filename|>
﻿using ProtoBuf.Meta;

namespace ProtoBuf.AspNetCore
{
    /// <summary>
    /// Options for configuring protobuf-net usage inside ASP.NET Core
    /// </summary>
    public sealed class MvcProtoBufNetOptions
    {
        /// <summary>
        /// The type-model to use for serialization and deserialization; if omitted, the default model is assumed
        /// </summary>
        public TypeModel Model { get; set; }

        /// <summary>
        /// The maximum length of payloads to write; no limit by default
        /// </summary>
        public long WriteMaxLength { get; set; } = -1;

        /// <summary>
        /// The amount of memory to use for in-memory buffering if needed
        /// </summary>
        public int ReadMemoryBufferThreshold { get; set; } = 256 * 1024; // kinda arbitrary
    }
}


<|start_filename|>src/protobuf-net.Core/Internal/Level240DefaultSerializer.cs<|end_filename|>
﻿using ProtoBuf.Serializers;
using System;

namespace ProtoBuf.Internal
{
    internal class Level240DefaultSerializer :
        ISerializer<DateTime>, ISerializer<DateTime?>,
        ISerializer<TimeSpan>, ISerializer<TimeSpan?>
    {
        DateTime? ISerializer<DateTime?>.Read(ref ProtoReader.State state, DateTime? value)
            => ((ISerializer<DateTime>)this).Read(ref state, value.GetValueOrDefault());
        void ISerializer<DateTime?>.Write(ref ProtoWriter.State state, DateTime? value)
            => ((ISerializer<DateTime>)this).Write(ref state, value.Value);

        TimeSpan? ISerializer<TimeSpan?>.Read(ref ProtoReader.State state, TimeSpan? value)
            => ((ISerializer<TimeSpan>)this).Read(ref state, value.GetValueOrDefault());
        void ISerializer<TimeSpan?>.Write(ref ProtoWriter.State state, TimeSpan? value)
            => ((ISerializer<TimeSpan>)this).Write(ref state, value.Value);

        DateTime ISerializer<DateTime>.Read(ref ProtoReader.State state, DateTime value)
            => PrimaryTypeProvider.ReadTimestamp(ref state, value);

        void ISerializer<DateTime>.Write(ref ProtoWriter.State state, DateTime value)
            => PrimaryTypeProvider.WriteTimestamp(ref state, value);

        TimeSpan ISerializer<TimeSpan>.Read(ref ProtoReader.State state, TimeSpan value)
            => PrimaryTypeProvider.ReadDuration(ref state, value);

        void ISerializer<TimeSpan>.Write(ref ProtoWriter.State state, TimeSpan value)
            => PrimaryTypeProvider.WriteDuration(ref state, value);

        SerializerFeatures ISerializer<TimeSpan>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        SerializerFeatures ISerializer<TimeSpan?>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        SerializerFeatures ISerializer<DateTime>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
        SerializerFeatures ISerializer<DateTime?>.Features => SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;
    }
}


<|start_filename|>src/TheAwaitingGame/BenchmarkDotNet.Artifacts/results/Benchmarker-report.html<|end_filename|>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Benchmarker</title>

<style type="text/css">
	table { border-collapse: collapse; display: block; width: 100%; overflow: auto; }
	td, th { padding: 6px 13px; border: 1px solid #ddd; }
	tr { background-color: #fff; border-top: 1px solid #ccc; }
	tr:nth-child(even) { background: #f8f8f8; }
</style>
</head>
<body>
<pre><code>
BenchmarkDotNet=v0.10.3.111-nightly, OS=Windows 10.0.15063
Processor=Intel(R) Core(TM) i7-7700HQ CPU 2.80GHz, ProcessorCount=8
Frequency=2742188 Hz, Resolution=364.6723 ns, Timer=TSC
dotnet cli version=1.0.2
  [Host]     : .NET Core 4.6.25009.03, 64bit RyuJIT
  Job-RZXVEI : .NET Core 4.6.25009.03, 64bit RyuJIT
</code></pre>
<pre><code>Force=False  
</code></pre>

<table>
<thead><tr><th>                  Method</th><th>Mean</th><th>StdDev</th><th>Op/s</th><th>Gen 0</th><th>Gen 1</th><th>Allocated</th>
</tr>
</thead><tbody><tr><td>                    Sync</td><td>20.2238 us</td><td>0.0964 us</td><td>49446.57</td><td>-</td><td>-</td><td>0 kB</td>
</tr><tr><td>               TaskAsync</td><td>30.6326 us</td><td>0.3065 us</td><td>32645</td><td>7.7250</td><td>-</td><td>24.25 kB</td>
</tr><tr><td>        TaskCheckedAsync</td><td>30.0058 us</td><td>0.1833 us</td><td>33326.85</td><td>7.7250</td><td>-</td><td>24.25 kB</td>
</tr><tr><td>          ValueTaskAsync</td><td>35.1996 us</td><td>0.3619 us</td><td>28409.39</td><td>-</td><td>-</td><td>0 kB</td>
</tr><tr><td>   ValueTaskWrappedAsync</td><td>33.2181 us</td><td>0.2537 us</td><td>30104.09</td><td>1.2667</td><td>0.0083</td><td>3.99 kB</td>
</tr><tr><td>ValueTaskDecimalReferenceAsync</td><td>30.1789 us</td><td>0.6205 us</td><td>33135.76</td><td>3.0917</td><td>-</td><td>9.7 kB</td>
</tr><tr><td>   ValueTaskCheckedAsync</td><td>32.5184 us</td><td>0.2960 us</td><td>30751.79</td><td>-</td><td>-</td><td>0 kB</td>
</tr><tr><td>        HandCrankedAsync</td><td>25.8619 us</td><td>0.1911 us</td><td>38666.89</td><td>-</td><td>-</td><td>0 kB</td>
</tr><tr><td>    AssertCompletedAsync</td><td>27.9178 us</td><td>0.1402 us</td><td>35819.44</td><td>-</td><td>-</td><td>0 kB</td>
</tr><tr><td>         TaskDoubleAsync</td><td>26.0973 us</td><td>0.2359 us</td><td>38318.2</td><td>6.9500</td><td>-</td><td>21.83 kB</td>
</tr><tr><td>    ValueTaskDoubleAsync</td><td>28.7127 us</td><td>0.2823 us</td><td>34827.83</td><td>-</td><td>-</td><td>0 kB</td>
</tr></tbody></table>
</body>
</html>


<|start_filename|>src/protogen.site.blazor.client/wwwroot/css/site.css<|end_filename|>
﻿
html,
body {
    height: 100%;
}

.nav-tabs {
    overflow-x: auto;
    overflow-y: hidden;
    display: -webkit-box;
    display: -moz-box;
}

    .nav-tabs > li {
        float: none;
    }

        .nav-tabs > li a.nav-link.active {
            border-bottom: 3px #007bff solid;
        }


<|start_filename|>src/protobuf-net.Reflection/CodeGenerator.OneOfStub.cs<|end_filename|>
﻿using Google.Protobuf.Reflection;

namespace ProtoBuf.Reflection
{
    public partial class CommonCodeGenerator
    {
        /// <summary>
        /// Represents the union summary of a one-of declaration
        /// </summary>
        protected class OneOfStub
        {
            /// <summary>
            /// The underlying descriptor
            /// </summary>
            public OneofDescriptorProto OneOf { get; }

            /// <summary>
            /// The effective index of this stub
            /// </summary>
            public int Index { get; }

            internal OneOfStub(OneofDescriptorProto decl, int index)
            {
                OneOf = decl;
                Index = index;
            }
            internal int Count32 { get; private set; }
            internal int Count64 { get; private set; }
            internal int Count128 { get; private set; }
            internal int CountRef { get; private set; }
            internal int CountTotal => CountRef + Count32 + Count64;

            private void AccountFor(FieldDescriptorProto.Type type, string typeName)
            {
                switch (type)
                {
                    case FieldDescriptorProto.Type.TypeBool:
                    case FieldDescriptorProto.Type.TypeEnum:
                    case FieldDescriptorProto.Type.TypeFixed32:
                    case FieldDescriptorProto.Type.TypeFloat:
                    case FieldDescriptorProto.Type.TypeInt32:
                    case FieldDescriptorProto.Type.TypeSfixed32:
                    case FieldDescriptorProto.Type.TypeSint32:
                    case FieldDescriptorProto.Type.TypeUint32:
                        Count32++;
                        break;
                    case FieldDescriptorProto.Type.TypeDouble:
                    case FieldDescriptorProto.Type.TypeFixed64:
                    case FieldDescriptorProto.Type.TypeInt64:
                    case FieldDescriptorProto.Type.TypeSfixed64:
                    case FieldDescriptorProto.Type.TypeSint64:
                    case FieldDescriptorProto.Type.TypeUint64:
                        Count32++;
                        Count64++;
                        break;
                    case FieldDescriptorProto.Type.TypeMessage:
                        switch(typeName)
                        {
                            case ".google.protobuf.Timestamp":
                            case ".google.protobuf.Duration":
                                Count64++;
                                break;
                            case ".bcl.Guid":
                                Count128++;
                                break;
                            default:
                                CountRef++;
                                break;
                        }
                        break;
                    default:
                        CountRef++;
                        break;
                }
            }
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0066:Convert switch statement to expression", Justification = "Readability")]
            internal string GetStorage(FieldDescriptorProto.Type type, string typeName)
            {
                switch (type)
                {
                    case FieldDescriptorProto.Type.TypeBool:
                        return "Boolean";
                    case FieldDescriptorProto.Type.TypeInt32:
                    case FieldDescriptorProto.Type.TypeSfixed32:
                    case FieldDescriptorProto.Type.TypeSint32:
                    case FieldDescriptorProto.Type.TypeEnum:
                        return "Int32";
                    case FieldDescriptorProto.Type.TypeFloat:
                        return "Single";
                    case FieldDescriptorProto.Type.TypeFixed32:
                    case FieldDescriptorProto.Type.TypeUint32:
                        return "UInt32";
                    case FieldDescriptorProto.Type.TypeDouble:
                        return "Double";
                    case FieldDescriptorProto.Type.TypeInt64:
                    case FieldDescriptorProto.Type.TypeSfixed64:
                    case FieldDescriptorProto.Type.TypeSint64:
                        return "Int64";
                    case FieldDescriptorProto.Type.TypeFixed64:
                    case FieldDescriptorProto.Type.TypeUint64:
                        return "UInt64";
                    case FieldDescriptorProto.Type.TypeMessage:
                        return typeName switch
                        {
                            ".google.protobuf.Timestamp" => "DateTime",
                            ".google.protobuf.Duration" => "TimeSpan",
                            ".bcl.Guid" => "Guid",
                            _ => "Object",
                        };
                    default:
                        return "Object";
                }
            }
            internal static OneOfStub[] Build(DescriptorProto message)
            {
                if (message.OneofDecls.Count == 0) return null;
                var stubs = new OneOfStub[message.OneofDecls.Count];
                int index = 0;
                foreach (var decl in message.OneofDecls)
                {
                    stubs[index] = new OneOfStub(decl, index);
                    index++;
                }
                foreach (var field in message.Fields)
                {
                    if (field.ShouldSerializeOneofIndex())
                    {
                        stubs[field.OneofIndex].AccountFor(field.type, field.TypeName);
                    }
                }
                return stubs;
            }
            private bool isFirst = true;
            internal bool IsFirst()
            {
                if (isFirst)
                {
                    isFirst = false;
                    return true;
                }
                return false;
            }

            internal string GetUnionType()
            {
                if (Count128 != 0)
                {
                    return CountRef == 0 ? "DiscriminatedUnion128" : "DiscriminatedUnion128Object";
                }
                if (Count64 != 0)
                {
                    return CountRef == 0 ? "DiscriminatedUnion64" : "DiscriminatedUnion64Object";
                }
                if (Count32 != 0)
                {
                    return CountRef == 0 ? "DiscriminatedUnion32" : "DiscriminatedUnion32Object";
                }
                return "DiscriminatedUnionObject";
            }
        }
    }
}


<|start_filename|>src/protobuf-net/Internal/Serializers/TupleSerializer.cs<|end_filename|>
﻿using System;
using System.Reflection;
using ProtoBuf.Meta;
using ProtoBuf.Serializers;

namespace ProtoBuf.Internal.Serializers
{
    internal sealed class TupleSerializer<T> : IProtoTypeSerializer, ISerializer<T>
    {
        public SerializerFeatures Features { get; private set; } = SerializerFeatures.WireTypeString | SerializerFeatures.CategoryMessage;

        bool IProtoTypeSerializer.IsSubType => false;
        private readonly MemberInfo[] members;
        private readonly ConstructorInfo ctor;
        private readonly IRuntimeProtoSerializerNode[] tails;
        public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, SerializerFeatures features, CompatibilityLevel compatibilityLevel)
        {
            this.ctor = ctor ?? throw new ArgumentNullException(nameof(ctor));
            this.members = members ?? throw new ArgumentNullException(nameof(members));
            this.tails = new IRuntimeProtoSerializerNode[members.Length];

            Features = features;
            ParameterInfo[] parameters = ctor.GetParameters();
            for (int i = 0; i < members.Length; i++)
            {
                Type finalType = parameters[i].ParameterType;

                var repeated = model.TryGetRepeatedProvider(finalType);
                Type tmp = repeated?.ItemType ?? finalType;

                bool asReference = false;
                int typeIndex = model.FindOrAddAuto(tmp, false, true, false, compatibilityLevel);
                if (typeIndex >= 0)
                {
                    asReference = model[tmp].AsReferenceDefault;
                }
                IRuntimeProtoSerializerNode tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, compatibilityLevel, tmp, out WireType wireType, asReference, false, false, true), serializer;
                if (tail is null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName);
                }

                if (repeated is null)
                {
                    serializer = new TagDecorator(i + 1, wireType, false, tail);
                }
                else if (repeated.IsMap)
                {
                    serializer = ValueMember.CreateMap(repeated, model, DataFormat.Default, compatibilityLevel, DataFormat.Default, DataFormat.Default, asReference, false, true, false, i + 1);
                }
                else
                {

                    SerializerFeatures listFeatures = wireType.AsFeatures() | SerializerFeatures.OptionPackedDisabled;
                    serializer = RepeatedDecorator.Create(repeated, i + 1, listFeatures, compatibilityLevel, DataFormat.Default);
                }
                tails[i] = serializer;
            }
        }
        public bool HasCallbacks(Meta.TypeModel.CallbackType callbackType)
        {
            return false;
        }

        public void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, Meta.TypeModel.CallbackType callbackType) { }
        public Type ExpectedType => typeof(T);
        Type IProtoTypeSerializer.BaseType => typeof(T);

        void IProtoTypeSerializer.Callback(object value, Meta.TypeModel.CallbackType callbackType, ISerializationContext context) { }
        object IProtoTypeSerializer.CreateInstance(ISerializationContext source) { throw new NotSupportedException(); }
        private object GetValue(object obj, int index)
        {
            if (members[index] is PropertyInfo prop)
            {
                if (obj is null)
                    return prop.PropertyType.IsValueType ? Activator.CreateInstance(prop.PropertyType, nonPublic: true) : null;
                return prop.GetValue(obj, null);
            }
            else if (members[index] is FieldInfo field)
            {
                if (obj is null)
                    return field.FieldType.IsValueType ? Activator.CreateInstance(field.FieldType, nonPublic: true) : null;
                return field.GetValue(obj);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }

        T ISerializer<T>.Read(ref ProtoReader.State state, T value)
            => (T)Read(ref state, value);

        void ISerializer<T>.Write(ref ProtoWriter.State state, T value)
            => Write(ref state, value);

        public object Read(ref ProtoReader.State state, object value)
        {
            object[] values = new object[members.Length];
            bool invokeCtor = false;
            if (value is null)
            {
                invokeCtor = true;
            }
            for (int i = 0; i < values.Length; i++)
                values[i] = GetValue(value, i);
            int field;
            while ((field = state.ReadFieldHeader()) > 0)
            {
                invokeCtor = true;
                if (field <= tails.Length)
                {
                    IRuntimeProtoSerializerNode tail = tails[field - 1];
                    values[field - 1] = tails[field - 1].Read(ref state, tail.RequiresOldValue ? values[field - 1] : null);
                }
                else
                {
                    state.SkipField();
                }
            }
            return invokeCtor ? ctor.Invoke(values) : value;
        }

        public void Write(ref ProtoWriter.State state, object value)
        {
            for (int i = 0; i < tails.Length; i++)
            {
                object val = GetValue(value, i);
                if (val is object) tails[i].Write(ref state, val);
            }
        }

        public bool RequiresOldValue => true;

        public bool ReturnsValue => false;

        bool IProtoTypeSerializer.CanCreateInstance() { return false; }

        private Type GetMemberType(int index)
        {
            Type result = Helpers.GetMemberType(members[index]);
            if (result is null) throw new InvalidOperationException();
            return result;
        }
        public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using Compiler.Local loc = ctx.GetLocalWithValue(ctor.DeclaringType, valueFrom);
            for (int i = 0; i < tails.Length; i++)
            {
                Type type = GetMemberType(i);
                ctx.LoadAddress(loc, ExpectedType);
                if (members[i] is FieldInfo fieldInfo)
                {
                    ctx.LoadValue(fieldInfo);
                }
                else if (members[i] is PropertyInfo propertyInfo)
                {
                    ctx.LoadValue(propertyInfo);
                }
                ctx.WriteNullCheckedTail(type, tails[i], null);
            }
        }

        bool IProtoTypeSerializer.ShouldEmitCreateInstance => false;
        void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx, bool callNoteObject) { throw new NotSupportedException(); }

        void IProtoTypeSerializer.EmitReadRoot(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
            => EmitRead(ctx, valueFrom);

        void IProtoTypeSerializer.EmitWriteRoot(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
            => EmitWrite(ctx, valueFrom);

        bool IProtoTypeSerializer.HasInheritance => false;

        public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local incoming)
        {
            using Compiler.Local objValue = ctx.GetLocalWithValue(ExpectedType, incoming);
            Compiler.Local[] locals = new Compiler.Local[members.Length];
            try
            {
                for (int i = 0; i < locals.Length; i++)
                {
                    Type type = GetMemberType(i);
                    bool store = true;
                    locals[i] = new Compiler.Local(ctx, type);
                    if (!ExpectedType.IsValueType)
                    {
                        // value-types always read the old value
                        if (type.IsValueType)
                        {
                            switch (Helpers.GetTypeCode(type))
                            {
                                case ProtoTypeCode.Boolean:
                                case ProtoTypeCode.Byte:
                                case ProtoTypeCode.Int16:
                                case ProtoTypeCode.Int32:
                                case ProtoTypeCode.SByte:
                                case ProtoTypeCode.UInt16:
                                case ProtoTypeCode.UInt32:
                                    ctx.LoadValue(0);
                                    break;
                                case ProtoTypeCode.Int64:
                                case ProtoTypeCode.UInt64:
                                    ctx.LoadValue(0L);
                                    break;
                                case ProtoTypeCode.Single:
                                    ctx.LoadValue(0.0F);
                                    break;
                                case ProtoTypeCode.Double:
                                    ctx.LoadValue(0.0D);
                                    break;
                                case ProtoTypeCode.Decimal:
                                    ctx.LoadValue(0M);
                                    break;
                                case ProtoTypeCode.Guid:
                                    ctx.LoadValue(Guid.Empty);
                                    break;
                                default:
                                    ctx.LoadAddress(locals[i], type);
                                    ctx.EmitCtor(type);
                                    store = false;
                                    break;
                            }
                        }
                        else
                        {
                            ctx.LoadNullRef();
                        }
                        if (store)
                        {
                            ctx.StoreValue(locals[i]);
                        }
                    }
                }

                Compiler.CodeLabel skipOld = ExpectedType.IsValueType
                                                    ? new Compiler.CodeLabel()
                                                    : ctx.DefineLabel();
                if (!ExpectedType.IsValueType)
                {
                    ctx.LoadAddress(objValue, ExpectedType);
                    ctx.BranchIfFalse(skipOld, false);
                }
                for (int i = 0; i < members.Length; i++)
                {
                    ctx.LoadAddress(objValue, ExpectedType);
                    if (members[i] is FieldInfo fieldInfo)
                    {
                        ctx.LoadValue(fieldInfo);
                    }
                    else if (members[i] is PropertyInfo propertyInfo)
                    {
                        ctx.LoadValue(propertyInfo);
                    }
                    ctx.StoreValue(locals[i]);
                }

                if (!ExpectedType.IsValueType) ctx.MarkLabel(skipOld);

                using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof(int)))
                {
                    Compiler.CodeLabel @continue = ctx.DefineLabel(),
                                       processField = ctx.DefineLabel(),
                                       notRecognised = ctx.DefineLabel();
                    ctx.Branch(@continue, false);

                    Compiler.CodeLabel[] handlers = new Compiler.CodeLabel[members.Length];
                    for (int i = 0; i < members.Length; i++)
                    {
                        handlers[i] = ctx.DefineLabel();
                    }

                    ctx.MarkLabel(processField);

                    ctx.LoadValue(fieldNumber);
                    ctx.LoadValue(1);
                    ctx.Subtract(); // jump-table is zero-based
                    ctx.Switch(handlers);

                    // and the default:
                    ctx.Branch(notRecognised, false);
                    for (int i = 0; i < handlers.Length; i++)
                    {
                        ctx.MarkLabel(handlers[i]);
                        IRuntimeProtoSerializerNode tail = tails[i];
                        Compiler.Local oldValIfNeeded = tail.RequiresOldValue ? locals[i] : null;
                        ctx.ReadNullCheckedTail(locals[i].Type, tail, oldValIfNeeded);
                        if (tail.ReturnsValue)
                        {
                            if (locals[i].Type.IsValueType)
                            {
                                ctx.StoreValue(locals[i]);
                            }
                            else
                            {
                                Compiler.CodeLabel hasValue = ctx.DefineLabel(), allDone = ctx.DefineLabel();

                                ctx.CopyValue();
                                ctx.BranchIfTrue(hasValue, true); // interpret null as "don't assign"
                                ctx.DiscardValue();
                                ctx.Branch(allDone, true);
                                ctx.MarkLabel(hasValue);
                                ctx.StoreValue(locals[i]);
                                ctx.MarkLabel(allDone);
                            }
                        }
                        ctx.Branch(@continue, false);
                    }

                    ctx.MarkLabel(notRecognised);
                    ctx.LoadState();
                    ctx.EmitCall(typeof(ProtoReader.State).GetMethod(nameof(ProtoReader.State.SkipField), Type.EmptyTypes));

                    ctx.MarkLabel(@continue);
                    ctx.EmitStateBasedRead(nameof(ProtoReader.State.ReadFieldHeader), typeof(int));
                    ctx.CopyValue();
                    ctx.StoreValue(fieldNumber);
                    ctx.LoadValue(0);
                    ctx.BranchIfGreater(processField, false);
                }
                for (int i = 0; i < locals.Length; i++)
                {
                    ctx.LoadValue(locals[i]);
                }

                ctx.EmitCtor(ctor);
                ctx.StoreValue(objValue);
            }
            finally
            {
                for (int i = 0; i < locals.Length; i++)
                {
                    if (locals[i] is object)
                        locals[i].Dispose(); // release for re-use
                }
            }
        }
    }
}

<|start_filename|>src/protobuf-net.Core/ProtoException.cs<|end_filename|>
﻿using System;

using System.Runtime.Serialization;
namespace ProtoBuf
{
    /// <summary>
    /// Indicates an error during serialization/deserialization of a proto stream.
    /// </summary>
    [Serializable]
    public class ProtoException : Exception
    {
        /// <summary>Creates a new ProtoException instance.</summary>
        public ProtoException() { }

        /// <summary>Creates a new ProtoException instance.</summary>
        public ProtoException(string message) : base(message) { }

        /// <summary>Creates a new ProtoException instance.</summary>
        public ProtoException(string message, Exception innerException) : base(message, innerException) { }

        /// <summary>Creates a new ProtoException instance.</summary>
        protected ProtoException(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }
}


<|start_filename|>src/Examples/NWind/CompatDbBuffers.cs<|end_filename|>
﻿#if PLAT_SPANS

using DAL;
using Examples;
using Pipelines.Sockets.Unofficial.Buffers;
using ProtoBuf.Meta;
using System;
using System.Buffers;
using System.Diagnostics;
using System.IO;
using Xunit;
using Xunit.Abstractions;

namespace ProtoBuf.NWind
{
    public class CompatDbBuffers
    {
        private readonly ITestOutputHelper Log;
        public CompatDbBuffers(ITestOutputHelper log)
        {
            Log = log;
            Serializer.PrepareSerializer<DatabaseCompat>();
        }

        [Fact]
        public void GenerateModel()
        {
            var model = RuntimeTypeModel.Create();
            model.Add(typeof(DatabaseCompat), true);
            model.Compile("CompatDbBuffers", "CompatDbBuffers.dll");
            Log?.WriteLine(Path.Combine(Environment.CurrentDirectory, "CompatDbBuffers.dll"));
            PEVerify.AssertValid("CompatDbBuffers.dll");
        }

        private DatabaseCompat LoadFromDisk(out ReadOnlySpan<byte> contents)
        {
            var path = NWindTests.GetNWindBinPath();
            byte[] arr = File.ReadAllBytes(path);
            Log?.WriteLine($"{arr.Length} bytes loaded from {path}");
            contents = arr;
            using var readState = ProtoReader.State.Create(arr, RuntimeTypeModel.Default);
            var watch = Stopwatch.StartNew();
            var obj = (DatabaseCompat)readState.DeserializeRoot<DatabaseCompat>(null);
            watch.Stop();
            Log?.WriteLine($"Deserialized: {watch.ElapsedMilliseconds}ms");
            return obj;
        }

        void Write(DatabaseCompat db, ref ProtoWriter.State state)
        {
            try
            {
                var watch = Stopwatch.StartNew();
                state.SerializeRoot(db);
                state.Close();
                watch.Stop();
                Log?.WriteLine($"Serialized: {watch.ElapsedMilliseconds}ms");
            }
            catch
            {
                state.Abandon();
                throw;
            }
        }

        [Fact]
        public void RoundTripViaStream()
        {
            var db = LoadFromDisk(out var contents);
            Assert.Equal(830, db.Orders.Count);

            using var ms = new MemoryStream();
            var writeState = ProtoWriter.State.Create(ms, RuntimeTypeModel.Default);
            try
            {
                Write(db, ref writeState);
            }
            finally
            {
                writeState.Dispose();
            }
            Assert.Equal(contents.Length, ms.Length);

            Assert.True(ms.TryGetBuffer(out var buffer));
            var span = new ReadOnlySpan<byte>(buffer.Array, buffer.Offset, buffer.Count);
            Assert.True(contents.SequenceEqual(span));
            Log?.WriteLine($"{span.Length} bytes verified");
        }

        [Fact]
        public void RoundTripViaBuffers()
        {
            var db = LoadFromDisk(out var contents);
            Assert.Equal(830, db.Orders.Count);

            using var bw = BufferWriter<byte>.Create();
            var writeState = ProtoWriter.State.Create(bw.Writer, RuntimeTypeModel.Default);
            try
            {
                Write(db, ref writeState);
            }
            finally
            {
                writeState.Dispose();
            }

            using var buffer = bw.Flush();
            var b = buffer.Value;
            int len = checked((int)b.Length);
            var arr = ArrayPool<byte>.Shared.Rent(len);
            try
            {
                var span = new Span<byte>(arr, 0, len);
                b.CopyTo(span);
                Assert.True(contents.SequenceEqual(span));
                Log?.WriteLine($"{span.Length} bytes verified");
            }
            finally
            {
                ArrayPool<byte>.Shared.Return(arr);
            }
        }
    }
}
#endif

<|start_filename|>src/Examples/SimpleStream/Collections.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using Xunit;
using ProtoBuf;

namespace Examples.SimpleStream
{
    
    public class Collections
    {

        [ProtoContract]
        public class FooContainer
        {
            [ProtoMember(1)]
            public Foo Foo { get; set; }
        }
        [ProtoContract]
        public class Foo
        {
            [ProtoMember(1)]
            public List<Bar> Bars { get; set; }
        }
        [ProtoContract]
        public class Bar
        {
            [ProtoMember(1)]
            public int Value { get; set; }
        }

        static Foo GetFullFoo()
        {
            Foo foo = new Foo();
            foo.Bars = new List<Bar>();
            for (int i = Int16.MinValue; i <= Int16.MaxValue; i++)
            {
                foo.Bars.Add(new Bar { Value = i });
            }
            return foo;
        }

        [Fact]
        public void RunWrappedCollectionTest()
        {
            FooContainer fooContainer = new FooContainer(), cloneContainer;
            Foo foo = GetFullFoo(), clone;
            fooContainer.Foo = foo;

            cloneContainer = Serializer.DeepClone(fooContainer);
            clone = cloneContainer.Foo;
            Assert.NotNull(cloneContainer); //, "Clone Container");
            Assert.True(CompareFoos(foo, clone));
        }

        [Fact]
        public void RunNakedCollectionTest()
        {
            Foo foo = GetFullFoo(), clone = Serializer.DeepClone(foo);
            Assert.True(CompareFoos(foo, clone));            
        }

        private static bool CompareFoos(Foo original, Foo clone) {
            Assert.NotNull(original); //, "Original");
            Assert.NotNull(clone); //, "Clone");
            Assert.Equal(original.Bars.Count, clone.Bars.Count); //, "Item count");
            if (original == null || clone == null ||
                original.Bars.Count != clone.Bars.Count) return false;
            int count = clone.Bars.Count;
            for (int i = 0; i < count; i++)
            {
                Assert.Equal(original.Bars[i].Value, clone.Bars[i].Value); //, "Value mismatch");
                if (original.Bars[i].Value != clone.Bars[i].Value) return false;
            }
            return true;
        }
    }
}
