Răsfoiți Sursa

Include the size of values (and tags) for extensions, even if the value is the default

Fixes #8218.
Jon Skeet 4 ani în urmă
părinte
comite
cea3653a2e

+ 16 - 1
csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs

@@ -116,7 +116,22 @@ namespace Google.Protobuf
             var other = message.Clone();
             var other = message.Clone();
 
 
             Assert.AreEqual(message, other);
             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));
         }
         }
     }
     }
 }
 }

+ 1 - 1
csharp/src/Google.Protobuf/ExtensionValue.cs

@@ -59,7 +59,7 @@ namespace Google.Protobuf
 
 
         public int CalculateSize()
         public int CalculateSize()
         {
         {
-            return codec.CalculateSizeWithTag(field);
+            return codec.CalculateUnconditionalSizeWithTag(field);
         }
         }
 
 
         public IExtensionValue Clone()
         public IExtensionValue Clone()

+ 6 - 0
csharp/src/Google.Protobuf/FieldCodec.cs

@@ -876,6 +876,12 @@ namespace Google.Protobuf
         /// </summary>
         /// </summary>
         public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize;
         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);
         private bool IsDefault(T value) => EqualityComparer.Equals(value, DefaultValue);
     }
     }
 }
 }