#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#endregion

using System;
using System.IO;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Linq;
using Google.Protobuf.WellKnownTypes;
using Google.Protobuf.Collections;

namespace Google.Protobuf
{
    /// <summary>
    /// Tests around the generated TestAllTypes message.
    /// </summary>
    public partial class GeneratedMessageTest
    {
        [Test]
        public void EmptyMessageFieldDistinctFromMissingMessageField()
        {
            // This demonstrates what we're really interested in...
            var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
            var message2 = new TestAllTypes(); // SingleForeignMessage is null
            EqualityTester.AssertInequality(message1, message2);
        }

        [Test]
        public void DefaultValues()
        {
            // Single fields
            var message = new TestAllTypes();
            Assert.AreEqual(false, message.SingleBool);
            Assert.AreEqual(ByteString.Empty, message.SingleBytes);
            Assert.AreEqual(0.0, message.SingleDouble);
            Assert.AreEqual(0, message.SingleFixed32);
            Assert.AreEqual(0L, message.SingleFixed64);
            Assert.AreEqual(0.0f, message.SingleFloat);
            Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
            Assert.IsNull(message.SingleForeignMessage);
            Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
            Assert.IsNull(message.SingleImportMessage);
            Assert.AreEqual(0, message.SingleInt32);
            Assert.AreEqual(0L, message.SingleInt64);
            Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
            Assert.IsNull(message.SingleNestedMessage);
            Assert.IsNull(message.SinglePublicImportMessage);
            Assert.AreEqual(0, message.SingleSfixed32);
            Assert.AreEqual(0L, message.SingleSfixed64);
            Assert.AreEqual(0, message.SingleSint32);
            Assert.AreEqual(0L, message.SingleSint64);
            Assert.AreEqual("", message.SingleString);
            Assert.AreEqual(0U, message.SingleUint32);
            Assert.AreEqual(0UL, message.SingleUint64);

            // Repeated fields
            Assert.AreEqual(0, message.RepeatedBool.Count);
            Assert.AreEqual(0, message.RepeatedBytes.Count);
            Assert.AreEqual(0, message.RepeatedDouble.Count);
            Assert.AreEqual(0, message.RepeatedFixed32.Count);
            Assert.AreEqual(0, message.RepeatedFixed64.Count);
            Assert.AreEqual(0, message.RepeatedFloat.Count);
            Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
            Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
            Assert.AreEqual(0, message.RepeatedImportEnum.Count);
            Assert.AreEqual(0, message.RepeatedImportMessage.Count);
            Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
            Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
            Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
            Assert.AreEqual(0, message.RepeatedSfixed32.Count);
            Assert.AreEqual(0, message.RepeatedSfixed64.Count);
            Assert.AreEqual(0, message.RepeatedSint32.Count);
            Assert.AreEqual(0, message.RepeatedSint64.Count);
            Assert.AreEqual(0, message.RepeatedString.Count);
            Assert.AreEqual(0, message.RepeatedUint32.Count);
            Assert.AreEqual(0, message.RepeatedUint64.Count);

            // Oneof fields
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
            Assert.AreEqual(0, message.OneofUint32);
            Assert.AreEqual("", message.OneofString);
            Assert.AreEqual(ByteString.Empty, message.OneofBytes);
            Assert.IsNull(message.OneofNestedMessage);
        }

        [Test]
        public void NullStringAndBytesRejected()
        {
            var message = new TestAllTypes();
            Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
            Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
            Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
            Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
        }

        [Test]
        public void RoundTrip_Empty()
        {
            var message = new TestAllTypes();
            // Without setting any values, there's nothing to write.
            byte[] bytes = message.ToByteArray();
            Assert.AreEqual(0, bytes.Length);

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
        }

        [Test]
        public void RoundTrip_SingleValues()
        {
            var message = new TestAllTypes
            {
                SingleBool = true,
                SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
                SingleDouble = 23.5,
                SingleFixed32 = 23,
                SingleFixed64 = 1234567890123,
                SingleFloat = 12.25f,
                SingleForeignEnum = ForeignEnum.ForeignBar,
                SingleForeignMessage = new ForeignMessage { C = 10 },
                SingleImportEnum = ImportEnum.ImportBaz,
                SingleImportMessage = new ImportMessage { D = 20 },
                SingleInt32 = 100,
                SingleInt64 = 3210987654321,
                SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
                SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
                SinglePublicImportMessage = new PublicImportMessage { E = 54 },
                SingleSfixed32 = -123,
                SingleSfixed64 = -12345678901234,
                SingleSint32 = -456,
                SingleSint64 = -12345678901235,
                SingleString = "test",
                SingleUint32 = uint.MaxValue,
                SingleUint64 = ulong.MaxValue
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
        }

        [Test]
        public void RoundTrip_RepeatedValues()
        {
            var message = new TestAllTypes
            {
                RepeatedBool = { true, false },
                RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
                RepeatedDouble = { -12.25, 23.5 },
                RepeatedFixed32 = { uint.MaxValue, 23 },
                RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
                RepeatedFloat = { 100f, 12.25f },
                RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
                RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
                RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
                RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
                RepeatedInt32 = { 100, 200 },
                RepeatedInt64 = { 3210987654321, long.MaxValue },
                RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
                RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
                RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
                RepeatedSfixed32 = { -123, 123 },
                RepeatedSfixed64 = { -12345678901234, 12345678901234 },
                RepeatedSint32 = { -456, 100 },
                RepeatedSint64 = { -12345678901235, 123 },
                RepeatedString = { "foo", "bar" },
                RepeatedUint32 = { uint.MaxValue, uint.MinValue },
                RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
        }

        // Note that not every map within map_unittest_proto3 is used. They all go through very
        // similar code paths. The fact that all maps are present is validation that we have codecs
        // for every type.
        [Test]
        public void RoundTrip_Maps()
        {
            var message = new TestMap
            {
                MapBoolBool = {
                    { false, true },
                    { true, false }
                },
                MapInt32Bytes = {
                    { 5, ByteString.CopyFrom(6, 7, 8) },
                    { 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
                    { 10, ByteString.Empty }
                },
                MapInt32ForeignMessage = {
                    { 0, new ForeignMessage { C = 10 } },
                    { 5, new ForeignMessage() },
                },
                MapInt32Enum = {
                    { 1, MapEnum.Bar },
                    { 2000, MapEnum.Foo }
                }
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestMap.Parser, message);
        }

        [Test]
        public void MapWithEmptyEntry()
        {
            var message = new TestMap
            {
                MapInt32Bytes = { { 0, ByteString.Empty } }
            };

            byte[] bytes = message.ToByteArray();
            Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                bytes,
                parsed=>
                {
                    Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
                    Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
                });
        }

        [Test]
        public void MapWithOnlyValue()
        {
            // Hand-craft the stream to contain a single entry with just a value.
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);
            output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
            var nestedMessage = new ForeignMessage { C = 20 };
            // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
            output.WriteLength(2 + nestedMessage.CalculateSize());
            output.WriteTag(2, WireFormat.WireType.LengthDelimited);
            output.WriteMessage(nestedMessage);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
                });
        }

        [Test]
        public void MapWithOnlyKey_PrimitiveValue()
        {
            // Hand-craft the stream to contain a single entry with just a key.
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);
            output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
            int key = 10;
            output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
                });
        }

        [Test]
        public void MapWithOnlyKey_MessageValue()
        {
            // Hand-craft the stream to contain a single entry with just a key.
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);
            output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
            int key = 10;
            output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
                });
        }

        [Test]
        public void MapIgnoresExtraFieldsWithinEntryMessages()
        {
            // Hand-craft the stream to contain a single entry with three fields
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);

            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);

            var key = 10; // Field 1
            var value = 20; // Field 2
            var extra = 30; // Field 3

            // Each field can be represented in a single byte, with a single byte tag.
            // Total message size: 6 bytes.
            output.WriteLength(6);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value);
            output.WriteTag(3, WireFormat.WireType.Varint);
            output.WriteInt32(extra);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    Assert.AreEqual(value, parsed.MapInt32Int32[key]);
                });
        }

        [Test]
        public void MapFieldOrderIsIrrelevant()
        {
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);

            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);

            var key = 10;
            var value = 20;

            // Each field can be represented in a single byte, with a single byte tag.
            // Total message size: 4 bytes.
            output.WriteLength(4);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    Assert.AreEqual(value, parsed.MapInt32Int32[key]);
                });
        }

        [Test]
        public void MapNonContiguousEntries()
        {
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);

            // Message structure:
            // Entry for MapInt32Int32
            // Entry for MapStringString
            // Entry for MapInt32Int32

            // First entry
            var key1 = 10;
            var value1 = 20;
            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key1);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value1);

            // Second entry
            var key2 = "a";
            var value2 = "b";
            output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(6); // 3 bytes per entry: tag, size, character
            output.WriteTag(1, WireFormat.WireType.LengthDelimited);
            output.WriteString(key2);
            output.WriteTag(2, WireFormat.WireType.LengthDelimited);
            output.WriteString(value2);

            // Third entry
            var key3 = 15;
            var value3 = 25;
            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key3);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value3);

            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    var expected = new TestMap
                    {
                        MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
                        MapStringString = { { key2, value2 } }
                    };
                    Assert.AreEqual(expected, parsed);
                });
        }

        [Test]
        public void DuplicateKeys_LastEntryWins()
        {
            var memoryStream = new MemoryStream();
            var output = new CodedOutputStream(memoryStream);

            var key = 10;
            var value1 = 20;
            var value2 = 30;

            // First entry
            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value1);

            // Second entry - same key, different value
            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value2);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
                {
                    Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
                });
        }

        [Test]
        public void CloneSingleNonMessageValues()
        {
            var original = new TestAllTypes
            {
                SingleBool = true,
                SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
                SingleDouble = 23.5,
                SingleFixed32 = 23,
                SingleFixed64 = 1234567890123,
                SingleFloat = 12.25f,
                SingleInt32 = 100,
                SingleInt64 = 3210987654321,
                SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
                SingleSfixed32 = -123,
                SingleSfixed64 = -12345678901234,
                SingleSint32 = -456,
                SingleSint64 = -12345678901235,
                SingleString = "test",
                SingleUint32 = uint.MaxValue,
                SingleUint64 = ulong.MaxValue
            };
            var clone = original.Clone();
            Assert.AreNotSame(original, clone);
            Assert.AreEqual(original, clone);
            // Just as a single example
            clone.SingleInt32 = 150;
            Assert.AreNotEqual(original, clone);
        }

        [Test]
        public void CloneRepeatedNonMessageValues()
        {
            var original = new TestAllTypes
            {
                RepeatedBool = { true, false },
                RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
                RepeatedDouble = { -12.25, 23.5 },
                RepeatedFixed32 = { uint.MaxValue, 23 },
                RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
                RepeatedFloat = { 100f, 12.25f },
                RepeatedInt32 = { 100, 200 },
                RepeatedInt64 = { 3210987654321, long.MaxValue },
                RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
                RepeatedSfixed32 = { -123, 123 },
                RepeatedSfixed64 = { -12345678901234, 12345678901234 },
                RepeatedSint32 = { -456, 100 },
                RepeatedSint64 = { -12345678901235, 123 },
                RepeatedString = { "foo", "bar" },
                RepeatedUint32 = { uint.MaxValue, uint.MinValue },
                RepeatedUint64 = { ulong.MaxValue, uint.MinValue }
            };

            var clone = original.Clone();
            Assert.AreNotSame(original, clone);
            Assert.AreEqual(original, clone);
            // Just as a single example
            clone.RepeatedDouble.Add(25.5);
            Assert.AreNotEqual(original, clone);
        }

        [Test]
        public void CloneSingleMessageField()
        {
            var original = new TestAllTypes
            {
                SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
            };

            var clone = original.Clone();
            Assert.AreNotSame(original, clone);
            Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
            Assert.AreEqual(original, clone);

            clone.SingleNestedMessage.Bb = 30;
            Assert.AreNotEqual(original, clone);
        }

        [Test]
        public void CloneRepeatedMessageField()
        {
            var original = new TestAllTypes
            {
                RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
            };

            var clone = original.Clone();
            Assert.AreNotSame(original, clone);
            Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
            Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
            Assert.AreEqual(original, clone);

            clone.RepeatedNestedMessage[0].Bb = 30;
            Assert.AreNotEqual(original, clone);
        }

        [Test]
        public void CloneOneofField()
        {
            var original = new TestAllTypes
            {
                OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
            };

            var clone = original.Clone();
            Assert.AreNotSame(original, clone);
            Assert.AreEqual(original, clone);

            // We should have cloned the message
            original.OneofNestedMessage.Bb = 30;
            Assert.AreNotEqual(original, clone);
        }

        [Test]
        public void OneofProperties()
        {
            // Switch the oneof case between each of the different options, and check everything behaves
            // as expected in each case.
            var message = new TestAllTypes();
            Assert.AreEqual("", message.OneofString);
            Assert.AreEqual(0, message.OneofUint32);
            Assert.AreEqual(ByteString.Empty, message.OneofBytes);
            Assert.IsNull(message.OneofNestedMessage);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);

            message.OneofString = "sample";
            Assert.AreEqual("sample", message.OneofString);
            Assert.AreEqual(0, message.OneofUint32);
            Assert.AreEqual(ByteString.Empty, message.OneofBytes);
            Assert.IsNull(message.OneofNestedMessage);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase);

            var bytes = ByteString.CopyFrom(1, 2, 3);
            message.OneofBytes = bytes;
            Assert.AreEqual("", message.OneofString);
            Assert.AreEqual(0, message.OneofUint32);
            Assert.AreEqual(bytes, message.OneofBytes);
            Assert.IsNull(message.OneofNestedMessage);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofBytes, message.OneofFieldCase);

            message.OneofUint32 = 20;
            Assert.AreEqual("", message.OneofString);
            Assert.AreEqual(20, message.OneofUint32);
            Assert.AreEqual(ByteString.Empty, message.OneofBytes);
            Assert.IsNull(message.OneofNestedMessage);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message.OneofFieldCase);

            var nestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 25 };
            message.OneofNestedMessage = nestedMessage;
            Assert.AreEqual("", message.OneofString);
            Assert.AreEqual(0, message.OneofUint32);
            Assert.AreEqual(ByteString.Empty, message.OneofBytes);
            Assert.AreEqual(nestedMessage, message.OneofNestedMessage);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofNestedMessage, message.OneofFieldCase);

            message.ClearOneofField();
            Assert.AreEqual("", message.OneofString);
            Assert.AreEqual(0, message.OneofUint32);
            Assert.AreEqual(ByteString.Empty, message.OneofBytes);
            Assert.IsNull(message.OneofNestedMessage);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
        }

        [Test]
        public void Oneof_DefaultValuesNotEqual()
        {
            var message1 = new TestAllTypes { OneofString = "" };
            var message2 = new TestAllTypes { OneofUint32 = 0 };
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
            Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
            Assert.AreNotEqual(message1, message2);
        }

        [Test]
        public void OneofSerialization_NonDefaultValue()
        {
            var message = new TestAllTypes
            {
                OneofString = "this would take a bit of space",
                OneofUint32 = 10
            };
            var bytes = message.ToByteArray();
            Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage =>
            {
                Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase);
            });
        }

        [Test]
        public void OneofSerialization_DefaultValue()
        {
            var message = new TestAllTypes
            {
                OneofString = "this would take a bit of space",
                OneofUint32 = 0 // This is the default value for UInt32; normally wouldn't be serialized
            };
            var bytes = message.ToByteArray();
            Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage =>
            {
                Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase);
            });
        }

        [Test]
        public void MapStringString_DeterministicTrue_ThenBytesIdentical()
        {
            // Define three strings consisting of different versions of the letter I.
            // LATIN CAPITAL LETTER I (U+0049)
            string capitalLetterI = "I";
            // LATIN SMALL LETTER I (U+0069)
            string smallLetterI   = "i";
            // LATIN SMALL LETTER DOTLESS I (U+0131)
            string smallLetterDotlessI = "\u0131";
            var testMap1 = new TestMap();

            testMap1.MapStringString.Add(smallLetterDotlessI, "value_"+smallLetterDotlessI);
            testMap1.MapStringString.Add(smallLetterI, "value_"+smallLetterI);
            testMap1.MapStringString.Add(capitalLetterI, "content_"+capitalLetterI);
            var bytes1 = SerializeTestMap(testMap1, true);

            var testMap2 = new TestMap();
            testMap2.MapStringString.Add(capitalLetterI, "content_"+capitalLetterI);
            testMap2.MapStringString.Add(smallLetterI, "value_"+smallLetterI);
            testMap2.MapStringString.Add(smallLetterDotlessI, "value_"+smallLetterDotlessI);

            var bytes2 = SerializeTestMap(testMap2, true);
            var parsedBytes2 = TestMap.Parser.ParseFrom(bytes2);
            var parsedBytes1 = TestMap.Parser.ParseFrom(bytes1);
            Assert.IsTrue(bytes1.SequenceEqual(bytes2));
        }

        [Test]
        public void MapInt32Bytes_DeterministicTrue_ThenBytesIdentical()
        {
            var testMap1 = new TestMap();
            testMap1.MapInt32Bytes.Add(1, ByteString.CopyFromUtf8("test1"));
            testMap1.MapInt32Bytes.Add(2, ByteString.CopyFromUtf8("test2"));
            var bytes1 = SerializeTestMap(testMap1, true);

            var testMap2 = new TestMap();
            testMap2.MapInt32Bytes.Add(2, ByteString.CopyFromUtf8("test2"));
            testMap2.MapInt32Bytes.Add(1, ByteString.CopyFromUtf8("test1"));
            var bytes2 = SerializeTestMap(testMap2, true);

            Assert.IsTrue(bytes1.SequenceEqual(bytes2));
        }

        [Test]
        public void MapInt32Bytes_DeterministicFalse_ThenBytesDifferent()
        {
            var testMap1 = new TestMap();
            testMap1.MapInt32Bytes.Add(1, ByteString.CopyFromUtf8("test1"));
            testMap1.MapInt32Bytes.Add(2, ByteString.CopyFromUtf8("test2"));
            var bytes1 = SerializeTestMap(testMap1, false);

            var testMap2 = new TestMap();
            testMap2.MapInt32Bytes.Add(2, ByteString.CopyFromUtf8("test2"));
            testMap2.MapInt32Bytes.Add(1, ByteString.CopyFromUtf8("test1"));
            var bytes2 = SerializeTestMap(testMap2, false);

            Assert.IsFalse(bytes1.SequenceEqual(bytes2));
        }

        private byte[] SerializeTestMap(TestMap testMap, bool deterministic)
        {
            using var memoryStream = new MemoryStream();
            var codedOutputStream = new CodedOutputStream(memoryStream);
            codedOutputStream.Deterministic = deterministic;

            testMap.WriteTo(codedOutputStream);
            codedOutputStream.Flush();

            memoryStream.Seek(0, SeekOrigin.Begin);
            return memoryStream.ToArray();
        }

        [Test]
        public void DiscardUnknownFields_RealDataStillRead()
        {
            var message = SampleMessages.CreateFullTestAllTypes();
            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);
            var unusedFieldNumber = 23456;
            Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
            output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteString("ignore me");
            message.WriteTo(output);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestAllTypes.Parser,
                stream.ToArray(),
                parsed =>
                {
                    // TODO: Add test back when DiscardUnknownFields API is supported.
                    // Assert.AreEqual(message, parsed);
                });
        }

        [Test]
        public void DiscardUnknownFields_AllTypes()
        {
            // Simple way of ensuring we can skip all kinds of fields.
            var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
            var empty = Empty.Parser.ParseFrom(data);

            MessageParsingHelpers.AssertReadingMessage(
                Empty.Parser,
                data,
                parsed =>
                {
                    // TODO: Add test back when DiscardUnknownFields API is supported.
                    // Assert.AreNotEqual(new Empty(), empty);
                });
        }

        // This was originally seen as a conformance test failure.
        [Test]
        public void TruncatedMessageFieldThrows()
        {
            // 130, 3 is the message tag
            // 1 is the data length - but there's no data.
            var data = new byte[] { 130, 3, 1 };
            MessageParsingHelpers.AssertReadingMessageThrows<TestAllTypes, InvalidProtocolBufferException>(TestAllTypes.Parser, data);
        }

        /// <summary>
        /// Demonstrates current behaviour with an extraneous end group tag - see issue 688
        /// for details; we may want to change this.
        /// </summary>
        [Test]
        public void ExtraEndGroupThrows()
        {
            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);

            output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
            output.WriteFixed32(123);
            output.WriteTag(100, WireFormat.WireType.EndGroup);

            output.Flush();

            stream.Position = 0;
            MessageParsingHelpers.AssertReadingMessageThrows<TestAllTypes, InvalidProtocolBufferException>(TestAllTypes.Parser, stream.ToArray());
        }

        [Test]
        public void CustomDiagnosticMessage_DirectToStringCall()
        {
            var message = new ForeignMessage { C = 31 };
            Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
            Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
        }

        [Test]
        public void CustomDiagnosticMessage_Nested()
        {
            var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
            Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
            Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
        }

        [Test]
        public void CustomDiagnosticMessage_DirectToTextWriterCall()
        {
            var message = new ForeignMessage { C = 31 };
            var writer = new StringWriter();
            JsonFormatter.Default.Format(message, writer);
            Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
        }

        [Test]
        public void NaNComparisons()
        {
            var message1 = new TestAllTypes { SingleDouble = SampleNaNs.Regular };
            var message2 = new TestAllTypes { SingleDouble = SampleNaNs.PayloadFlipped };
            var message3 = new TestAllTypes { SingleDouble = SampleNaNs.Regular };

            EqualityTester.AssertInequality(message1, message2);
            EqualityTester.AssertEquality(message1, message3);
        }

        [Test]
        [TestCase(false)]
        [TestCase(true)]
        public void MapFieldMerging(bool direct)
        {
            var message1 = new TestMap
            {
                MapStringString =
                {
                    { "x1", "y1" },
                    { "common", "message1" }
                }
            };
            var message2 = new TestMap
            {
                MapStringString =
                {
                    { "x2", "y2" },
                    { "common", "message2" }
                }
            };
            if (direct)
            {
                message1.MergeFrom(message2);
            }
            else
            {
                message1.MergeFrom(message2.ToByteArray());
            }

            var expected = new MapField<string, string>
            {
                { "x1", "y1" },
                { "x2", "y2" },
                { "common", "message2" }
            };
            Assert.AreEqual(expected, message1.MapStringString);
        }
    }
}