From cea3653a2ea4fa08ba8fa59b3f06cad27b5af074 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Wed, 20 Jan 2021 08:06:34 +0000 Subject: [PATCH] Include the size of values (and tags) for extensions, even if the value is the default Fixes #8218. --- .../Google.Protobuf.Test/ExtensionSetTest.cs | 17 ++++++++++++++++- csharp/src/Google.Protobuf/ExtensionValue.cs | 2 +- csharp/src/Google.Protobuf/FieldCodec.cs | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs index aceb4a68f7..951e856a59 100644 --- a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs +++ b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs @@ -116,7 +116,22 @@ namespace Google.Protobuf var other = message.Clone(); Assert.AreEqual(message, other); - Assert.AreEqual(message.CalculateSize(), message.CalculateSize()); + Assert.AreEqual(message.CalculateSize(), other.CalculateSize()); + } + + [Test] + public void TestDefaultValueRoundTrip() + { + var message = new TestAllExtensions(); + message.SetExtension(OptionalBoolExtension, false); + Assert.IsFalse(message.GetExtension(OptionalBoolExtension)); + Assert.IsTrue(message.HasExtension(OptionalBoolExtension)); + + var bytes = message.ToByteArray(); + var registry = new ExtensionRegistry { OptionalBoolExtension }; + var parsed = TestAllExtensions.Parser.WithExtensionRegistry(registry).ParseFrom(bytes); + Assert.IsFalse(parsed.GetExtension(OptionalBoolExtension)); + Assert.IsTrue(parsed.HasExtension(OptionalBoolExtension)); } } } diff --git a/csharp/src/Google.Protobuf/ExtensionValue.cs b/csharp/src/Google.Protobuf/ExtensionValue.cs index ada5d79c80..5257c4c955 100644 --- a/csharp/src/Google.Protobuf/ExtensionValue.cs +++ b/csharp/src/Google.Protobuf/ExtensionValue.cs @@ -59,7 +59,7 @@ namespace Google.Protobuf public int CalculateSize() { - return codec.CalculateSizeWithTag(field); + return codec.CalculateUnconditionalSizeWithTag(field); } public IExtensionValue Clone() diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs index 158739d50a..ee6bd6a0eb 100644 --- a/csharp/src/Google.Protobuf/FieldCodec.cs +++ b/csharp/src/Google.Protobuf/FieldCodec.cs @@ -876,6 +876,12 @@ namespace Google.Protobuf /// public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize; + /// + /// Calculates the size required to write the given value, with a tag, even + /// if the value is the default. + /// + internal int CalculateUnconditionalSizeWithTag(T value) => ValueSizeCalculator(value) + tagSize; + private bool IsDefault(T value) => EqualityComparer.Equals(value, DefaultValue); } }