Add tests
diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh index 66d87c0..35ce28c 100755 --- a/csharp/generate_protos.sh +++ b/csharp/generate_protos.sh
@@ -44,23 +44,26 @@ # Note that this deliberately does *not* include old_extensions1.proto # and old_extensions2.proto, which are generated with an older version # of protoc. -$PROTOC -Isrc -Icsharp/protos \ +$PROTOC -Isrc -Icsharp/protos -Icsharp/protos/extensions \ --csharp_out=csharp/src/Google.Protobuf.Test.TestProtos \ --descriptor_set_out=csharp/src/Google.Protobuf.Test/testprotos.pb \ --include_source_info \ --include_imports \ - csharp/protos/map_unittest_proto3.proto \ - csharp/protos/unittest_issues.proto \ - csharp/protos/unittest_custom_options_proto3.proto \ - csharp/protos/unittest_proto3.proto \ - csharp/protos/unittest_import_proto3.proto \ - csharp/protos/unittest_import_public_proto3.proto \ - csharp/protos/unittest.proto \ - csharp/protos/unittest_import.proto \ - csharp/protos/unittest_import_public.proto \ - src/google/protobuf/unittest_well_known_types.proto \ - src/google/protobuf/test_messages_proto3.proto \ - src/google/protobuf/test_messages_proto2.proto + map_unittest_proto3.proto \ + unittest_issues.proto \ + unittest_custom_options_proto3.proto \ + unittest_proto3.proto \ + unittest_import_proto3.proto \ + unittest_import_public_proto3.proto \ + unittest.proto \ + unittest_import.proto \ + unittest_import_public.proto \ + extensions_a.proto \ + extensions_b.proto \ + extensions_c.proto \ + google/protobuf/unittest_well_known_types.proto \ + google/protobuf/test_messages_proto3.proto \ + google/protobuf/test_messages_proto2.proto # AddressBook sample protos $PROTOC -Iexamples -Isrc --csharp_out=csharp/src/AddressBook \
diff --git a/csharp/protos/extensions/extensions_a.proto b/csharp/protos/extensions/extensions_a.proto new file mode 100644 index 0000000..e967ded --- /dev/null +++ b/csharp/protos/extensions/extensions_a.proto
@@ -0,0 +1,12 @@ +syntax = "proto3"; + +option csharp_namespace = "Google.Protobuf.TestProtos.Extensions"; + +// This file is used as part of a unit test for issue 6936 +// We don't need to use it, we just have to import it in both b and c + +import "google/protobuf/descriptor.proto"; + +extend google.protobuf.MessageOptions { + string opt = 50000; +} \ No newline at end of file
diff --git a/csharp/protos/extensions/extensions_b.proto b/csharp/protos/extensions/extensions_b.proto new file mode 100644 index 0000000..c19e988 --- /dev/null +++ b/csharp/protos/extensions/extensions_b.proto
@@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "extensions_a.proto"; + +option csharp_namespace = "Google.Protobuf.TestProtos.Extensions"; + +// This file is used as part of a unit test for issue 6936 +// We don't need to use it, we just have to import it in c + +message Foo { + option (opt) = "bar"; +} \ No newline at end of file
diff --git a/csharp/protos/extensions/extensions_c.proto b/csharp/protos/extensions/extensions_c.proto new file mode 100644 index 0000000..3a32da9 --- /dev/null +++ b/csharp/protos/extensions/extensions_c.proto
@@ -0,0 +1,14 @@ +syntax = "proto3"; + +import "extensions_a.proto"; +import "extensions_b.proto"; + +option csharp_namespace = "Google.Protobuf.TestProtos.Extensions"; + +// This file is used as part of a unit test for issue 6936 +// We don't need to use it, we just have to load it at runtime + +message Bar { + option (opt) = "foo"; + Foo foo = 1; +} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsA.cs b/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsA.cs new file mode 100644 index 0000000..f2f66ff --- /dev/null +++ b/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsA.cs
@@ -0,0 +1,46 @@ +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: extensions_a.proto +// </auto-generated> +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Google.Protobuf.TestProtos.Extensions { + + /// <summary>Holder for reflection information generated from extensions_a.proto</summary> + public static partial class ExtensionsAReflection { + + #region Descriptor + /// <summary>File descriptor for extensions_a.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static ExtensionsAReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChJleHRlbnNpb25zX2EucHJvdG8aIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlw", + "dG9yLnByb3RvOi4KA29wdBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0", + "aW9ucxjQhgMgASgJQiiqAiVHb29nbGUuUHJvdG9idWYuVGVzdFByb3Rvcy5F", + "eHRlbnNpb25zYgZwcm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(null, new pb::Extension[] { ExtensionsAExtensions.Opt }, null)); + } + #endregion + + } + /// <summary>Holder for extension identifiers generated from the top level of extensions_a.proto</summary> + public static partial class ExtensionsAExtensions { + public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, string> Opt = + new pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, string>(50000, pb::FieldCodec.ForString(400002, "")); + } + +} + +#endregion Designer generated code
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsB.cs b/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsB.cs new file mode 100644 index 0000000..a67688f --- /dev/null +++ b/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsB.cs
@@ -0,0 +1,145 @@ +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: extensions_b.proto +// </auto-generated> +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Google.Protobuf.TestProtos.Extensions { + + /// <summary>Holder for reflection information generated from extensions_b.proto</summary> + public static partial class ExtensionsBReflection { + + #region Descriptor + /// <summary>File descriptor for extensions_b.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static ExtensionsBReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChJleHRlbnNpb25zX2IucHJvdG8aEmV4dGVuc2lvbnNfYS5wcm90byIOCgNG", + "b286B4K1GANiYXJCKKoCJUdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zLkV4", + "dGVuc2lvbnNiBnByb3RvMw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.Extensions.ExtensionsAReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Extensions.Foo), global::Google.Protobuf.TestProtos.Extensions.Foo.Parser, null, null, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class Foo : pb::IMessage<Foo> { + private static readonly pb::MessageParser<Foo> _parser = new pb::MessageParser<Foo>(() => new Foo()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Foo> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Google.Protobuf.TestProtos.Extensions.ExtensionsBReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Foo() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Foo(Foo other) : this() { + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Foo Clone() { + return new Foo(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Foo); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Foo other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Foo other) { + if (other == null) { + return; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsC.cs b/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsC.cs new file mode 100644 index 0000000..d8387c1 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test.TestProtos/ExtensionsC.cs
@@ -0,0 +1,180 @@ +// <auto-generated> +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: extensions_c.proto +// </auto-generated> +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Google.Protobuf.TestProtos.Extensions { + + /// <summary>Holder for reflection information generated from extensions_c.proto</summary> + public static partial class ExtensionsCReflection { + + #region Descriptor + /// <summary>File descriptor for extensions_c.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static ExtensionsCReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChJleHRlbnNpb25zX2MucHJvdG8aEmV4dGVuc2lvbnNfYS5wcm90bxoSZXh0", + "ZW5zaW9uc19iLnByb3RvIiEKA0JhchIRCgNmb28YASABKAsyBC5Gb286B4K1", + "GANmb29CKKoCJUdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zLkV4dGVuc2lv", + "bnNiBnByb3RvMw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.Extensions.ExtensionsAReflection.Descriptor, global::Google.Protobuf.TestProtos.Extensions.ExtensionsBReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Extensions.Bar), global::Google.Protobuf.TestProtos.Extensions.Bar.Parser, new[]{ "Foo" }, null, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class Bar : pb::IMessage<Bar> { + private static readonly pb::MessageParser<Bar> _parser = new pb::MessageParser<Bar>(() => new Bar()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Bar> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Google.Protobuf.TestProtos.Extensions.ExtensionsCReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Bar() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Bar(Bar other) : this() { + foo_ = other.foo_ != null ? other.foo_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Bar Clone() { + return new Bar(this); + } + + /// <summary>Field number for the "foo" field.</summary> + public const int FooFieldNumber = 1; + private global::Google.Protobuf.TestProtos.Extensions.Foo foo_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.TestProtos.Extensions.Foo Foo { + get { return foo_; } + set { + foo_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Bar); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Bar other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!object.Equals(Foo, other.Foo)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (foo_ != null) hash ^= Foo.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (foo_ != null) { + output.WriteRawTag(10); + output.WriteMessage(Foo); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (foo_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Foo); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Bar other) { + if (other == null) { + return; + } + if (other.foo_ != null) { + if (foo_ == null) { + Foo = new global::Google.Protobuf.TestProtos.Extensions.Foo(); + } + Foo.MergeFrom(other.Foo); + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + if (foo_ == null) { + Foo = new global::Google.Protobuf.TestProtos.Extensions.Foo(); + } + input.ReadMessage(Foo); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs index d65a6f2..99f7e28 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs
@@ -42,6 +42,7 @@ using static UnitTest.Issues.TestProtos.UnittestCustomOptionsProto3Extensions; using static UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types; using Google.Protobuf.TestProtos; +using Google.Protobuf.TestProtos.Extensions; #pragma warning disable CS0618 @@ -193,6 +194,12 @@ Assert.NotNull(TestAllTypes.Descriptor.Oneofs[0].CustomOptions); } + [Test] + public void MultipleImportOfSameFileWithExtension() + { + var descriptor = ExtensionsCReflection.Descriptor; + } + private void AssertOption<T, D>(T expected, OptionFetcher<T> fetcher, Extension<D, T> extension, Func<Extension<D, T>, T> descriptorOptionFetcher) where D : IExtendableMessage<D> { T customOptionsValue;
diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index 818b227..b1c6650 100644 --- a/csharp/src/Google.Protobuf.Test/testprotos.pb +++ b/csharp/src/Google.Protobuf.Test/testprotos.pb Binary files differ