Include the size of values (and tags) for extensions, even if the value is the default Fixes #8218.
diff --git a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs index aceb4a6..951e856 100644 --- a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs +++ b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
@@ -116,7 +116,22 @@ 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 ada5d79..5257c4c 100644 --- a/csharp/src/Google.Protobuf/ExtensionValue.cs +++ b/csharp/src/Google.Protobuf/ExtensionValue.cs
@@ -59,7 +59,7 @@ 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 158739d..ee6bd6a 100644 --- a/csharp/src/Google.Protobuf/FieldCodec.cs +++ b/csharp/src/Google.Protobuf/FieldCodec.cs
@@ -876,6 +876,12 @@ /// </summary> public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize; + /// <summary> + /// Calculates the size required to write the given value, with a tag, even + /// if the value is the default. + /// </summary> + internal int CalculateUnconditionalSizeWithTag(T value) => ValueSizeCalculator(value) + tagSize; + private bool IsDefault(T value) => EqualityComparer.Equals(value, DefaultValue); } }