소스 검색

Added group roundtrip tests and fixed any issues discovered

Sydney Acksman 6 년 전
부모
커밋
cd65535423

+ 50 - 0
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs

@@ -348,6 +348,56 @@ namespace Google.Protobuf
             Assert.AreEqual(message, parsed);
             Assert.AreEqual(message, parsed);
         }
         }
 
 
+        [Test]
+        public void RoundTrip_Groups()
+        {
+            var message = new Proto2.TestAllTypes
+            {
+                OptionalGroup = new Proto2.TestAllTypes.Types.OptionalGroup
+                {
+                    A = 10
+                },
+                RepeatedGroup =
+                {
+                    new Proto2.TestAllTypes.Types.RepeatedGroup { A = 10 },
+                    new Proto2.TestAllTypes.Types.RepeatedGroup { A = 20 },
+                    new Proto2.TestAllTypes.Types.RepeatedGroup { A = 30 }
+                }
+            };
+
+            byte[] bytes = message.ToByteArray();
+            Proto2.TestAllTypes parsed = Proto2.TestAllTypes.Parser.ParseFrom(bytes);
+            Assert.AreEqual(message, parsed);
+        }
+
+        [Test]
+        public void RoundTrip_ExtensionGroups()
+        {
+            var message = new Proto2.TestAllExtensions();
+            message.SetExtension(Proto2.UnittestExtensions.OptionalGroupExtension, new Proto2.OptionalGroup_extension { A = 10 });
+            message.GetOrRegisterExtension(Proto2.UnittestExtensions.RepeatedGroupExtension).AddRange(new[]
+            {
+                new Proto2.RepeatedGroup_extension { A = 10 },
+                new Proto2.RepeatedGroup_extension { A = 20 },
+                new Proto2.RepeatedGroup_extension { A = 30 }
+            });
+
+            byte[] bytes = message.ToByteArray();
+            Proto2.TestAllExtensions extendable_parsed = Proto2.TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { Proto2.UnittestExtensions.OptionalGroupExtension, Proto2.UnittestExtensions.RepeatedGroupExtension }).ParseFrom(bytes);
+            Assert.AreEqual(message, extendable_parsed);
+        }
+
+        [Test]
+        public void RoundTrip_NestedExtensionGroup()
+        {
+            var message = new Proto2.TestGroupExtension();
+            message.SetExtension(Proto2.TestNestedExtension.Extensions.OptionalGroupExtension, new Proto2.TestNestedExtension.Types.OptionalGroup_extension { A = 10 });
+
+            byte[] bytes = message.ToByteArray();
+            Proto2.TestGroupExtension extendable_parsed = Proto2.TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { Proto2.TestNestedExtension.Extensions.OptionalGroupExtension }).ParseFrom(bytes);
+            Assert.AreEqual(message, extendable_parsed);
+        }
+
         // Note that not every map within map_unittest_proto3 is used. They all go through very
         // 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
         // similar code paths. The fact that all maps are present is validation that we have codecs
         // for every type.
         // for every type.

+ 2 - 0
csharp/src/Google.Protobuf.Test/SampleMessages.cs

@@ -123,6 +123,7 @@ namespace Google.Protobuf
                 OptionalString = "test",
                 OptionalString = "test",
                 OptionalUint32 = UInt32.MaxValue,
                 OptionalUint32 = UInt32.MaxValue,
                 OptionalUint64 = UInt64.MaxValue,
                 OptionalUint64 = UInt64.MaxValue,
+                OptionalGroup = new Proto2.TestAllTypes.Types.OptionalGroup { A = 10 },
                 RepeatedBool = { true, false },
                 RepeatedBool = { true, false },
                 RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) },
                 RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) },
                 RepeatedDouble = { -12.25, 23.5 },
                 RepeatedDouble = { -12.25, 23.5 },
@@ -144,6 +145,7 @@ namespace Google.Protobuf
                 RepeatedString = { "foo", "bar" },
                 RepeatedString = { "foo", "bar" },
                 RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
                 RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
                 RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
                 RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
+                RepeatedGroup = { new Proto2.TestAllTypes.Types.RepeatedGroup { A = 10 }, new Proto2.TestAllTypes.Types.RepeatedGroup { A = 20 } },
                 OneofString = "Oneof string"
                 OneofString = "Oneof string"
             };
             };
         }
         }

+ 6 - 0
csharp/src/Google.Protobuf.Test/TestProtos/Unittest.cs

@@ -5406,6 +5406,8 @@ namespace Google.Protobuf.TestProtos.Proto2 {
       uint tag;
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
         switch(tag) {
+          case 132:
+            return;
           default:
           default:
             _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
             break;
@@ -5550,6 +5552,8 @@ namespace Google.Protobuf.TestProtos.Proto2 {
       uint tag;
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
       while ((tag = input.ReadTag()) != 0) {
         switch(tag) {
         switch(tag) {
+          case 372:
+            return;
           default:
           default:
             _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
             break;
             break;
@@ -6279,6 +6283,8 @@ namespace Google.Protobuf.TestProtos.Proto2 {
           uint tag;
           uint tag;
           while ((tag = input.ReadTag()) != 0) {
           while ((tag = input.ReadTag()) != 0) {
             switch(tag) {
             switch(tag) {
+              case 132:
+                return;
               default:
               default:
                 _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                 break;
                 break;

+ 4 - 0
csharp/src/Google.Protobuf/Collections/RepeatedField.cs

@@ -148,6 +148,10 @@ namespace Google.Protobuf.Collections
             {
             {
                 var sizeCalculator = codec.ValueSizeCalculator;
                 var sizeCalculator = codec.ValueSizeCalculator;
                 int size = count * CodedOutputStream.ComputeRawVarint32Size(tag);
                 int size = count * CodedOutputStream.ComputeRawVarint32Size(tag);
+                if (codec.EndTag != 0)
+                {
+                    size += count * CodedOutputStream.ComputeRawVarint32Size(codec.EndTag);
+                }
                 for (int i = 0; i < count; i++)
                 for (int i = 0; i < count; i++)
                 {
                 {
                     size += sizeCalculator(array[i]);
                     size += sizeCalculator(array[i]);

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

@@ -731,6 +731,7 @@ namespace Google.Protobuf
             ValueSizeCalculator = sizeCalculator;
             ValueSizeCalculator = sizeCalculator;
             FixedSize = 0;
             FixedSize = 0;
             Tag = tag;
             Tag = tag;
+            EndTag = endTag;
             DefaultValue = defaultValue;
             DefaultValue = defaultValue;
             tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
             tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
             if (endTag != 0)
             if (endTag != 0)

+ 25 - 8
src/google/protobuf/compiler/csharp/csharp_helpers.cc

@@ -284,16 +284,33 @@ std::string GetEnumValueName(const std::string& enum_name, const std::string& en
 
 
 uint GetGroupEndTag(const Descriptor* descriptor) {
 uint GetGroupEndTag(const Descriptor* descriptor) {
   const Descriptor* containing_type = descriptor->containing_type();
   const Descriptor* containing_type = descriptor->containing_type();
-  if (containing_type == NULL) {
-    return 0;
-  }
-  const FieldDescriptor* field;
-  for (int i = 0; i < containing_type->field_count(); i++) {
-    field = containing_type->field(i);
-    if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
-      return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+  if (containing_type != NULL) {
+    const FieldDescriptor* field;
+    for (int i = 0; i < containing_type->field_count(); i++) {
+      field = containing_type->field(i);
+      if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
+        return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+      }
+    }
+    for (int i = 0; i < containing_type->extension_count(); i++) {
+      field = containing_type->extension(i);
+      if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
+        return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+      }
+    }
+  } else {
+    const FileDescriptor* containing_file = descriptor->file();
+    if (containing_file != NULL) {
+      const FieldDescriptor* field;
+      for (int i = 0; i < containing_file->extension_count(); i++) {
+        field = containing_file->extension(i);
+        if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
+          return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
+        }
+      }
     }
     }
   }
   }
+
   return 0;
   return 0;
 }
 }