diff --git a/Makefile.am b/Makefile.am index 903eca7c016..f87e74d0ac5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -148,12 +148,17 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs \ csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \ + csharp/src/Google.Protobuf/Extension.cs \ + csharp/src/Google.Protobuf/ExtensionRegistry.cs \ + csharp/src/Google.Protobuf/ExtensionSet.cs \ + csharp/src/Google.Protobuf/ExtensionValue.cs \ csharp/src/Google.Protobuf/FieldCodec.cs \ csharp/src/Google.Protobuf/FieldMaskTree.cs \ csharp/src/Google.Protobuf/FrameworkPortability.cs \ csharp/src/Google.Protobuf/Google.Protobuf.csproj \ csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs \ csharp/src/Google.Protobuf/IDeepCloneable.cs \ + csharp/src/Google.Protobuf/IExtendableMessage.cs \ csharp/src/Google.Protobuf/IMessage.cs \ csharp/src/Google.Protobuf/InvalidJsonException.cs \ csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs \ @@ -164,6 +169,7 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/LimitedInputStream.cs \ csharp/src/Google.Protobuf/MessageExtensions.cs \ csharp/src/Google.Protobuf/MessageParser.cs \ + csharp/src/Google.Protobuf/ObjectIntPair.cs \ csharp/src/Google.Protobuf/ProtoPreconditions.cs \ csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs \ csharp/src/Google.Protobuf/Reflection/CustomOptions.cs \ @@ -175,6 +181,8 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/Reflection/DescriptorValidationException.cs \ csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs \ + csharp/src/Google.Protobuf/Reflection/ExtensionAccessor.cs \ + csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs \ csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs \ csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs \ csharp/src/Google.Protobuf/Reflection/FieldType.cs \ diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index d3e1ea95344..cbd97726962 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -37,9 +37,9 @@ public static partial class AddressbookReflection { "ZHJlc3NCb29rYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), global::Google.Protobuf.Examples.AddressBook.Person.Parser, new[]{ "Name", "Id", "Email", "Phones", "LastUpdated" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser, new[]{ "Number", "Type" }, null, null, null)}), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.AddressBook), global::Google.Protobuf.Examples.AddressBook.AddressBook.Parser, new[]{ "People" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), global::Google.Protobuf.Examples.AddressBook.Person.Parser, new[]{ "Name", "Id", "Email", "Phones", "LastUpdated" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser, new[]{ "Number", "Type" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.AddressBook), global::Google.Protobuf.Examples.AddressBook.AddressBook.Parser, new[]{ "People" }, null, null, null, null) })); } #endregion @@ -347,7 +347,7 @@ public sealed partial class PhoneNumber : pb::IMessage { /// Field number for the "type" field. public const int TypeFieldNumber = 2; - private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = 0; + private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType Type { get { return type_; } @@ -378,7 +378,7 @@ public sealed partial class PhoneNumber : pb::IMessage { public override int GetHashCode() { int hash = 1; if (Number.Length != 0) hash ^= Number.GetHashCode(); - if (Type != 0) hash ^= Type.GetHashCode(); + if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile) hash ^= Type.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -396,7 +396,7 @@ public sealed partial class PhoneNumber : pb::IMessage { output.WriteRawTag(10); output.WriteString(Number); } - if (Type != 0) { + if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile) { output.WriteRawTag(16); output.WriteEnum((int) Type); } @@ -411,7 +411,7 @@ public sealed partial class PhoneNumber : pb::IMessage { if (Number.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Number); } - if (Type != 0) { + if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type); } if (_unknownFields != null) { @@ -428,7 +428,7 @@ public sealed partial class PhoneNumber : pb::IMessage { if (other.Number.Length != 0) { Number = other.Number; } - if (other.Type != 0) { + if (other.Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile) { Type = other.Type; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); diff --git a/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs index c0c6d666d90..9e8c330a2b6 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs @@ -55,9 +55,9 @@ public static partial class BenchmarkMessage1Proto3Reflection { "YmVuY2htYXJrc0gB+AEBYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.Proto3.GoogleMessage1), global::Benchmarks.Proto3.GoogleMessage1.Parser, new[]{ "Field1", "Field9", "Field18", "Field80", "Field81", "Field2", "Field3", "Field280", "Field6", "Field22", "Field4", "Field5", "Field59", "Field7", "Field16", "Field130", "Field12", "Field17", "Field13", "Field14", "Field104", "Field100", "Field101", "Field102", "Field103", "Field29", "Field30", "Field60", "Field271", "Field272", "Field150", "Field23", "Field24", "Field25", "Field15", "Field78", "Field67", "Field68", "Field128", "Field129", "Field131" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.Proto3.GoogleMessage1SubMessage), global::Benchmarks.Proto3.GoogleMessage1SubMessage.Parser, new[]{ "Field1", "Field2", "Field3", "Field15", "Field12", "Field13", "Field14", "Field16", "Field19", "Field20", "Field28", "Field21", "Field22", "Field23", "Field206", "Field203", "Field204", "Field205", "Field207", "Field300" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.Proto3.GoogleMessage1), global::Benchmarks.Proto3.GoogleMessage1.Parser, new[]{ "Field1", "Field9", "Field18", "Field80", "Field81", "Field2", "Field3", "Field280", "Field6", "Field22", "Field4", "Field5", "Field59", "Field7", "Field16", "Field130", "Field12", "Field17", "Field13", "Field14", "Field104", "Field100", "Field101", "Field102", "Field103", "Field29", "Field30", "Field60", "Field271", "Field272", "Field150", "Field23", "Field24", "Field25", "Field15", "Field78", "Field67", "Field68", "Field128", "Field129", "Field131" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.Proto3.GoogleMessage1SubMessage), global::Benchmarks.Proto3.GoogleMessage1SubMessage.Parser, new[]{ "Field1", "Field2", "Field3", "Field15", "Field12", "Field13", "Field14", "Field16", "Field19", "Field20", "Field28", "Field21", "Field22", "Field23", "Field206", "Field203", "Field204", "Field205", "Field207", "Field300" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs b/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs index d2af7eefa6b..01dfcd72dc6 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs @@ -30,8 +30,8 @@ public static partial class BenchmarksReflection { "a3NiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.BenchmarkDataset), global::Benchmarks.BenchmarkDataset.Parser, new[]{ "Name", "MessageName", "Payload" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.BenchmarkDataset), global::Benchmarks.BenchmarkDataset.Parser, new[]{ "Name", "MessageName", "Payload" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs index 589ea7606e3..65ba9b1265a 100644 --- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs +++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs @@ -48,11 +48,11 @@ public static partial class ConformanceReflection { "Z2xlLnByb3RvYnVmLmNvbmZvcm1hbmNlYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.TestCategory), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.FailureSet), global::Conformance.FailureSet.Parser, new[]{ "Failure" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "JspbPayload", "TextPayload", "RequestedOutputFormat", "MessageType", "TestCategory", "JspbEncodingOptions", "PrintUnknownFields" }, new[]{ "Payload" }, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped", "JspbPayload", "TextPayload" }, new[]{ "Result" }, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.JspbEncodingConfig), global::Conformance.JspbEncodingConfig.Parser, new[]{ "UseJspbArrayAnyFormat" }, null, null, null) + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.TestCategory), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.FailureSet), global::Conformance.FailureSet.Parser, new[]{ "Failure" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "JspbPayload", "TextPayload", "RequestedOutputFormat", "MessageType", "TestCategory", "JspbEncodingOptions", "PrintUnknownFields" }, new[]{ "Payload" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped", "JspbPayload", "TextPayload" }, new[]{ "Result" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.JspbEncodingConfig), global::Conformance.JspbEncodingConfig.Parser, new[]{ "UseJspbArrayAnyFormat" }, null, null, null, null) })); } #endregion @@ -337,7 +337,7 @@ public sealed partial class ConformanceRequest : pb::IMessageField number for the "requested_output_format" field. public const int RequestedOutputFormatFieldNumber = 3; - private global::Conformance.WireFormat requestedOutputFormat_ = 0; + private global::Conformance.WireFormat requestedOutputFormat_ = global::Conformance.WireFormat.Unspecified; /// /// Which format should the testee serialize its message to? /// @@ -367,7 +367,7 @@ public sealed partial class ConformanceRequest : pb::IMessageField number for the "test_category" field. public const int TestCategoryFieldNumber = 5; - private global::Conformance.TestCategory testCategory_ = 0; + private global::Conformance.TestCategory testCategory_ = global::Conformance.TestCategory.UnspecifiedTest; /// /// Each test is given a specific test category. Some category may need /// spedific support in testee programs. Refer to the defintion of TestCategory @@ -464,9 +464,9 @@ public enum PayloadOneofCase { if (payloadCase_ == PayloadOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode(); if (payloadCase_ == PayloadOneofCase.JspbPayload) hash ^= JspbPayload.GetHashCode(); if (payloadCase_ == PayloadOneofCase.TextPayload) hash ^= TextPayload.GetHashCode(); - if (RequestedOutputFormat != 0) hash ^= RequestedOutputFormat.GetHashCode(); + if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) hash ^= RequestedOutputFormat.GetHashCode(); if (MessageType.Length != 0) hash ^= MessageType.GetHashCode(); - if (TestCategory != 0) hash ^= TestCategory.GetHashCode(); + if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) hash ^= TestCategory.GetHashCode(); if (jspbEncodingOptions_ != null) hash ^= JspbEncodingOptions.GetHashCode(); if (PrintUnknownFields != false) hash ^= PrintUnknownFields.GetHashCode(); hash ^= (int) payloadCase_; @@ -491,7 +491,7 @@ public enum PayloadOneofCase { output.WriteRawTag(18); output.WriteString(JsonPayload); } - if (RequestedOutputFormat != 0) { + if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) { output.WriteRawTag(24); output.WriteEnum((int) RequestedOutputFormat); } @@ -499,7 +499,7 @@ public enum PayloadOneofCase { output.WriteRawTag(34); output.WriteString(MessageType); } - if (TestCategory != 0) { + if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) { output.WriteRawTag(40); output.WriteEnum((int) TestCategory); } @@ -539,13 +539,13 @@ public enum PayloadOneofCase { if (payloadCase_ == PayloadOneofCase.TextPayload) { size += 1 + pb::CodedOutputStream.ComputeStringSize(TextPayload); } - if (RequestedOutputFormat != 0) { + if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RequestedOutputFormat); } if (MessageType.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageType); } - if (TestCategory != 0) { + if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) TestCategory); } if (jspbEncodingOptions_ != null) { @@ -565,13 +565,13 @@ public enum PayloadOneofCase { if (other == null) { return; } - if (other.RequestedOutputFormat != 0) { + if (other.RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) { RequestedOutputFormat = other.RequestedOutputFormat; } if (other.MessageType.Length != 0) { MessageType = other.MessageType; } - if (other.TestCategory != 0) { + if (other.TestCategory != global::Conformance.TestCategory.UnspecifiedTest) { TestCategory = other.TestCategory; } if (other.jspbEncodingOptions_ != null) { diff --git a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs index 68b4d6af7cf..ff4e9a7ffd0 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs @@ -99,66 +99,6 @@ public class CustomOptionsTest { delegate bool OptionFetcher(int field, out T value); - [Test] - public void EmptyOptionsIsShared() - { - var structOptions = Struct.Descriptor.CustomOptions; - var timestampOptions = Struct.Descriptor.CustomOptions; - Assert.AreSame(structOptions, timestampOptions); - } - - [Test] - public void SimpleIntegerTest() - { - var stream = new MemoryStream(); - var output = new CodedOutputStream(stream); - output.WriteTag(MakeTag(1, WireType.Varint)); - output.WriteInt32(1234567); - output.Flush(); - stream.Position = 0; - var input = new CodedInputStream(stream); - input.ReadTag(); - - var options = CustomOptions.Empty; - options = options.ReadOrSkipUnknownField(input); - - int intValue; - Assert.True(options.TryGetInt32(1, out intValue)); - Assert.AreEqual(1234567, intValue); - - string stringValue; - // No ByteString stored values - Assert.False(options.TryGetString(1, out stringValue)); - // Nothing stored for field 2 - Assert.False(options.TryGetInt32(2, out intValue)); - } - - [Test] - public void SimpleStringTest() - { - var stream = new MemoryStream(); - var output = new CodedOutputStream(stream); - output.WriteTag(MakeTag(1, WireType.LengthDelimited)); - output.WriteString("value"); - output.Flush(); - stream.Position = 0; - var input = new CodedInputStream(stream); - input.ReadTag(); - - var options = CustomOptions.Empty; - options = options.ReadOrSkipUnknownField(input); - - string stringValue; - Assert.True(options.TryGetString(1, out stringValue)); - Assert.AreEqual("value", stringValue); - - int intValue; - // No numeric stored values - Assert.False(options.TryGetInt32(1, out intValue)); - // Nothing stored for field 2 - Assert.False(options.TryGetString(2, out stringValue)); - } - [Test] public void ScalarOptions() { @@ -168,7 +108,7 @@ public void ScalarOptions() AssertOption(1.234567890123456789d, options.TryGetDouble, DoubleOpt); AssertOption("Hello, \"World\"", options.TryGetString, StringOpt); AssertOption(ByteString.CopyFromUtf8("Hello\0World"), options.TryGetBytes, BytesOpt); - AssertOption((int) TestEnumType.TestOptionEnumType2, options.TryGetInt32, EnumOpt); + AssertOption((int)TestEnumType.TestOptionEnumType2, options.TryGetInt32, EnumOpt); } [Test] @@ -177,11 +117,12 @@ public void MessageOptions() var options = VariousComplexOptions.Descriptor.CustomOptions; AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1); AssertOption(new ComplexOptionType2 - { - Baz = 987, Bar = new ComplexOptionType1 { Foo = 743 }, - Fred = new ComplexOptionType4 { Waldo = 321 }, - Barney = { new ComplexOptionType4 { Waldo = 101 }, new ComplexOptionType4 { Waldo = 212 } } - }, + { + Baz = 987, + Bar = new ComplexOptionType1 { Foo = 743 }, + Fred = new ComplexOptionType4 { Waldo = 321 }, + Barney = { new ComplexOptionType4 { Waldo = 101 }, new ComplexOptionType4 { Waldo = 212 } } + }, options.TryGetMessage, ComplexOpt2); AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3); } @@ -195,7 +136,7 @@ public void OptionLocations() var messageOptions = TestMessageWithCustomOptions.Descriptor.CustomOptions; AssertOption(-56, messageOptions.TryGetInt32, MessageOpt1); - var fieldOptions = TestMessageWithCustomOptions.Descriptor.Fields["field1"] .CustomOptions; + var fieldOptions = TestMessageWithCustomOptions.Descriptor.Fields["field1"].CustomOptions; AssertOption(8765432109UL, fieldOptions.TryGetFixed64, FieldOpt1); var oneofOptions = TestMessageWithCustomOptions.Descriptor.Oneofs[0].CustomOptions; @@ -213,7 +154,7 @@ public void OptionLocations() AssertOption(-9876543210, serviceOptions.TryGetSInt64, ServiceOpt1); var methodOptions = service.Methods[0].CustomOptions; - AssertOption((int) UnitTest.Issues.TestProtos.MethodOpt1.Val2, methodOptions.TryGetInt32, CustomOptionNumber.MethodOpt1); + AssertOption((int)UnitTest.Issues.TestProtos.MethodOpt1.Val2, methodOptions.TryGetInt32, CustomOptionNumber.MethodOpt1); } [Test] @@ -264,7 +205,7 @@ public void AggregateOptions() private void AssertOption(T expected, OptionFetcher fetcher, CustomOptionNumber field) { T actual; - Assert.IsTrue(fetcher((int) field, out actual)); + Assert.IsTrue(fetcher((int)field, out actual)); Assert.AreEqual(expected, actual); } } diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs index 6d3cd026d11..197b197d0ea 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs @@ -150,14 +150,14 @@ public static partial class MapUnittestProto3Reflection { "WhACQh2qAhpHb29nbGUuUHJvdG9idWYuVGVzdFByb3Rvc2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), global::Google.Protobuf.TestProtos.TestMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMapSubmessage), global::Google.Protobuf.TestProtos.TestMapSubmessage.Parser, new[]{ "TestMap" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMessageMap), global::Google.Protobuf.TestProtos.TestMessageMap.Parser, new[]{ "MapInt32Message" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestSameTypeMap), global::Google.Protobuf.TestProtos.TestSameTypeMap.Parser, new[]{ "Map1", "Map2" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestArenaMap), global::Google.Protobuf.TestProtos.TestArenaMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType), global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser, new[]{ "Type" }, null, new[]{ typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Types.Type) }, new pbr::GeneratedClrTypeInfo[] { null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry), global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry.Parser, new[]{ "Entry" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }) + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), global::Google.Protobuf.TestProtos.TestMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMapSubmessage), global::Google.Protobuf.TestProtos.TestMapSubmessage.Parser, new[]{ "TestMap" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMessageMap), global::Google.Protobuf.TestProtos.TestMessageMap.Parser, new[]{ "MapInt32Message" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestSameTypeMap), global::Google.Protobuf.TestProtos.TestSameTypeMap.Parser, new[]{ "Map1", "Map2" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, }), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestArenaMap), global::Google.Protobuf.TestProtos.TestArenaMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType), global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser, new[]{ "Type" }, null, new[]{ typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Types.Type) }, null, new pbr::GeneratedClrTypeInfo[] { null, }), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry), global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry.Parser, new[]{ "Entry" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }) })); } #endregion @@ -229,7 +229,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int32_int32" field. public const int MapInt32Int32FieldNumber = 1; private static readonly pbc::MapField.Codec _map_mapInt32Int32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForInt32(16, 0), 10); private readonly pbc::MapField mapInt32Int32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Int32 { @@ -239,7 +239,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int64_int64" field. public const int MapInt64Int64FieldNumber = 2; private static readonly pbc::MapField.Codec _map_mapInt64Int64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt64(8), pb::FieldCodec.ForInt64(16), 18); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt64(8, 0L), pb::FieldCodec.ForInt64(16, 0L), 18); private readonly pbc::MapField mapInt64Int64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt64Int64 { @@ -249,7 +249,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_uint32_uint32" field. public const int MapUint32Uint32FieldNumber = 3; private static readonly pbc::MapField.Codec _map_mapUint32Uint32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForUInt32(8), pb::FieldCodec.ForUInt32(16), 26); + = new pbc::MapField.Codec(pb::FieldCodec.ForUInt32(8, 0), pb::FieldCodec.ForUInt32(16, 0), 26); private readonly pbc::MapField mapUint32Uint32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapUint32Uint32 { @@ -259,7 +259,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_uint64_uint64" field. public const int MapUint64Uint64FieldNumber = 4; private static readonly pbc::MapField.Codec _map_mapUint64Uint64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForUInt64(8), pb::FieldCodec.ForUInt64(16), 34); + = new pbc::MapField.Codec(pb::FieldCodec.ForUInt64(8, 0UL), pb::FieldCodec.ForUInt64(16, 0UL), 34); private readonly pbc::MapField mapUint64Uint64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapUint64Uint64 { @@ -269,7 +269,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_sint32_sint32" field. public const int MapSint32Sint32FieldNumber = 5; private static readonly pbc::MapField.Codec _map_mapSint32Sint32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSInt32(8), pb::FieldCodec.ForSInt32(16), 42); + = new pbc::MapField.Codec(pb::FieldCodec.ForSInt32(8, 0), pb::FieldCodec.ForSInt32(16, 0), 42); private readonly pbc::MapField mapSint32Sint32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSint32Sint32 { @@ -279,7 +279,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_sint64_sint64" field. public const int MapSint64Sint64FieldNumber = 6; private static readonly pbc::MapField.Codec _map_mapSint64Sint64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSInt64(8), pb::FieldCodec.ForSInt64(16), 50); + = new pbc::MapField.Codec(pb::FieldCodec.ForSInt64(8, 0L), pb::FieldCodec.ForSInt64(16, 0L), 50); private readonly pbc::MapField mapSint64Sint64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSint64Sint64 { @@ -289,7 +289,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_fixed32_fixed32" field. public const int MapFixed32Fixed32FieldNumber = 7; private static readonly pbc::MapField.Codec _map_mapFixed32Fixed32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForFixed32(13), pb::FieldCodec.ForFixed32(21), 58); + = new pbc::MapField.Codec(pb::FieldCodec.ForFixed32(13, 0), pb::FieldCodec.ForFixed32(21, 0), 58); private readonly pbc::MapField mapFixed32Fixed32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapFixed32Fixed32 { @@ -299,7 +299,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_fixed64_fixed64" field. public const int MapFixed64Fixed64FieldNumber = 8; private static readonly pbc::MapField.Codec _map_mapFixed64Fixed64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForFixed64(9), pb::FieldCodec.ForFixed64(17), 66); + = new pbc::MapField.Codec(pb::FieldCodec.ForFixed64(9, 0UL), pb::FieldCodec.ForFixed64(17, 0UL), 66); private readonly pbc::MapField mapFixed64Fixed64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapFixed64Fixed64 { @@ -309,7 +309,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_sfixed32_sfixed32" field. public const int MapSfixed32Sfixed32FieldNumber = 9; private static readonly pbc::MapField.Codec _map_mapSfixed32Sfixed32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed32(13), pb::FieldCodec.ForSFixed32(21), 74); + = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed32(13, 0), pb::FieldCodec.ForSFixed32(21, 0), 74); private readonly pbc::MapField mapSfixed32Sfixed32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSfixed32Sfixed32 { @@ -319,7 +319,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_sfixed64_sfixed64" field. public const int MapSfixed64Sfixed64FieldNumber = 10; private static readonly pbc::MapField.Codec _map_mapSfixed64Sfixed64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed64(9), pb::FieldCodec.ForSFixed64(17), 82); + = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed64(9, 0L), pb::FieldCodec.ForSFixed64(17, 0L), 82); private readonly pbc::MapField mapSfixed64Sfixed64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSfixed64Sfixed64 { @@ -329,7 +329,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int32_float" field. public const int MapInt32FloatFieldNumber = 11; private static readonly pbc::MapField.Codec _map_mapInt32Float_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForFloat(21), 90); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForFloat(21, 0F), 90); private readonly pbc::MapField mapInt32Float_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Float { @@ -339,7 +339,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int32_double" field. public const int MapInt32DoubleFieldNumber = 12; private static readonly pbc::MapField.Codec _map_mapInt32Double_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForDouble(17), 98); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForDouble(17, 0D), 98); private readonly pbc::MapField mapInt32Double_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Double { @@ -349,7 +349,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_bool_bool" field. public const int MapBoolBoolFieldNumber = 13; private static readonly pbc::MapField.Codec _map_mapBoolBool_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForBool(8), pb::FieldCodec.ForBool(16), 106); + = new pbc::MapField.Codec(pb::FieldCodec.ForBool(8, false), pb::FieldCodec.ForBool(16, false), 106); private readonly pbc::MapField mapBoolBool_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapBoolBool { @@ -359,7 +359,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_string_string" field. public const int MapStringStringFieldNumber = 14; private static readonly pbc::MapField.Codec _map_mapStringString_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForString(18), 114); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForString(18, ""), 114); private readonly pbc::MapField mapStringString_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringString { @@ -369,7 +369,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int32_bytes" field. public const int MapInt32BytesFieldNumber = 15; private static readonly pbc::MapField.Codec _map_mapInt32Bytes_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForBytes(18), 122); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForBytes(18, pb::ByteString.Empty), 122); private readonly pbc::MapField mapInt32Bytes_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Bytes { @@ -379,7 +379,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int32_enum" field. public const int MapInt32EnumFieldNumber = 16; private static readonly pbc::MapField.Codec _map_mapInt32Enum_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Google.Protobuf.TestProtos.MapEnum) x), 130); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Google.Protobuf.TestProtos.MapEnum) x, global::Google.Protobuf.TestProtos.MapEnum.Foo), 130); private readonly pbc::MapField mapInt32Enum_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Enum { @@ -389,7 +389,7 @@ public sealed partial class TestMap : pb::IMessage { /// Field number for the "map_int32_foreign_message" field. public const int MapInt32ForeignMessageFieldNumber = 17; private static readonly pbc::MapField.Codec _map_mapInt32ForeignMessage_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.ForeignMessage.Parser), 138); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.ForeignMessage.Parser), 138); private readonly pbc::MapField mapInt32ForeignMessage_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32ForeignMessage { @@ -789,7 +789,7 @@ public sealed partial class TestMessageMap : pb::IMessage { /// Field number for the "map_int32_message" field. public const int MapInt32MessageFieldNumber = 1; private static readonly pbc::MapField.Codec _map_mapInt32Message_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.TestAllTypes.Parser), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.TestAllTypes.Parser), 10); private readonly pbc::MapField mapInt32Message_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Message { @@ -914,7 +914,7 @@ public sealed partial class TestSameTypeMap : pb::IMessage { /// Field number for the "map1" field. public const int Map1FieldNumber = 1; private static readonly pbc::MapField.Codec _map_map1_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForInt32(16, 0), 10); private readonly pbc::MapField map1_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Map1 { @@ -924,7 +924,7 @@ public sealed partial class TestSameTypeMap : pb::IMessage { /// Field number for the "map2" field. public const int Map2FieldNumber = 2; private static readonly pbc::MapField.Codec _map_map2_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 18); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForInt32(16, 0), 18); private readonly pbc::MapField map2_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Map2 { @@ -1068,7 +1068,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_int32_int32" field. public const int MapInt32Int32FieldNumber = 1; private static readonly pbc::MapField.Codec _map_mapInt32Int32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForInt32(16, 0), 10); private readonly pbc::MapField mapInt32Int32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Int32 { @@ -1078,7 +1078,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_int64_int64" field. public const int MapInt64Int64FieldNumber = 2; private static readonly pbc::MapField.Codec _map_mapInt64Int64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt64(8), pb::FieldCodec.ForInt64(16), 18); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt64(8, 0L), pb::FieldCodec.ForInt64(16, 0L), 18); private readonly pbc::MapField mapInt64Int64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt64Int64 { @@ -1088,7 +1088,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_uint32_uint32" field. public const int MapUint32Uint32FieldNumber = 3; private static readonly pbc::MapField.Codec _map_mapUint32Uint32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForUInt32(8), pb::FieldCodec.ForUInt32(16), 26); + = new pbc::MapField.Codec(pb::FieldCodec.ForUInt32(8, 0), pb::FieldCodec.ForUInt32(16, 0), 26); private readonly pbc::MapField mapUint32Uint32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapUint32Uint32 { @@ -1098,7 +1098,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_uint64_uint64" field. public const int MapUint64Uint64FieldNumber = 4; private static readonly pbc::MapField.Codec _map_mapUint64Uint64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForUInt64(8), pb::FieldCodec.ForUInt64(16), 34); + = new pbc::MapField.Codec(pb::FieldCodec.ForUInt64(8, 0UL), pb::FieldCodec.ForUInt64(16, 0UL), 34); private readonly pbc::MapField mapUint64Uint64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapUint64Uint64 { @@ -1108,7 +1108,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_sint32_sint32" field. public const int MapSint32Sint32FieldNumber = 5; private static readonly pbc::MapField.Codec _map_mapSint32Sint32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSInt32(8), pb::FieldCodec.ForSInt32(16), 42); + = new pbc::MapField.Codec(pb::FieldCodec.ForSInt32(8, 0), pb::FieldCodec.ForSInt32(16, 0), 42); private readonly pbc::MapField mapSint32Sint32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSint32Sint32 { @@ -1118,7 +1118,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_sint64_sint64" field. public const int MapSint64Sint64FieldNumber = 6; private static readonly pbc::MapField.Codec _map_mapSint64Sint64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSInt64(8), pb::FieldCodec.ForSInt64(16), 50); + = new pbc::MapField.Codec(pb::FieldCodec.ForSInt64(8, 0L), pb::FieldCodec.ForSInt64(16, 0L), 50); private readonly pbc::MapField mapSint64Sint64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSint64Sint64 { @@ -1128,7 +1128,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_fixed32_fixed32" field. public const int MapFixed32Fixed32FieldNumber = 7; private static readonly pbc::MapField.Codec _map_mapFixed32Fixed32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForFixed32(13), pb::FieldCodec.ForFixed32(21), 58); + = new pbc::MapField.Codec(pb::FieldCodec.ForFixed32(13, 0), pb::FieldCodec.ForFixed32(21, 0), 58); private readonly pbc::MapField mapFixed32Fixed32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapFixed32Fixed32 { @@ -1138,7 +1138,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_fixed64_fixed64" field. public const int MapFixed64Fixed64FieldNumber = 8; private static readonly pbc::MapField.Codec _map_mapFixed64Fixed64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForFixed64(9), pb::FieldCodec.ForFixed64(17), 66); + = new pbc::MapField.Codec(pb::FieldCodec.ForFixed64(9, 0UL), pb::FieldCodec.ForFixed64(17, 0UL), 66); private readonly pbc::MapField mapFixed64Fixed64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapFixed64Fixed64 { @@ -1148,7 +1148,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_sfixed32_sfixed32" field. public const int MapSfixed32Sfixed32FieldNumber = 9; private static readonly pbc::MapField.Codec _map_mapSfixed32Sfixed32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed32(13), pb::FieldCodec.ForSFixed32(21), 74); + = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed32(13, 0), pb::FieldCodec.ForSFixed32(21, 0), 74); private readonly pbc::MapField mapSfixed32Sfixed32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSfixed32Sfixed32 { @@ -1158,7 +1158,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_sfixed64_sfixed64" field. public const int MapSfixed64Sfixed64FieldNumber = 10; private static readonly pbc::MapField.Codec _map_mapSfixed64Sfixed64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed64(9), pb::FieldCodec.ForSFixed64(17), 82); + = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed64(9, 0L), pb::FieldCodec.ForSFixed64(17, 0L), 82); private readonly pbc::MapField mapSfixed64Sfixed64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSfixed64Sfixed64 { @@ -1168,7 +1168,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_int32_float" field. public const int MapInt32FloatFieldNumber = 11; private static readonly pbc::MapField.Codec _map_mapInt32Float_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForFloat(21), 90); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForFloat(21, 0F), 90); private readonly pbc::MapField mapInt32Float_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Float { @@ -1178,7 +1178,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_int32_double" field. public const int MapInt32DoubleFieldNumber = 12; private static readonly pbc::MapField.Codec _map_mapInt32Double_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForDouble(17), 98); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForDouble(17, 0D), 98); private readonly pbc::MapField mapInt32Double_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Double { @@ -1188,7 +1188,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_bool_bool" field. public const int MapBoolBoolFieldNumber = 13; private static readonly pbc::MapField.Codec _map_mapBoolBool_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForBool(8), pb::FieldCodec.ForBool(16), 106); + = new pbc::MapField.Codec(pb::FieldCodec.ForBool(8, false), pb::FieldCodec.ForBool(16, false), 106); private readonly pbc::MapField mapBoolBool_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapBoolBool { @@ -1198,7 +1198,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_int32_enum" field. public const int MapInt32EnumFieldNumber = 14; private static readonly pbc::MapField.Codec _map_mapInt32Enum_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Google.Protobuf.TestProtos.MapEnum) x), 114); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Google.Protobuf.TestProtos.MapEnum) x, global::Google.Protobuf.TestProtos.MapEnum.Foo), 114); private readonly pbc::MapField mapInt32Enum_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Enum { @@ -1208,7 +1208,7 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Field number for the "map_int32_foreign_message" field. public const int MapInt32ForeignMessageFieldNumber = 15; private static readonly pbc::MapField.Codec _map_mapInt32ForeignMessage_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.ForeignMessage.Parser), 122); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.ForeignMessage.Parser), 122); private readonly pbc::MapField mapInt32ForeignMessage_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32ForeignMessage { @@ -1459,7 +1459,7 @@ public sealed partial class MessageContainingEnumCalledType : pb::IMessageField number for the "type" field. public const int TypeFieldNumber = 1; private static readonly pbc::MapField.Codec _map_type_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser), 10); private readonly pbc::MapField type_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Type { @@ -1594,7 +1594,7 @@ public sealed partial class MessageContainingMapCalledEntry : pb::IMessageField number for the "entry" field. public const int EntryFieldNumber = 1; private static readonly pbc::MapField.Codec _map_entry_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForInt32(16, 0), 10); private readonly pbc::MapField entry_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Entry { diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs index 824da8feb68..822ff268135 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs @@ -210,10 +210,10 @@ public static partial class TestMessagesProto3Reflection { "dF9tZXNzYWdlcy5wcm90bzNIAfgBAaICBlByb3RvM2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto3.ForeignEnum), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null), + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto3.ForeignEnum), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null), null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.ForeignMessage), global::ProtobufTestMessages.Proto3.ForeignMessage.Parser, new[]{ "C" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.ForeignMessage), global::ProtobufTestMessages.Proto3.ForeignMessage.Parser, new[]{ "C" }, null, null, null, null) })); } #endregion @@ -605,7 +605,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "optional_nested_enum" field. public const int OptionalNestedEnumFieldNumber = 21; - private global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum optionalNestedEnum_ = 0; + private global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum optionalNestedEnum_ = global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum OptionalNestedEnum { get { return optionalNestedEnum_; } @@ -616,7 +616,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "optional_foreign_enum" field. public const int OptionalForeignEnumFieldNumber = 22; - private global::ProtobufTestMessages.Proto3.ForeignEnum optionalForeignEnum_ = 0; + private global::ProtobufTestMessages.Proto3.ForeignEnum optionalForeignEnum_ = global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::ProtobufTestMessages.Proto3.ForeignEnum OptionalForeignEnum { get { return optionalForeignEnum_; } @@ -627,7 +627,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "optional_aliased_enum" field. public const int OptionalAliasedEnumFieldNumber = 23; - private global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum optionalAliasedEnum_ = 0; + private global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum optionalAliasedEnum_ = global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum.AliasFoo; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum OptionalAliasedEnum { get { return optionalAliasedEnum_; } @@ -885,7 +885,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_int32_int32" field. public const int MapInt32Int32FieldNumber = 56; private static readonly pbc::MapField.Codec _map_mapInt32Int32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 450); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForInt32(16, 0), 450); private readonly pbc::MapField mapInt32Int32_ = new pbc::MapField(); /// /// Map @@ -898,7 +898,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_int64_int64" field. public const int MapInt64Int64FieldNumber = 57; private static readonly pbc::MapField.Codec _map_mapInt64Int64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt64(8), pb::FieldCodec.ForInt64(16), 458); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt64(8, 0L), pb::FieldCodec.ForInt64(16, 0L), 458); private readonly pbc::MapField mapInt64Int64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt64Int64 { @@ -908,7 +908,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_uint32_uint32" field. public const int MapUint32Uint32FieldNumber = 58; private static readonly pbc::MapField.Codec _map_mapUint32Uint32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForUInt32(8), pb::FieldCodec.ForUInt32(16), 466); + = new pbc::MapField.Codec(pb::FieldCodec.ForUInt32(8, 0), pb::FieldCodec.ForUInt32(16, 0), 466); private readonly pbc::MapField mapUint32Uint32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapUint32Uint32 { @@ -918,7 +918,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_uint64_uint64" field. public const int MapUint64Uint64FieldNumber = 59; private static readonly pbc::MapField.Codec _map_mapUint64Uint64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForUInt64(8), pb::FieldCodec.ForUInt64(16), 474); + = new pbc::MapField.Codec(pb::FieldCodec.ForUInt64(8, 0UL), pb::FieldCodec.ForUInt64(16, 0UL), 474); private readonly pbc::MapField mapUint64Uint64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapUint64Uint64 { @@ -928,7 +928,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_sint32_sint32" field. public const int MapSint32Sint32FieldNumber = 60; private static readonly pbc::MapField.Codec _map_mapSint32Sint32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSInt32(8), pb::FieldCodec.ForSInt32(16), 482); + = new pbc::MapField.Codec(pb::FieldCodec.ForSInt32(8, 0), pb::FieldCodec.ForSInt32(16, 0), 482); private readonly pbc::MapField mapSint32Sint32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSint32Sint32 { @@ -938,7 +938,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_sint64_sint64" field. public const int MapSint64Sint64FieldNumber = 61; private static readonly pbc::MapField.Codec _map_mapSint64Sint64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSInt64(8), pb::FieldCodec.ForSInt64(16), 490); + = new pbc::MapField.Codec(pb::FieldCodec.ForSInt64(8, 0L), pb::FieldCodec.ForSInt64(16, 0L), 490); private readonly pbc::MapField mapSint64Sint64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSint64Sint64 { @@ -948,7 +948,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_fixed32_fixed32" field. public const int MapFixed32Fixed32FieldNumber = 62; private static readonly pbc::MapField.Codec _map_mapFixed32Fixed32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForFixed32(13), pb::FieldCodec.ForFixed32(21), 498); + = new pbc::MapField.Codec(pb::FieldCodec.ForFixed32(13, 0), pb::FieldCodec.ForFixed32(21, 0), 498); private readonly pbc::MapField mapFixed32Fixed32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapFixed32Fixed32 { @@ -958,7 +958,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_fixed64_fixed64" field. public const int MapFixed64Fixed64FieldNumber = 63; private static readonly pbc::MapField.Codec _map_mapFixed64Fixed64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForFixed64(9), pb::FieldCodec.ForFixed64(17), 506); + = new pbc::MapField.Codec(pb::FieldCodec.ForFixed64(9, 0UL), pb::FieldCodec.ForFixed64(17, 0UL), 506); private readonly pbc::MapField mapFixed64Fixed64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapFixed64Fixed64 { @@ -968,7 +968,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_sfixed32_sfixed32" field. public const int MapSfixed32Sfixed32FieldNumber = 64; private static readonly pbc::MapField.Codec _map_mapSfixed32Sfixed32_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed32(13), pb::FieldCodec.ForSFixed32(21), 514); + = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed32(13, 0), pb::FieldCodec.ForSFixed32(21, 0), 514); private readonly pbc::MapField mapSfixed32Sfixed32_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSfixed32Sfixed32 { @@ -978,7 +978,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_sfixed64_sfixed64" field. public const int MapSfixed64Sfixed64FieldNumber = 65; private static readonly pbc::MapField.Codec _map_mapSfixed64Sfixed64_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed64(9), pb::FieldCodec.ForSFixed64(17), 522); + = new pbc::MapField.Codec(pb::FieldCodec.ForSFixed64(9, 0L), pb::FieldCodec.ForSFixed64(17, 0L), 522); private readonly pbc::MapField mapSfixed64Sfixed64_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapSfixed64Sfixed64 { @@ -988,7 +988,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_int32_float" field. public const int MapInt32FloatFieldNumber = 66; private static readonly pbc::MapField.Codec _map_mapInt32Float_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForFloat(21), 530); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForFloat(21, 0F), 530); private readonly pbc::MapField mapInt32Float_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Float { @@ -998,7 +998,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_int32_double" field. public const int MapInt32DoubleFieldNumber = 67; private static readonly pbc::MapField.Codec _map_mapInt32Double_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForDouble(17), 538); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForDouble(17, 0D), 538); private readonly pbc::MapField mapInt32Double_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapInt32Double { @@ -1008,7 +1008,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_bool_bool" field. public const int MapBoolBoolFieldNumber = 68; private static readonly pbc::MapField.Codec _map_mapBoolBool_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForBool(8), pb::FieldCodec.ForBool(16), 546); + = new pbc::MapField.Codec(pb::FieldCodec.ForBool(8, false), pb::FieldCodec.ForBool(16, false), 546); private readonly pbc::MapField mapBoolBool_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapBoolBool { @@ -1018,7 +1018,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_string_string" field. public const int MapStringStringFieldNumber = 69; private static readonly pbc::MapField.Codec _map_mapStringString_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForString(18), 554); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForString(18, ""), 554); private readonly pbc::MapField mapStringString_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringString { @@ -1028,7 +1028,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_string_bytes" field. public const int MapStringBytesFieldNumber = 70; private static readonly pbc::MapField.Codec _map_mapStringBytes_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForBytes(18), 562); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForBytes(18, pb::ByteString.Empty), 562); private readonly pbc::MapField mapStringBytes_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringBytes { @@ -1038,7 +1038,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_string_nested_message" field. public const int MapStringNestedMessageFieldNumber = 71; private static readonly pbc::MapField.Codec _map_mapStringNestedMessage_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser), 570); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForMessage(18, global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser), 570); private readonly pbc::MapField mapStringNestedMessage_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringNestedMessage { @@ -1048,7 +1048,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_string_foreign_message" field. public const int MapStringForeignMessageFieldNumber = 72; private static readonly pbc::MapField.Codec _map_mapStringForeignMessage_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::ProtobufTestMessages.Proto3.ForeignMessage.Parser), 578); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForMessage(18, global::ProtobufTestMessages.Proto3.ForeignMessage.Parser), 578); private readonly pbc::MapField mapStringForeignMessage_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringForeignMessage { @@ -1058,7 +1058,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_string_nested_enum" field. public const int MapStringNestedEnumFieldNumber = 73; private static readonly pbc::MapField.Codec _map_mapStringNestedEnum_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum) x), 586); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum) x, global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo), 586); private readonly pbc::MapField mapStringNestedEnum_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringNestedEnum { @@ -1068,7 +1068,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "map_string_foreign_enum" field. public const int MapStringForeignEnumFieldNumber = 74; private static readonly pbc::MapField.Codec _map_mapStringForeignEnum_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::ProtobufTestMessages.Proto3.ForeignEnum) x), 594); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::ProtobufTestMessages.Proto3.ForeignEnum) x, global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo), 594); private readonly pbc::MapField mapStringForeignEnum_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField MapStringForeignEnum { @@ -1167,7 +1167,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageHolder for extension identifiers generated from the top level of unittest_custom_options_proto3.proto + internal static partial class UnittestCustomOptionsProto3Extensions { + public static readonly pb::Extension FileOpt1 = + new pb::Extension(7736974, pb::FieldCodec.ForUInt64(61895792, 0UL)); + public static readonly pb::Extension MessageOpt1 = + new pb::Extension(7739036, pb::FieldCodec.ForInt32(61912288, 0)); + public static readonly pb::Extension FieldOpt1 = + new pb::Extension(7740936, pb::FieldCodec.ForFixed64(61927489, 0UL)); + public static readonly pb::Extension OneofOpt1 = + new pb::Extension(7740111, pb::FieldCodec.ForInt32(61920888, 0)); + public static readonly pb::Extension EnumOpt1 = + new pb::Extension(7753576, pb::FieldCodec.ForSFixed32(62028613, 0)); + public static readonly pb::Extension EnumValueOpt1 = + new pb::Extension(1560678, pb::FieldCodec.ForInt32(12485424, 0)); + public static readonly pb::Extension ServiceOpt1 = + new pb::Extension(7887650, pb::FieldCodec.ForSInt64(63101200, 0L)); + public static readonly pb::Extension MethodOpt1 = + new pb::Extension(7890860, pb::FieldCodec.ForEnum(63126880, x => (int) x, x => (global::UnitTest.Issues.TestProtos.MethodOpt1) x, global::UnitTest.Issues.TestProtos.MethodOpt1.Unspecified)); + public static readonly pb::Extension BoolOpt = + new pb::Extension(7706090, pb::FieldCodec.ForBool(61648720, false)); + public static readonly pb::Extension Int32Opt = + new pb::Extension(7705709, pb::FieldCodec.ForInt32(61645672, 0)); + public static readonly pb::Extension Int64Opt = + new pb::Extension(7705542, pb::FieldCodec.ForInt64(61644336, 0L)); + public static readonly pb::Extension Uint32Opt = + new pb::Extension(7704880, pb::FieldCodec.ForUInt32(61639040, 0)); + public static readonly pb::Extension Uint64Opt = + new pb::Extension(7702367, pb::FieldCodec.ForUInt64(61618936, 0UL)); + public static readonly pb::Extension Sint32Opt = + new pb::Extension(7701568, pb::FieldCodec.ForSInt32(61612544, 0)); + public static readonly pb::Extension Sint64Opt = + new pb::Extension(7700863, pb::FieldCodec.ForSInt64(61606904, 0L)); + public static readonly pb::Extension Fixed32Opt = + new pb::Extension(7700307, pb::FieldCodec.ForFixed32(61602461, 0)); + public static readonly pb::Extension Fixed64Opt = + new pb::Extension(7700194, pb::FieldCodec.ForFixed64(61601553, 0UL)); + public static readonly pb::Extension Sfixed32Opt = + new pb::Extension(7698645, pb::FieldCodec.ForSFixed32(61589165, 0)); + public static readonly pb::Extension Sfixed64Opt = + new pb::Extension(7685475, pb::FieldCodec.ForSFixed64(61483801, 0L)); + public static readonly pb::Extension FloatOpt = + new pb::Extension(7675390, pb::FieldCodec.ForFloat(61403125, 0F)); + public static readonly pb::Extension DoubleOpt = + new pb::Extension(7673293, pb::FieldCodec.ForDouble(61386345, 0D)); + public static readonly pb::Extension StringOpt = + new pb::Extension(7673285, pb::FieldCodec.ForString(61386282, "")); + public static readonly pb::Extension BytesOpt = + new pb::Extension(7673238, pb::FieldCodec.ForBytes(61385906, pb::ByteString.Empty)); + public static readonly pb::Extension EnumOpt = + new pb::Extension(7673233, pb::FieldCodec.ForEnum(61385864, x => (int) x, x => (global::UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types.TestEnumType) x, global::UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types.TestEnumType.TestOptionEnumUnspecified)); + public static readonly pb::Extension MessageTypeOpt = + new pb::Extension(7665967, pb::FieldCodec.ForMessage(61327738, global::UnitTest.Issues.TestProtos.DummyMessageInvalidAsOptionType.Parser)); + public static readonly pb::Extension ComplexOpt1 = + new pb::Extension(7646756, pb::FieldCodec.ForMessage(61174050, global::UnitTest.Issues.TestProtos.ComplexOptionType1.Parser)); + public static readonly pb::Extension ComplexOpt2 = + new pb::Extension(7636949, pb::FieldCodec.ForMessage(61095594, global::UnitTest.Issues.TestProtos.ComplexOptionType2.Parser)); + public static readonly pb::Extension ComplexOpt3 = + new pb::Extension(7636463, pb::FieldCodec.ForMessage(61091706, global::UnitTest.Issues.TestProtos.ComplexOptionType3.Parser)); + public static readonly pb::Extension Fileopt = + new pb::Extension(15478479, pb::FieldCodec.ForMessage(123827834, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + public static readonly pb::Extension Msgopt = + new pb::Extension(15480088, pb::FieldCodec.ForMessage(123840706, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + public static readonly pb::Extension Fieldopt = + new pb::Extension(15481374, pb::FieldCodec.ForMessage(123850994, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + public static readonly pb::Extension Enumopt = + new pb::Extension(15483218, pb::FieldCodec.ForMessage(123865746, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + public static readonly pb::Extension Enumvalopt = + new pb::Extension(15486921, pb::FieldCodec.ForMessage(123895370, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + public static readonly pb::Extension Serviceopt = + new pb::Extension(15497145, pb::FieldCodec.ForMessage(123977162, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + public static readonly pb::Extension Methodopt = + new pb::Extension(15512713, pb::FieldCodec.ForMessage(124101706, global::UnitTest.Issues.TestProtos.Aggregate.Parser)); + } + #region Enums public enum MethodOpt1 { [pbr::OriginalName("METHODOPT1_UNSPECIFIED")] Unspecified = 0, @@ -2061,6 +2135,15 @@ public sealed partial class ComplexOptionType4 : pb::IMessageContainer for extensions for other messages declared in the ComplexOptionType4 message type. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + internal static partial class Extensions { + public static readonly pb::Extension ComplexOpt4 = + new pb::Extension(7633546, pb::FieldCodec.ForMessage(61068370, global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Parser)); + } + #endregion + } } diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs index 6bf97151715..19a1a34634f 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs @@ -32,8 +32,8 @@ public static partial class UnittestImportProto3Reflection { "cm90b2J1Zi5UZXN0UHJvdG9zUABiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportPublicProto3Reflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), global::Google.Protobuf.TestProtos.ImportMessage.Parser, new[]{ "D" }, null, null, null) + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), global::Google.Protobuf.TestProtos.ImportMessage.Parser, new[]{ "D" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs index 97d181aff48..a4556554698 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs @@ -30,8 +30,8 @@ public static partial class UnittestImportPublicProto3Reflection { "Mw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), global::Google.Protobuf.TestProtos.PublicImportMessage.Parser, new[]{ "E" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), global::Google.Protobuf.TestProtos.PublicImportMessage.Parser, new[]{ "E" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs index f27ab640749..f3f40c6a70c 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs @@ -54,16 +54,16 @@ public static partial class UnittestIssuesReflection { "cy5UZXN0UHJvdG9zYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null)})}), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null)}) + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null, null)})}), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser, null, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}) })); } #endregion @@ -443,7 +443,7 @@ public sealed partial class NegativeEnumMessage : pb::IMessageField number for the "value" field. public const int ValueFieldNumber = 1; - private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = 0; + private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.Zero; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::UnitTest.Issues.TestProtos.NegativeEnum Value { get { return value_; } @@ -494,7 +494,7 @@ public sealed partial class NegativeEnumMessage : pb::IMessageField number for the "EnumValue" field. public const int EnumValueFieldNumber = 5; - private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = 0; + private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = global::UnitTest.Issues.TestProtos.DeprecatedEnum.DeprecatedZero; [global::System.ObsoleteAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue { @@ -814,7 +814,7 @@ public sealed partial class DeprecatedFieldsMessage : pb::IMessage { /// Field number for the "single_nested_enum" field. public const int SingleNestedEnumFieldNumber = 21; - private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = 0; + private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.Unspecified; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum SingleNestedEnum { get { return singleNestedEnum_; } @@ -560,7 +560,7 @@ public sealed partial class TestAllTypes : pb::IMessage { /// Field number for the "single_foreign_enum" field. public const int SingleForeignEnumFieldNumber = 22; - private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = 0; + private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.ForeignEnum SingleForeignEnum { get { return singleForeignEnum_; } @@ -571,7 +571,7 @@ public sealed partial class TestAllTypes : pb::IMessage { /// Field number for the "single_import_enum" field. public const int SingleImportEnumFieldNumber = 23; - private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = 0; + private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = global::Google.Protobuf.TestProtos.ImportEnum.Unspecified; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.ImportEnum SingleImportEnum { get { return singleImportEnum_; } @@ -971,9 +971,9 @@ public enum OneofFieldOneofCase { if (singleNestedMessage_ != null) hash ^= SingleNestedMessage.GetHashCode(); if (singleForeignMessage_ != null) hash ^= SingleForeignMessage.GetHashCode(); if (singleImportMessage_ != null) hash ^= SingleImportMessage.GetHashCode(); - if (SingleNestedEnum != 0) hash ^= SingleNestedEnum.GetHashCode(); - if (SingleForeignEnum != 0) hash ^= SingleForeignEnum.GetHashCode(); - if (SingleImportEnum != 0) hash ^= SingleImportEnum.GetHashCode(); + if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.Unspecified) hash ^= SingleNestedEnum.GetHashCode(); + if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified) hash ^= SingleForeignEnum.GetHashCode(); + if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.Unspecified) hash ^= SingleImportEnum.GetHashCode(); if (singlePublicImportMessage_ != null) hash ^= SinglePublicImportMessage.GetHashCode(); hash ^= repeatedInt32_.GetHashCode(); hash ^= repeatedInt64_.GetHashCode(); @@ -1087,15 +1087,15 @@ public enum OneofFieldOneofCase { output.WriteRawTag(162, 1); output.WriteMessage(SingleImportMessage); } - if (SingleNestedEnum != 0) { + if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.Unspecified) { output.WriteRawTag(168, 1); output.WriteEnum((int) SingleNestedEnum); } - if (SingleForeignEnum != 0) { + if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified) { output.WriteRawTag(176, 1); output.WriteEnum((int) SingleForeignEnum); } - if (SingleImportEnum != 0) { + if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.Unspecified) { output.WriteRawTag(184, 1); output.WriteEnum((int) SingleImportEnum); } @@ -1203,13 +1203,13 @@ public enum OneofFieldOneofCase { if (singleImportMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleImportMessage); } - if (SingleNestedEnum != 0) { + if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.Unspecified) { size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleNestedEnum); } - if (SingleForeignEnum != 0) { + if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified) { size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleForeignEnum); } - if (SingleImportEnum != 0) { + if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.Unspecified) { size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleImportEnum); } if (singlePublicImportMessage_ != null) { @@ -1323,13 +1323,13 @@ public enum OneofFieldOneofCase { } SingleImportMessage.MergeFrom(other.SingleImportMessage); } - if (other.SingleNestedEnum != 0) { + if (other.SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.Unspecified) { SingleNestedEnum = other.SingleNestedEnum; } - if (other.SingleForeignEnum != 0) { + if (other.SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified) { SingleForeignEnum = other.SingleForeignEnum; } - if (other.SingleImportEnum != 0) { + if (other.SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.Unspecified) { SingleImportEnum = other.SingleImportEnum; } if (other.singlePublicImportMessage_ != null) { @@ -3130,7 +3130,7 @@ public sealed partial class TestEnumAllowAlias : pb::IMessageField number for the "value" field. public const int ValueFieldNumber = 1; - private global::Google.Protobuf.TestProtos.TestEnumWithDupValue value_ = 0; + private global::Google.Protobuf.TestProtos.TestEnumWithDupValue value_ = global::Google.Protobuf.TestProtos.TestEnumWithDupValue.Unspecified; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.TestEnumWithDupValue Value { get { return value_; } @@ -3159,7 +3159,7 @@ public sealed partial class TestEnumAllowAlias : pb::IMessageField number for the "EnumField" field. public const int EnumFieldFieldNumber = 3; - private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = 0; + private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.ForeignEnum EnumField { get { return enumField_; } @@ -3381,7 +3381,7 @@ public sealed partial class TestCamelCaseFieldNames : pb::IMessage /// Field number for the "sparse_enum" field. public const int SparseEnumFieldNumber = 1; - private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = 0; + private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.TestSparseEnum SparseEnum { get { return sparseEnum_; } @@ -3985,7 +3985,7 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (SparseEnum != 0) hash ^= SparseEnum.GetHashCode(); + if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified) hash ^= SparseEnum.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -3999,7 +3999,7 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (SparseEnum != 0) { + if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified) { output.WriteRawTag(8); output.WriteEnum((int) SparseEnum); } @@ -4011,7 +4011,7 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (SparseEnum != 0) { + if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) SparseEnum); } if (_unknownFields != null) { @@ -4025,7 +4025,7 @@ public sealed partial class SparseEnumMessage : pb::IMessage if (other == null) { return; } - if (other.SparseEnum != 0) { + if (other.SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified) { SparseEnum = other.SparseEnum; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs index 45f8ece6469..90b338436bc 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs @@ -163,11 +163,11 @@ public static partial class UnittestWellKnownTypesReflection { "dFByb3Rvc2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), global::Google.Protobuf.TestProtos.TestWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", "ValueField" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), global::Google.Protobuf.TestProtos.OneofWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, new[]{ "OneofField" }, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MapWellKnownTypes), global::Google.Protobuf.TestProtos.MapWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), global::Google.Protobuf.TestProtos.TestWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", "ValueField" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), global::Google.Protobuf.TestProtos.OneofWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, new[]{ "OneofField" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MapWellKnownTypes), global::Google.Protobuf.TestProtos.MapWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }) })); } #endregion @@ -2211,7 +2211,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "any_field" field. public const int AnyFieldFieldNumber = 1; private static readonly pbc::MapField.Codec _map_anyField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Any.Parser), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Any.Parser), 10); private readonly pbc::MapField anyField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField AnyField { @@ -2221,7 +2221,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "api_field" field. public const int ApiFieldFieldNumber = 2; private static readonly pbc::MapField.Codec _map_apiField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Api.Parser), 18); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Api.Parser), 18); private readonly pbc::MapField apiField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField ApiField { @@ -2231,7 +2231,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "duration_field" field. public const int DurationFieldFieldNumber = 3; private static readonly pbc::MapField.Codec _map_durationField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Duration.Parser), 26); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Duration.Parser), 26); private readonly pbc::MapField durationField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField DurationField { @@ -2241,7 +2241,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "empty_field" field. public const int EmptyFieldFieldNumber = 4; private static readonly pbc::MapField.Codec _map_emptyField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Empty.Parser), 34); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Empty.Parser), 34); private readonly pbc::MapField emptyField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField EmptyField { @@ -2251,7 +2251,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "field_mask_field" field. public const int FieldMaskFieldFieldNumber = 5; private static readonly pbc::MapField.Codec _map_fieldMaskField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.FieldMask.Parser), 42); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.FieldMask.Parser), 42); private readonly pbc::MapField fieldMaskField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField FieldMaskField { @@ -2261,7 +2261,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "source_context_field" field. public const int SourceContextFieldFieldNumber = 6; private static readonly pbc::MapField.Codec _map_sourceContextField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.SourceContext.Parser), 50); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.SourceContext.Parser), 50); private readonly pbc::MapField sourceContextField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField SourceContextField { @@ -2271,7 +2271,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "struct_field" field. public const int StructFieldFieldNumber = 7; private static readonly pbc::MapField.Codec _map_structField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Struct.Parser), 58); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Struct.Parser), 58); private readonly pbc::MapField structField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField StructField { @@ -2281,7 +2281,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "timestamp_field" field. public const int TimestampFieldFieldNumber = 8; private static readonly pbc::MapField.Codec _map_timestampField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Timestamp.Parser), 66); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Timestamp.Parser), 66); private readonly pbc::MapField timestampField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField TimestampField { @@ -2291,7 +2291,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "type_field" field. public const int TypeFieldFieldNumber = 9; private static readonly pbc::MapField.Codec _map_typeField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Type.Parser), 74); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Type.Parser), 74); private readonly pbc::MapField typeField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField TypeField { @@ -2301,7 +2301,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "double_field" field. public const int DoubleFieldFieldNumber = 10; private static readonly pbc::MapField.Codec _map_doubleField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 82); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 82); private readonly pbc::MapField doubleField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField DoubleField { @@ -2311,7 +2311,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "float_field" field. public const int FloatFieldFieldNumber = 11; private static readonly pbc::MapField.Codec _map_floatField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 90); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 90); private readonly pbc::MapField floatField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField FloatField { @@ -2321,7 +2321,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "int64_field" field. public const int Int64FieldFieldNumber = 12; private static readonly pbc::MapField.Codec _map_int64Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 98); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 98); private readonly pbc::MapField int64Field_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Int64Field { @@ -2331,7 +2331,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "uint64_field" field. public const int Uint64FieldFieldNumber = 13; private static readonly pbc::MapField.Codec _map_uint64Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 106); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 106); private readonly pbc::MapField uint64Field_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Uint64Field { @@ -2341,7 +2341,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "int32_field" field. public const int Int32FieldFieldNumber = 14; private static readonly pbc::MapField.Codec _map_int32Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 114); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 114); private readonly pbc::MapField int32Field_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Int32Field { @@ -2351,7 +2351,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "uint32_field" field. public const int Uint32FieldFieldNumber = 15; private static readonly pbc::MapField.Codec _map_uint32Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 122); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 122); private readonly pbc::MapField uint32Field_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField Uint32Field { @@ -2361,7 +2361,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "bool_field" field. public const int BoolFieldFieldNumber = 16; private static readonly pbc::MapField.Codec _map_boolField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 130); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForStructWrapper(18), 130); private readonly pbc::MapField boolField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField BoolField { @@ -2371,7 +2371,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "string_field" field. public const int StringFieldFieldNumber = 17; private static readonly pbc::MapField.Codec _map_stringField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper(18), 138); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForClassWrapper(18), 138); private readonly pbc::MapField stringField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField StringField { @@ -2381,7 +2381,7 @@ public sealed partial class MapWellKnownTypes : pb::IMessage /// Field number for the "bytes_field" field. public const int BytesFieldFieldNumber = 18; private static readonly pbc::MapField.Codec _map_bytesField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper(18), 146); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8, 0), pb::FieldCodec.ForClassWrapper(18), 146); private readonly pbc::MapField bytesField_ = new pbc::MapField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::MapField BytesField { diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs index 34e37300d6b..4d13f88ab95 100644 --- a/csharp/src/Google.Protobuf/CodedInputStream.cs +++ b/csharp/src/Google.Protobuf/CodedInputStream.cs @@ -272,6 +272,11 @@ public long Position /// internal bool DiscardUnknownFields { get; set; } + /// + /// Internal-only property; provides extension identifiers to compatible messages while parsing. + /// + internal ExtensionRegistry ExtensionRegistry { get; set; } + /// /// Disposes of this instance, potentially closing any underlying stream. /// @@ -574,7 +579,7 @@ public string ReadString() /// /// Reads an embedded message field value from the stream. - /// + /// public void ReadMessage(IMessage builder) { int length = ReadLength(); diff --git a/csharp/src/Google.Protobuf/Extension.cs b/csharp/src/Google.Protobuf/Extension.cs new file mode 100644 index 00000000000..ddeb97795aa --- /dev/null +++ b/csharp/src/Google.Protobuf/Extension.cs @@ -0,0 +1,111 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; + +namespace Google.Protobuf +{ + /// + /// Represents a non-generic extension definition + /// + public abstract class Extension + { + internal abstract Type TargetType { get; } + + /// + /// Internal use. Creates a new extension with the specified field number. + /// + protected Extension(int number) + { + FieldNumber = number; + } + + internal abstract IExtensionValue CreateValue(); + + /// + /// Gets the field number of this extension + /// + public int FieldNumber { get; } + } + + /// + /// Represents a type-safe extension identifier used for getting and setting single extension values in instances + /// + /// The message type this field applies to + /// The field value type of this extension + public sealed class Extension : Extension where TTarget : IExtendableMessage + { + private readonly FieldCodec codec; + + /// + /// Creates a new extension identifier with the specified field number and codec + /// + public Extension(int number, FieldCodec codec) : base(number) + { + this.codec = codec; + } + + internal TValue DefaultValue => codec.DefaultValue; + + internal override Type TargetType => typeof(TTarget); + + internal override IExtensionValue CreateValue() + { + return new ExtensionValue(codec); + } + } + + /// + /// Represents a type-safe extension identifier used for getting repeated extension values in instances + /// + /// The message type this field applies to + /// The repeated field value type of this extension + public sealed class RepeatedExtension : Extension where TTarget : IExtendableMessage + { + private readonly FieldCodec codec; + + /// + /// Creates a new repeated extension identifier with the specified field number and codec + /// + public RepeatedExtension(int number, FieldCodec codec) : base(number) + { + this.codec = codec; + } + + internal override Type TargetType => typeof(TTarget); + + internal override IExtensionValue CreateValue() + { + return new RepeatedExtensionValue(codec); + } + } +} diff --git a/csharp/src/Google.Protobuf/ExtensionRegistry.cs b/csharp/src/Google.Protobuf/ExtensionRegistry.cs new file mode 100644 index 00000000000..ea655c123e2 --- /dev/null +++ b/csharp/src/Google.Protobuf/ExtensionRegistry.cs @@ -0,0 +1,175 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Google.Protobuf +{ + /// + /// Provides extensions to messages while parsing + /// + public sealed class ExtensionRegistry : ICollection, IDeepCloneable + { + private IDictionary, Extension> extensions; + + /// + /// Creates a new empty extension registry + /// + public ExtensionRegistry() + { + extensions = new Dictionary, Extension>(); + } + + private ExtensionRegistry(IDictionary, Extension> collection) + { + extensions = collection.ToDictionary(k => k.Key, v => v.Value); + } + + /// + /// Gets the total number of extensions in this extension registry + /// + public int Count => extensions.Count; + + /// + /// Returns whether the registry is readonly + /// + bool ICollection.IsReadOnly => false; + + internal bool ContainsInputField(CodedInputStream stream, Type target, out Extension extension) + { + return extensions.TryGetValue(new ObjectIntPair(target, WireFormat.GetTagFieldNumber(stream.LastTag)), out extension); + } + + /// + /// Adds the specified extension to the registry + /// + public void Add(Extension extension) + { + ProtoPreconditions.CheckNotNull(extension, nameof(extension)); + + extensions.Add(new ObjectIntPair(extension.TargetType, extension.FieldNumber), extension); + } + + /// + /// Adds the specified extensions to the registry + /// + public void Add(params Extension[] newExtensions) + { + ProtoPreconditions.CheckNotNull(newExtensions, nameof(newExtensions)); + + Add((IEnumerable)newExtensions); + } + + /// + /// Adds the specified extensions to the reigstry + /// + public void Add(IEnumerable newExtensions) + { + ProtoPreconditions.CheckNotNull(newExtensions, nameof(newExtensions)); + + foreach (var extension in newExtensions) + Add(extension); + } + + /// + /// Clears the registry of all values + /// + public void Clear() + { + extensions.Clear(); + } + + /// + /// Gets whether the extension registry contains the specified extension + /// + public bool Contains(Extension item) + { + ProtoPreconditions.CheckNotNull(item, nameof(item)); + + return extensions.ContainsKey(new ObjectIntPair(item.TargetType, item.FieldNumber)); + } + + /// + /// Copies the arrays in the registry set to the specified array at the specified index + /// + /// The array to copy to + /// The array index to start at + void ICollection.CopyTo(Extension[] array, int arrayIndex) + { + ProtoPreconditions.CheckNotNull(array, nameof(array)); + if (arrayIndex < 0 || arrayIndex >= array.Length) + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + if (array.Length - arrayIndex < Count) + throw new ArgumentException("The provided array is shorter than the number of elements in the registry"); + + for (int i = 0; i < array.Length; i++) + { + Extension extension = array[i]; + extensions.Add(new ObjectIntPair(extension.TargetType, extension.FieldNumber), extension); + } + } + + /// + /// Returns an enumerator to enumerate through the items in the registry + /// + /// Returns an enumerator for the extensions in this registry + public IEnumerator GetEnumerator() + { + return extensions.Values.GetEnumerator(); + } + + /// + /// Removes the specified extension from the set + /// + /// The extension + /// true if the extension was removed, otherwise false + public bool Remove(Extension item) + { + ProtoPreconditions.CheckNotNull(item, nameof(item)); + + return extensions.Remove(new ObjectIntPair(item.TargetType, item.FieldNumber)); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + /// Clones the registry into a new registry + /// + public ExtensionRegistry Clone() + { + return new ExtensionRegistry(extensions); + } + } +} diff --git a/csharp/src/Google.Protobuf/ExtensionSet.cs b/csharp/src/Google.Protobuf/ExtensionSet.cs new file mode 100644 index 00000000000..fa81e6a633a --- /dev/null +++ b/csharp/src/Google.Protobuf/ExtensionSet.cs @@ -0,0 +1,341 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using Google.Protobuf.Collections; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Google.Protobuf +{ + /// + /// Methods for managing s with null checking. + /// + /// Most users will not use this class directly + /// + public static class ExtensionSet + { + private static bool GetValue(ref ExtensionSet set, Extension extension, out IExtensionValue value) where TTarget : IExtendableMessage + { + if (set == null) + { + value = null; + return false; + } + return set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value); + } + + /// + /// Gets the value of the specified extension + /// + public static TValue Get(ref ExtensionSet set, Extension extension) where TTarget : IExtendableMessage + { + IExtensionValue value; + if (GetValue(ref set, extension, out value)) + { + return ((ExtensionValue)value).GetValue(); + } + else + { + return extension.DefaultValue; + } + } + + /// + /// Gets the value of the specified repeated extension or null if it doesn't exist in this set + /// + public static RepeatedField Get(ref ExtensionSet set, RepeatedExtension extension) where TTarget : IExtendableMessage + { + IExtensionValue value; + if (GetValue(ref set, extension, out value)) + { + return ((RepeatedExtensionValue)value).GetValue(); + } + else + { + return null; + } + } + + /// + /// Gets the value of the specified repeated extension, registering it if it doesn't exist + /// + public static RepeatedField GetOrRegister(ref ExtensionSet set, RepeatedExtension extension) where TTarget : IExtendableMessage + { + IExtensionValue value; + if (set == null) + { + value = extension.CreateValue(); + set = new ExtensionSet(); + set.ValuesByNumber.Add(extension.FieldNumber, value); + } + else + { + if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value)) + { + value = extension.CreateValue(); + set.ValuesByNumber.Add(extension.FieldNumber, value); + } + } + + return ((RepeatedExtensionValue)value).GetValue(); + } + + /// + /// Sets the value of the specified extension + /// + public static void Set(ref ExtensionSet set, Extension extension, TValue value) where TTarget : IExtendableMessage + { + IExtensionValue extensionValue; + if (set == null) + { + extensionValue = extension.CreateValue(); + set = new ExtensionSet(); + set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); + } + else + { + if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out extensionValue)) + { + extensionValue = extension.CreateValue(); + set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); + } + } + + ((ExtensionValue)extensionValue).SetValue(value); + } + + /// + /// Gets whether the value of the specified extension is set + /// + public static bool Has(ref ExtensionSet set, Extension extension) where TTarget : IExtendableMessage + { + IExtensionValue value; + if (GetValue(ref set, extension, out value)) + { + return ((ExtensionValue)value).HasValue; + } + else + { + return false; + } + } + + /// + /// Clears the value of the specified extension + /// + public static void Clear(ref ExtensionSet set, Extension extension) where TTarget : IExtendableMessage + { + if (set == null) + { + return; + } + set.ValuesByNumber.Remove(extension.FieldNumber); + if (set.ValuesByNumber.Count == 0) + { + set = null; + } + } + + /// + /// Clears the value of the specified extension + /// + public static void Clear(ref ExtensionSet set, RepeatedExtension extension) where TTarget : IExtendableMessage + { + if (set == null) + { + return; + } + set.ValuesByNumber.Remove(extension.FieldNumber); + if (set.ValuesByNumber.Count == 0) + { + set = null; + } + } + + /// + /// Tries to merge a field from the coded input, returning true if the field was merged. + /// If the set is null or the field was not otherwise merged, this returns false. + /// + public static bool TryMergeFieldFrom(ref ExtensionSet set, CodedInputStream stream) where TTarget : IExtendableMessage + { + Extension extension; + int lastFieldNumber = WireFormat.GetTagFieldNumber(stream.LastTag); + + IExtensionValue extensionValue; + if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue)) + { + extensionValue.MergeFrom(stream); + return true; + } + else if (stream.ExtensionRegistry != null && stream.ExtensionRegistry.ContainsInputField(stream, typeof(TTarget), out extension)) + { + IExtensionValue value = extension.CreateValue(); + value.MergeFrom(stream); + set = (set ?? new ExtensionSet()); + set.ValuesByNumber.Add(extension.FieldNumber, value); + return true; + } + else + { + return false; + } + } + + /// + /// Merges the second set into the first set, creating a new instance if first is null + /// + public static void MergeFrom(ref ExtensionSet first, ExtensionSet second) where TTarget : IExtendableMessage + { + if (second == null) + { + return; + } + if (first == null) + { + first = new ExtensionSet(); + } + foreach (var pair in second.ValuesByNumber) + { + IExtensionValue value; + if (first.ValuesByNumber.TryGetValue(pair.Key, out value)) + { + value.MergeFrom(pair.Value); + } + else + { + var cloned = pair.Value.Clone(); + first.ValuesByNumber[pair.Key] = cloned; + } + } + } + + /// + /// Clones the set into a new set. If the set is null, this returns null + /// + public static ExtensionSet Clone(ExtensionSet set) where TTarget : IExtendableMessage + { + if (set == null) + { + return null; + } + + var newSet = new ExtensionSet(); + foreach (var pair in set.ValuesByNumber) + { + var cloned = pair.Value.Clone(); + newSet.ValuesByNumber[pair.Key] = cloned; + } + return newSet; + } + } + + /// + /// Used for keeping track of extensions in messages. + /// methods route to this set. + /// + /// Most users will not need to use this class directly + /// + /// The message type that extensions in this set target + public sealed class ExtensionSet where TTarget : IExtendableMessage + { + internal Dictionary ValuesByNumber { get; } = new Dictionary(); + + /// + /// Gets a hash code of the set + /// + public override int GetHashCode() + { + int ret = typeof(TTarget).GetHashCode(); + foreach (KeyValuePair field in ValuesByNumber) + { + // Use ^ here to make the field order irrelevant. + int hash = field.Key.GetHashCode() ^ field.Value.GetHashCode(); + ret ^= hash; + } + return ret; + } + + /// + /// Returns whether this set is equal to the other object + /// + public override bool Equals(object other) + { + if (ReferenceEquals(this, other)) + { + return true; + } + ExtensionSet otherSet = other as ExtensionSet; + if (ValuesByNumber.Count != otherSet.ValuesByNumber.Count) + { + return false; + } + foreach (var pair in ValuesByNumber) + { + IExtensionValue secondValue; + if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue)) + { + return false; + } + if (!pair.Value.Equals(secondValue)) + { + return false; + } + } + return true; + } + + /// + /// Calculates the size of this extension set + /// + public int CalculateSize() + { + int size = 0; + foreach (var value in ValuesByNumber.Values) + { + size += value.CalculateSize(); + } + return size; + } + + /// + /// Writes the extension values in this set to the output stream + /// + public void WriteTo(CodedOutputStream stream) + { + foreach (var value in ValuesByNumber.Values) + { + value.WriteTo(stream); + } + } + } +} diff --git a/csharp/src/Google.Protobuf/ExtensionValue.cs b/csharp/src/Google.Protobuf/ExtensionValue.cs new file mode 100644 index 00000000000..181e88264c5 --- /dev/null +++ b/csharp/src/Google.Protobuf/ExtensionValue.cs @@ -0,0 +1,207 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using Google.Protobuf.Collections; +using System; + +namespace Google.Protobuf +{ + internal interface IExtensionValue : IEquatable, IDeepCloneable + { + void MergeFrom(CodedInputStream input); + void MergeFrom(IExtensionValue value); + void WriteTo(CodedOutputStream output); + int CalculateSize(); + } + + internal sealed class ExtensionValue : IExtensionValue + { + private bool hasValue; + private T field; + private FieldCodec codec; + + internal ExtensionValue(FieldCodec codec) + { + this.codec = codec; + field = codec.DefaultValue; + } + + public int CalculateSize() + { + if (!hasValue) + { + return 0; + } + return codec.CalculateSizeWithTag(field); + } + + public IExtensionValue Clone() + { + return new ExtensionValue(codec) + { + hasValue = hasValue, + field = field is IDeepCloneable ? (field as IDeepCloneable).Clone() : field + }; + } + + public bool Equals(IExtensionValue other) + { + if (ReferenceEquals(this, other)) + return true; + + return other is ExtensionValue + && codec.Equals((other as ExtensionValue).codec) + && hasValue.Equals((other as ExtensionValue).hasValue) + && Equals(field, (other as ExtensionValue).field); + // we check for equality in the codec since we could have equal field values however the values could be written in different ways + } + + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = hash * 31 + hasValue.GetHashCode(); + hash = hash * 31 + field.GetHashCode(); + hash = hash * 31 + codec.GetHashCode(); + return hash; + } + } + + public void MergeFrom(CodedInputStream input) + { + hasValue = true; + codec.ValueMerger(input, ref field); + } + + public void MergeFrom(IExtensionValue value) + { + if (value is ExtensionValue) + { + var extensionValue = value as ExtensionValue; + if (extensionValue.hasValue) + { + hasValue |= codec.FieldMerger(ref field, extensionValue.field); + } + } + } + + public void WriteTo(CodedOutputStream output) + { + if (hasValue) + { + output.WriteTag(codec.Tag); + codec.ValueWriter(output, field); + if (codec.EndTag != 0) + { + output.WriteTag(codec.EndTag); + } + } + } + + public T GetValue() => field; + + public void SetValue(T value) + { + hasValue = true; + field = value; + } + + public bool HasValue => hasValue; + } + + internal sealed class RepeatedExtensionValue : IExtensionValue + { + private RepeatedField field; + private readonly FieldCodec codec; + + internal RepeatedExtensionValue(FieldCodec codec) + { + this.codec = codec; + field = new RepeatedField(); + } + + public int CalculateSize() + { + return field.CalculateSize(codec); + } + + public IExtensionValue Clone() + { + return new RepeatedExtensionValue(codec) + { + field = field.Clone() + }; + } + + public bool Equals(IExtensionValue other) + { + if (ReferenceEquals(this, other)) + return true; + + return other is RepeatedExtensionValue + && field.Equals((other as RepeatedExtensionValue).field) + && codec.Equals((other as RepeatedExtensionValue).codec); + } + + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = hash * 31 + field.GetHashCode(); + hash = hash * 31 + codec.GetHashCode(); + return hash; + } + } + + public void MergeFrom(CodedInputStream input) + { + field.AddEntriesFrom(input, codec); + } + + public void MergeFrom(IExtensionValue value) + { + if (value is RepeatedExtensionValue) + { + field.Add((value as RepeatedExtensionValue).field); + } + } + + public void WriteTo(CodedOutputStream output) + { + field.WriteTo(output, codec); + } + + public RepeatedField GetValue() => field; + } +} diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs index 7044ded93cd..60e64effd40 100644 --- a/csharp/src/Google.Protobuf/FieldCodec.cs +++ b/csharp/src/Google.Protobuf/FieldCodec.cs @@ -49,8 +49,9 @@ public static class FieldCodec /// Retrieves a codec suitable for a string field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForString(uint tag) + public static FieldCodec ForString(uint tag, string defaultValue = "") { return new FieldCodec(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag); } @@ -59,8 +60,9 @@ public static FieldCodec ForString(uint tag) /// Retrieves a codec suitable for a bytes field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForBytes(uint tag) + public static FieldCodec ForBytes(uint tag, ByteString defaultValue = null) { return new FieldCodec(input => input.ReadBytes(), (output, value) => output.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag); } @@ -69,8 +71,9 @@ public static FieldCodec ForBytes(uint tag) /// Retrieves a codec suitable for a bool field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForBool(uint tag) + public static FieldCodec ForBool(uint tag, bool defaultValue = false) { return new FieldCodec(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.BoolSize, tag); } @@ -79,8 +82,9 @@ public static FieldCodec ForBool(uint tag) /// Retrieves a codec suitable for an int32 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForInt32(uint tag) + public static FieldCodec ForInt32(uint tag, int defaultValue = 0) { return new FieldCodec(input => input.ReadInt32(), (output, value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag); } @@ -89,8 +93,9 @@ public static FieldCodec ForInt32(uint tag) /// Retrieves a codec suitable for an sint32 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForSInt32(uint tag) + public static FieldCodec ForSInt32(uint tag, int defaultValue = 0) { return new FieldCodec(input => input.ReadSInt32(), (output, value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag); } @@ -99,8 +104,9 @@ public static FieldCodec ForSInt32(uint tag) /// Retrieves a codec suitable for a fixed32 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForFixed32(uint tag) + public static FieldCodec ForFixed32(uint tag, uint defaultValue = 0) { return new FieldCodec(input => input.ReadFixed32(), (output, value) => output.WriteFixed32(value), 4, tag); } @@ -109,8 +115,9 @@ public static FieldCodec ForFixed32(uint tag) /// Retrieves a codec suitable for an sfixed32 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForSFixed32(uint tag) + public static FieldCodec ForSFixed32(uint tag, int defaultValue = 0) { return new FieldCodec(input => input.ReadSFixed32(), (output, value) => output.WriteSFixed32(value), 4, tag); } @@ -119,8 +126,9 @@ public static FieldCodec ForSFixed32(uint tag) /// Retrieves a codec suitable for a uint32 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForUInt32(uint tag) + public static FieldCodec ForUInt32(uint tag, uint defaultValue = 0) { return new FieldCodec(input => input.ReadUInt32(), (output, value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag); } @@ -129,8 +137,9 @@ public static FieldCodec ForUInt32(uint tag) /// Retrieves a codec suitable for an int64 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForInt64(uint tag) + public static FieldCodec ForInt64(uint tag, long defaultValue = 0) { return new FieldCodec(input => input.ReadInt64(), (output, value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag); } @@ -139,8 +148,9 @@ public static FieldCodec ForInt64(uint tag) /// Retrieves a codec suitable for an sint64 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForSInt64(uint tag) + public static FieldCodec ForSInt64(uint tag, long defaultValue = 0) { return new FieldCodec(input => input.ReadSInt64(), (output, value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag); } @@ -149,8 +159,9 @@ public static FieldCodec ForSInt64(uint tag) /// Retrieves a codec suitable for a fixed64 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForFixed64(uint tag) + public static FieldCodec ForFixed64(uint tag, ulong defaultValue = 0) { return new FieldCodec(input => input.ReadFixed64(), (output, value) => output.WriteFixed64(value), 8, tag); } @@ -159,8 +170,9 @@ public static FieldCodec ForFixed64(uint tag) /// Retrieves a codec suitable for an sfixed64 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForSFixed64(uint tag) + public static FieldCodec ForSFixed64(uint tag, long defaultValue = 0) { return new FieldCodec(input => input.ReadSFixed64(), (output, value) => output.WriteSFixed64(value), 8, tag); } @@ -169,8 +181,9 @@ public static FieldCodec ForSFixed64(uint tag) /// Retrieves a codec suitable for a uint64 field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForUInt64(uint tag) + public static FieldCodec ForUInt64(uint tag, ulong defaultValue = 0) { return new FieldCodec(input => input.ReadUInt64(), (output, value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag); } @@ -179,8 +192,9 @@ public static FieldCodec ForUInt64(uint tag) /// Retrieves a codec suitable for a float field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForFloat(uint tag) + public static FieldCodec ForFloat(uint tag, float defaultValue = 0) { return new FieldCodec(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag); } @@ -189,8 +203,9 @@ public static FieldCodec ForFloat(uint tag) /// Retrieves a codec suitable for a double field with the given tag. /// /// The tag. + /// The default value. /// A codec for the given tag. - public static FieldCodec ForDouble(uint tag) + public static FieldCodec ForDouble(uint tag, double defaultValue = 0) { return new FieldCodec(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag); } @@ -204,8 +219,9 @@ public static FieldCodec ForDouble(uint tag) /// The tag. /// A conversion function from to the enum type. /// A conversion function from the enum type to . + /// The default value. /// A codec for the given tag. - public static FieldCodec ForEnum(uint tag, Func toInt32, Func fromInt32) + public static FieldCodec ForEnum(uint tag, Func toInt32, Func fromInt32, T defaultValue = default(T)) { return new FieldCodec(input => fromInt32( input.ReadEnum()), @@ -219,10 +235,34 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, FuncThe tag. /// A parser to use for the message type. /// A codec for the given tag. - public static FieldCodec ForMessage(uint tag, MessageParser parser) where T : IMessage + public static FieldCodec ForMessage(uint tag, MessageParser parser) where T : class, IMessage { return new FieldCodec(input => { T message = parser.CreateTemplate(); input.ReadMessage(message); return message; }, - (output, value) => output.WriteMessage(value), message => CodedOutputStream.ComputeMessageSize(message), tag); + (output, value) => output.WriteMessage(value), (CodedInputStream i, ref T v) => + { + if (v == null) + { + v = parser.CreateTemplate(); + } + + i.ReadMessage(v); + }, + (ref T v, T v2) => + { + if (v2 == null) + { + return false; + } + else if (v == null) + { + v = v2.Clone(); + } + else + { + v.MergeFrom(v2); + } + return true; + }, message => CodedOutputStream.ComputeMessageSize(message), tag); } /// @@ -232,10 +272,33 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, FuncThe end group tag. /// A parser to use for the group message type. /// A codec for given tag - public static FieldCodec ForGroup(uint startTag, uint endTag, MessageParser parser) where T : IMessage + public static FieldCodec ForGroup(uint startTag, uint endTag, MessageParser parser) where T : class, IMessage { return new FieldCodec(input => { T message = parser.CreateTemplate(); input.ReadGroup(message); return message; }, - (output, value) => output.WriteGroup(value), message => CodedOutputStream.ComputeGroupSize(message), startTag, endTag); + (output, value) => output.WriteGroup(value), (CodedInputStream i, ref T v) => { + if (v == null) + { + v = parser.CreateTemplate(); + } + + i.ReadGroup(v); + }, + (ref T v, T v2) => + { + if (v2 == null) + { + return v == null; + } + else if (v == null) + { + v = v2.Clone(); + } + else + { + v.MergeFrom(v2); + } + return true; + }, message => CodedOutputStream.ComputeGroupSize(message), startTag, endTag); } /// @@ -247,6 +310,8 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func( input => WrapperCodecs.Read(input, nestedCodec), (output, value) => WrapperCodecs.Write(output, value, nestedCodec), + (CodedInputStream i, ref T v) => v = WrapperCodecs.Read(i, nestedCodec), + (ref T v, T v2) => { v = v2; return v == null; }, value => WrapperCodecs.CalculateSize(value, nestedCodec), tag, 0, null); // Default value for the wrapper @@ -262,6 +327,8 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func( input => WrapperCodecs.Read(input, nestedCodec), (output, value) => WrapperCodecs.Write(output, value.Value, nestedCodec), + (CodedInputStream i, ref T? v) => v = WrapperCodecs.Read(i, nestedCodec), + (ref T? v, T? v2) => { if (v2.HasValue) { v = v2; } return v.HasValue; }, value => value == null ? 0 : WrapperCodecs.CalculateSize(value.Value, nestedCodec), tag, 0, null); // Default value for the wrapper @@ -365,6 +432,16 @@ public sealed class FieldCodec // Only non-nullable value types support packing. This is the simplest way of detecting that. private static readonly bool TypeSupportsPacking = default(T) != null; + /// + /// Merges an input stream into a value + /// + internal delegate void InputMerger(CodedInputStream input, ref T value); + + /// + /// Merges a value into a reference to another value, returning a boolean if the value was set + /// + internal delegate bool ValuesMerger(ref T value, T other); + static FieldCodec() { if (typeof(T) == typeof(string)) @@ -399,6 +476,17 @@ static FieldCodec() /// internal Func ValueReader { get; } + /// + /// Returns a delegate to merge a value from a coded input stream. + /// It is assumed that the stream is already positioned on the appropriate tag + /// + internal InputMerger ValueMerger { get; } + + /// + /// Returns a delegate to merge two values together. + /// + internal ValuesMerger FieldMerger { get; } + /// /// Returns the fixed size for an entry, or 0 if sizes vary. /// @@ -446,13 +534,26 @@ static FieldCodec() Action writer, Func sizeCalculator, uint tag, - uint endTag = 0) : this(reader, writer, sizeCalculator, tag, endTag, DefaultDefault) + uint endTag = 0) : this(reader, writer, (CodedInputStream i, ref T v) => v = reader(i), (ref T v, T v2) => { v = v2; return true; }, sizeCalculator, tag, endTag, DefaultDefault) + { + } + + internal FieldCodec( + Func reader, + Action writer, + InputMerger inputMerger, + ValuesMerger valuesMerger, + Func sizeCalculator, + uint tag, + uint endTag = 0) : this(reader, writer, inputMerger, valuesMerger, sizeCalculator, tag, endTag, DefaultDefault) { } internal FieldCodec( Func reader, Action writer, + InputMerger inputMerger, + ValuesMerger valuesMerger, Func sizeCalculator, uint tag, uint endTag, @@ -460,11 +561,15 @@ static FieldCodec() { ValueReader = reader; ValueWriter = writer; + ValueMerger = inputMerger; + FieldMerger = valuesMerger; ValueSizeCalculator = sizeCalculator; FixedSize = 0; Tag = tag; DefaultValue = defaultValue; tagSize = CodedOutputStream.ComputeRawVarint32Size(tag); + if (endTag != 0) + tagSize += CodedOutputStream.ComputeRawVarint32Size(endTag); // Detect packed-ness once, so we can check for it within RepeatedField. PackedRepeatedField = IsPackedRepeatedField(tag); } diff --git a/csharp/src/Google.Protobuf/IExtendableMessage.cs b/csharp/src/Google.Protobuf/IExtendableMessage.cs new file mode 100644 index 00000000000..5cc2ae31a6d --- /dev/null +++ b/csharp/src/Google.Protobuf/IExtendableMessage.cs @@ -0,0 +1,78 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + /// + /// Generic interface for a Protocol Buffers message containing one or more extensions, where the type parameter is expected to be the same type as the implementation class + /// + public interface IExtendableMessage : IMessage where T : IExtendableMessage + { + /// + /// Gets the value of the specified extension + /// + TValue GetExtension(Extension extension); + + /// + /// Gets the value of the specified repeated extension or null if the extension isn't registered in this set. + /// For a version of this method that never returns null, use + /// + RepeatedField GetExtension(RepeatedExtension extension); + + /// + /// Gets the value of the specified repeated extension, registering it if it isn't + /// + RepeatedField GetOrRegisterExtension(RepeatedExtension extension); + + /// + /// Sets the value of the specified extension + /// + void SetExtension(Extension extension, TValue value); + + /// + /// Gets whether the value of the specified extension is set + /// + bool HasExtension(Extension extension); + + /// + /// Clears the value of the specified extension + /// + void ClearExtension(Extension extension); + + /// + /// Clears the value of the specified repeated extension + /// + void ClearExtension(RepeatedExtension extension); + } +} diff --git a/csharp/src/Google.Protobuf/MessageExtensions.cs b/csharp/src/Google.Protobuf/MessageExtensions.cs index 7b13aa7bad7..5ca772f58e8 100644 --- a/csharp/src/Google.Protobuf/MessageExtensions.cs +++ b/csharp/src/Google.Protobuf/MessageExtensions.cs @@ -48,7 +48,7 @@ public static class MessageExtensions /// The message to merge the data into. /// The data to merge, which must be protobuf-encoded binary data. public static void MergeFrom(this IMessage message, byte[] data) => - MergeFrom(message, data, false); + MergeFrom(message, data, false, null); /// /// Merges data from the given byte array slice into an existing message. @@ -58,7 +58,7 @@ public static class MessageExtensions /// The offset of the slice to merge. /// The length of the slice to merge. public static void MergeFrom(this IMessage message, byte[] data, int offset, int length) => - MergeFrom(message, data, offset, length, false); + MergeFrom(message, data, offset, length, false, null); /// /// Merges data from the given byte string into an existing message. @@ -66,7 +66,7 @@ public static class MessageExtensions /// The message to merge the data into. /// The data to merge, which must be protobuf-encoded binary data. public static void MergeFrom(this IMessage message, ByteString data) => - MergeFrom(message, data, false); + MergeFrom(message, data, false, null); /// /// Merges data from the given stream into an existing message. @@ -74,7 +74,7 @@ public static class MessageExtensions /// The message to merge the data into. /// Stream containing the data to merge, which must be protobuf-encoded binary data. public static void MergeFrom(this IMessage message, Stream input) => - MergeFrom(message, input, false); + MergeFrom(message, input, false, null); /// /// Merges length-delimited data from the given stream into an existing message. @@ -86,7 +86,7 @@ public static class MessageExtensions /// The message to merge the data into. /// Stream containing the data to merge, which must be protobuf-encoded binary data. public static void MergeDelimitedFrom(this IMessage message, Stream input) => - MergeDelimitedFrom(message, input, false); + MergeDelimitedFrom(message, input, false, null); /// /// Converts the given message into a byte array in protobuf encoding. @@ -191,53 +191,57 @@ public static bool IsInitialized(this IMessage message) } // Implementations allowing unknown fields to be discarded. - internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields) + internal static void MergeFrom(this IMessage message, byte[] data, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(data, "data"); CodedInputStream input = new CodedInputStream(data); input.DiscardUnknownFields = discardUnknownFields; + input.ExtensionRegistry = registry; message.MergeFrom(input); input.CheckReadEndOfStreamTag(); } - internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields) + internal static void MergeFrom(this IMessage message, byte[] data, int offset, int length, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(data, "data"); CodedInputStream input = new CodedInputStream(data, offset, length); input.DiscardUnknownFields = discardUnknownFields; + input.ExtensionRegistry = registry; message.MergeFrom(input); input.CheckReadEndOfStreamTag(); } - internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields) + internal static void MergeFrom(this IMessage message, ByteString data, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(data, "data"); CodedInputStream input = data.CreateCodedInput(); input.DiscardUnknownFields = discardUnknownFields; + input.ExtensionRegistry = registry; message.MergeFrom(input); input.CheckReadEndOfStreamTag(); } - internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields) + internal static void MergeFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(input, "input"); CodedInputStream codedInput = new CodedInputStream(input); codedInput.DiscardUnknownFields = discardUnknownFields; + codedInput.ExtensionRegistry = registry; message.MergeFrom(codedInput); codedInput.CheckReadEndOfStreamTag(); } - internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields) + internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(input, "input"); int size = (int) CodedInputStream.ReadRawVarint32(input); Stream limitedStream = new LimitedInputStream(input, size); - MergeFrom(message, limitedStream, discardUnknownFields); + MergeFrom(message, limitedStream, discardUnknownFields, registry); } } } diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs index 7e9c9884f4b..76a350ce4c6 100644 --- a/csharp/src/Google.Protobuf/MessageParser.cs +++ b/csharp/src/Google.Protobuf/MessageParser.cs @@ -45,10 +45,13 @@ public class MessageParser // TODO: When we use a C# 7.1 compiler, make this private protected. internal bool DiscardUnknownFields { get; } - internal MessageParser(Func factory, bool discardUnknownFields) + internal ExtensionRegistry Extensions { get; } + + internal MessageParser(Func factory, bool discardUnknownFields, ExtensionRegistry extensions) { this.factory = factory; DiscardUnknownFields = discardUnknownFields; + Extensions = extensions; } /// @@ -68,7 +71,7 @@ internal IMessage CreateTemplate() public IMessage ParseFrom(byte[] data) { IMessage message = factory(); - message.MergeFrom(data, DiscardUnknownFields); + message.MergeFrom(data, DiscardUnknownFields, Extensions); CheckMergedRequiredFields(message); return message; } @@ -83,7 +86,7 @@ public IMessage ParseFrom(byte[] data) public IMessage ParseFrom(byte[] data, int offset, int length) { IMessage message = factory(); - message.MergeFrom(data, offset, length, DiscardUnknownFields); + message.MergeFrom(data, offset, length, DiscardUnknownFields, Extensions); CheckMergedRequiredFields(message); return message; } @@ -96,7 +99,7 @@ public IMessage ParseFrom(byte[] data, int offset, int length) public IMessage ParseFrom(ByteString data) { IMessage message = factory(); - message.MergeFrom(data, DiscardUnknownFields); + message.MergeFrom(data, DiscardUnknownFields, Extensions); CheckMergedRequiredFields(message); return message; } @@ -109,7 +112,7 @@ public IMessage ParseFrom(ByteString data) public IMessage ParseFrom(Stream input) { IMessage message = factory(); - message.MergeFrom(input, DiscardUnknownFields); + message.MergeFrom(input, DiscardUnknownFields, Extensions); CheckMergedRequiredFields(message); return message; } @@ -126,7 +129,7 @@ public IMessage ParseFrom(Stream input) public IMessage ParseDelimitedFrom(Stream input) { IMessage message = factory(); - message.MergeDelimitedFrom(input, DiscardUnknownFields); + message.MergeDelimitedFrom(input, DiscardUnknownFields, Extensions); CheckMergedRequiredFields(message); return message; } @@ -185,7 +188,15 @@ internal static void CheckMergedRequiredFields(IMessage message) /// Whether or not to discard unknown fields when parsing. /// A newly configured message parser. public MessageParser WithDiscardUnknownFields(bool discardUnknownFields) => - new MessageParser(factory, discardUnknownFields); + new MessageParser(factory, discardUnknownFields, Extensions); + + /// + /// Creates a new message parser which registers extensions from the specified registry upon creating the message instance + /// + /// The extensions to register + /// A newly configured message parser. + public MessageParser WithExtensionRegistry(ExtensionRegistry registry) => + new MessageParser(factory, DiscardUnknownFields, registry); } /// @@ -220,11 +231,11 @@ public sealed class MessageParser : MessageParser where T : IMessage /// to require a parameterless constructor: delegates are significantly faster to execute. /// /// Function to invoke when a new, empty message is required. - public MessageParser(Func factory) : this(factory, false) + public MessageParser(Func factory) : this(factory, false, null) { } - internal MessageParser(Func factory, bool discardUnknownFields) : base(() => factory(), discardUnknownFields) + internal MessageParser(Func factory, bool discardUnknownFields, ExtensionRegistry extensions) : base(() => factory(), discardUnknownFields, extensions) { this.factory = factory; } @@ -246,7 +257,7 @@ internal new T CreateTemplate() public new T ParseFrom(byte[] data) { T message = factory(); - message.MergeFrom(data, DiscardUnknownFields); + message.MergeFrom(data, DiscardUnknownFields, Extensions); return message; } @@ -260,7 +271,7 @@ public new T ParseFrom(byte[] data) public new T ParseFrom(byte[] data, int offset, int length) { T message = factory(); - message.MergeFrom(data, offset, length, DiscardUnknownFields); + message.MergeFrom(data, offset, length, DiscardUnknownFields, Extensions); return message; } @@ -272,7 +283,7 @@ public new T ParseFrom(byte[] data, int offset, int length) public new T ParseFrom(ByteString data) { T message = factory(); - message.MergeFrom(data, DiscardUnknownFields); + message.MergeFrom(data, DiscardUnknownFields, Extensions); return message; } @@ -284,7 +295,7 @@ public new T ParseFrom(ByteString data) public new T ParseFrom(Stream input) { T message = factory(); - message.MergeFrom(input, DiscardUnknownFields); + message.MergeFrom(input, DiscardUnknownFields, Extensions); return message; } @@ -300,7 +311,7 @@ public new T ParseFrom(Stream input) public new T ParseDelimitedFrom(Stream input) { T message = factory(); - message.MergeDelimitedFrom(input, DiscardUnknownFields); + message.MergeDelimitedFrom(input, DiscardUnknownFields, Extensions); return message; } @@ -336,6 +347,14 @@ public new T ParseJson(string json) /// Whether or not to discard unknown fields when parsing. /// A newly configured message parser. public new MessageParser WithDiscardUnknownFields(bool discardUnknownFields) => - new MessageParser(factory, discardUnknownFields); + new MessageParser(factory, discardUnknownFields, Extensions); + + /// + /// Creates a new message parser which registers extensions from the specified registry upon creating the message instance + /// + /// The extensions to register + /// A newly configured message parser. + public new MessageParser WithExtensionRegistry(ExtensionRegistry registry) => + new MessageParser(factory, DiscardUnknownFields, registry); } } diff --git a/csharp/src/Google.Protobuf/ObjectIntPair.cs b/csharp/src/Google.Protobuf/ObjectIntPair.cs new file mode 100644 index 00000000000..b98d93a517c --- /dev/null +++ b/csharp/src/Google.Protobuf/ObjectIntPair.cs @@ -0,0 +1,40 @@ +using System; + +namespace Google.Protobuf +{ + /// + /// Struct used to hold the keys for the fieldByNumber table in DescriptorPool and the keys for the + /// extensionByNumber table in ExtensionRegistry. + /// + internal struct ObjectIntPair : IEquatable> where T : class + { + private readonly int number; + private readonly T obj; + + internal ObjectIntPair(T obj, int number) + { + this.number = number; + this.obj = obj; + } + + public bool Equals(ObjectIntPair other) + { + return obj == other.obj + && number == other.number; + } + + public override bool Equals(object obj) + { + if (obj is ObjectIntPair) + { + return Equals((ObjectIntPair)obj); + } + return false; + } + + public override int GetHashCode() + { + return obj.GetHashCode() * ((1 << 16) - 1) + number; + } + } +} diff --git a/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs b/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs index 82e59cdcfa6..57df2ed4a8a 100644 --- a/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs +++ b/csharp/src/Google.Protobuf/Reflection/CustomOptions.cs @@ -30,8 +30,12 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; using System; +using System.Collections; using System.Collections.Generic; +using System.Linq; +using System.Reflection; namespace Google.Protobuf.Reflection { @@ -59,19 +63,13 @@ namespace Google.Protobuf.Reflection /// public sealed class CustomOptions { - /// - /// Singleton for all descriptors with an empty set of options. - /// - internal static readonly CustomOptions Empty = new CustomOptions(); - - /// - /// A sequence of values per field. This needs to be per field rather than per tag to allow correct deserialization - /// of repeated fields which could be "int, ByteString, int" - unlikely as that is. The fact that values are boxed - /// is unfortunate; we might be able to use a struct instead, and we could combine uint and ulong values. - /// - private readonly Dictionary> valuesByField = new Dictionary>(); + private static readonly object[] EmptyParameters = new object[0]; + private readonly IDictionary values; - private CustomOptions() { } + internal CustomOptions(IDictionary values) + { + this.values = values; + } /// /// Retrieves a Boolean value for the specified option field. @@ -79,12 +77,7 @@ public sealed class CustomOptions /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetBool(int field, out bool value) - { - ulong? tmp = GetLastNumericValue(field); - value = tmp == 1UL; - return tmp != null; - } + public bool TryGetBool(int field, out bool value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a signed 32-bit integer value for the specified option field. @@ -92,12 +85,7 @@ public bool TryGetBool(int field, out bool value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetInt32(int field, out int value) - { - ulong? tmp = GetLastNumericValue(field); - value = (int) tmp.GetValueOrDefault(); - return tmp != null; - } + public bool TryGetInt32(int field, out int value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a signed 64-bit integer value for the specified option field. @@ -105,12 +93,7 @@ public bool TryGetInt32(int field, out int value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetInt64(int field, out long value) - { - ulong? tmp = GetLastNumericValue(field); - value = (long) tmp.GetValueOrDefault(); - return tmp != null; - } + public bool TryGetInt64(int field, out long value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves an unsigned 32-bit integer value for the specified option field, @@ -155,12 +138,7 @@ public bool TryGetInt64(int field, out long value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetSInt32(int field, out int value) - { - ulong? tmp = GetLastNumericValue(field); - value = CodedInputStream.DecodeZigZag32((uint) tmp.GetValueOrDefault()); - return tmp != null; - } + public bool TryGetSInt32(int field, out int value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a signed 64-bit integer value for the specified option field, @@ -169,12 +147,7 @@ public bool TryGetSInt32(int field, out int value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetSInt64(int field, out long value) - { - ulong? tmp = GetLastNumericValue(field); - value = CodedInputStream.DecodeZigZag64(tmp.GetValueOrDefault()); - return tmp != null; - } + public bool TryGetSInt64(int field, out long value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves an unsigned 32-bit integer value for the specified option field. @@ -182,12 +155,7 @@ public bool TryGetSInt64(int field, out long value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetUInt32(int field, out uint value) - { - ulong? tmp = GetLastNumericValue(field); - value = (uint) tmp.GetValueOrDefault(); - return tmp != null; - } + public bool TryGetUInt32(int field, out uint value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves an unsigned 64-bit integer value for the specified option field. @@ -195,12 +163,7 @@ public bool TryGetUInt32(int field, out uint value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetUInt64(int field, out ulong value) - { - ulong? tmp = GetLastNumericValue(field); - value = tmp.GetValueOrDefault(); - return tmp != null; - } + public bool TryGetUInt64(int field, out ulong value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a 32-bit floating point value for the specified option field. @@ -208,14 +171,7 @@ public bool TryGetUInt64(int field, out ulong value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetFloat(int field, out float value) - { - ulong? tmp = GetLastNumericValue(field); - int int32 = (int) tmp.GetValueOrDefault(); - byte[] bytes = BitConverter.GetBytes(int32); - value = BitConverter.ToSingle(bytes, 0); - return tmp != null; - } + public bool TryGetFloat(int field, out float value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a 64-bit floating point value for the specified option field. @@ -223,12 +179,7 @@ public bool TryGetFloat(int field, out float value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetDouble(int field, out double value) - { - ulong? tmp = GetLastNumericValue(field); - value = BitConverter.Int64BitsToDouble((long) tmp.GetValueOrDefault()); - return tmp != null; - } + public bool TryGetDouble(int field, out double value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a string value for the specified option field. @@ -236,12 +187,7 @@ public bool TryGetDouble(int field, out double value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetString(int field, out string value) - { - ByteString bytes = GetLastByteStringValue(field); - value = bytes?.ToStringUtf8(); - return bytes != null; - } + public bool TryGetString(int field, out string value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a bytes value for the specified option field. @@ -249,12 +195,7 @@ public bool TryGetString(int field, out string value) /// The field to fetch the value for. /// The output variable to populate. /// true if a suitable value for the field was found; false otherwise. - public bool TryGetBytes(int field, out ByteString value) - { - ByteString bytes = GetLastByteStringValue(field); - value = bytes; - return bytes != null; - } + public bool TryGetBytes(int field, out ByteString value) => TryGetPrimitiveValue(field, out value); /// /// Retrieves a message value for the specified option field. @@ -264,127 +205,106 @@ public bool TryGetBytes(int field, out ByteString value) /// true if a suitable value for the field was found; false otherwise. public bool TryGetMessage(int field, out T value) where T : class, IMessage, new() { - value = null; - List values; - if (!valuesByField.TryGetValue(field, out values)) + if (values == null) { + value = default(T); return false; } - foreach (FieldValue fieldValue in values) - { - if (fieldValue.ByteString != null) - { - if (value == null) - { - value = new T(); - } - value.MergeFrom(fieldValue.ByteString); - } - } - return value != null; - } - private ulong? GetLastNumericValue(int field) - { - List values; - if (!valuesByField.TryGetValue(field, out values)) + IExtensionValue extensionValue; + if (values.TryGetValue(field, out extensionValue)) { - return null; - } - for (int i = values.Count - 1; i >= 0; i--) - { - // A non-bytestring value is a numeric value - if (values[i].ByteString == null) + if (extensionValue is ExtensionValue) { - return values[i].Number; + ExtensionValue single = extensionValue as ExtensionValue; + ByteString bytes = single.GetValue().ToByteString(); + value = new T(); + value.MergeFrom(bytes); + return true; } - } - return null; - } - - private ByteString GetLastByteStringValue(int field) - { - List values; - if (!valuesByField.TryGetValue(field, out values)) - { - return null; - } - for (int i = values.Count - 1; i >= 0; i--) - { - if (values[i].ByteString != null) + else if (extensionValue is RepeatedExtensionValue) { - return values[i].ByteString; + RepeatedExtensionValue repeated = extensionValue as RepeatedExtensionValue; + value = repeated.GetValue() + .Select(v => v.ToByteString()) + .Aggregate(new T(), (t, b) => + { + t.MergeFrom(b); + return t; + }); + return true; } } - return null; - } - /// - /// Reads an unknown field, either parsing it and storing it or skipping it. - /// - /// - /// If the current set of options is empty and we manage to read a field, a new set of options - /// will be created and returned. Otherwise, the return value is this. This allows - /// us to start with a singleton empty set of options and just create new ones where necessary. - /// - /// Input stream to read from. - /// The resulting set of custom options, either this or a new set. - internal CustomOptions ReadOrSkipUnknownField(CodedInputStream input) - { - var tag = input.LastTag; - var field = WireFormat.GetTagFieldNumber(tag); - switch (WireFormat.GetTagWireType(tag)) - { - case WireFormat.WireType.LengthDelimited: - return AddValue(field, new FieldValue(input.ReadBytes())); - case WireFormat.WireType.Fixed32: - return AddValue(field, new FieldValue(input.ReadFixed32())); - case WireFormat.WireType.Fixed64: - return AddValue(field, new FieldValue(input.ReadFixed64())); - case WireFormat.WireType.Varint: - return AddValue(field, new FieldValue(input.ReadRawVarint64())); - // For StartGroup, EndGroup or any wire format we don't understand, - // just use the normal behavior (call SkipLastField). - default: - input.SkipLastField(); - return this; - } + value = null; + return false; } - private CustomOptions AddValue(int field, FieldValue value) + private bool TryGetPrimitiveValue(int field, out T value) { - var ret = valuesByField.Count == 0 ? new CustomOptions() : this; - List valuesForField; - if (!ret.valuesByField.TryGetValue(field, out valuesForField)) + if (values == null) { - // Expect almost all - valuesForField = new List(1); - ret.valuesByField[field] = valuesForField; + value = default(T); + return false; } - valuesForField.Add(value); - return ret; - } - - /// - /// All field values can be stored as a byte string or a 64-bit integer. - /// This struct avoids unnecessary boxing. - /// - private struct FieldValue - { - internal ulong Number { get; } - internal ByteString ByteString { get; } - internal FieldValue(ulong number) + IExtensionValue extensionValue; + if (values.TryGetValue(field, out extensionValue)) { - Number = number; - ByteString = null; + if (extensionValue is ExtensionValue) + { + ExtensionValue single = extensionValue as ExtensionValue; + if (single.HasValue) + { + value = single.GetValue(); + return true; + } + } + else if (extensionValue is RepeatedExtensionValue) + { + RepeatedExtensionValue repeated = extensionValue as RepeatedExtensionValue; + if (repeated.GetValue().Count != 0) + { + RepeatedField repeatedField = repeated.GetValue(); + value = repeatedField[repeatedField.Count - 1]; + return true; + } + } + else // and here we find explicit enum handling since T : Enum ! x is ExtensionValue + { + var type = extensionValue.GetType(); + if (type.GetGenericTypeDefinition() == typeof(ExtensionValue<>)) + { + var typeInfo = type.GetTypeInfo(); + var typeArgs = typeInfo.GenericTypeArguments; + if (typeArgs.Length == 1 && typeArgs[0].GetTypeInfo().IsEnum) + { + if ((bool)typeInfo.GetDeclaredProperty(nameof(ExtensionValue.HasValue)).GetValue(extensionValue)) + { + value = (T)typeInfo.GetDeclaredMethod(nameof(ExtensionValue.GetValue)).Invoke(extensionValue, EmptyParameters); + return true; + } + } + } + else if (type.GetGenericTypeDefinition() == typeof(RepeatedExtensionValue<>)) + { + var typeInfo = type.GetTypeInfo(); + var typeArgs = typeInfo.GenericTypeArguments; + if (typeArgs.Length == 1 && typeArgs[0].GetTypeInfo().IsEnum) + { + var values = (IList)typeInfo.GetDeclaredMethod(nameof(RepeatedExtensionValue.GetValue)).Invoke(extensionValue, EmptyParameters); + if (values.Count != 0) + { + value = (T)values[values.Count - 1]; + return true; + } + } + } + } } - internal FieldValue(ByteString byteString) - { - Number = 0; - ByteString = byteString; - } + value = default(T); + return false; } } } diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index 6f4b5c52a1f..3052f73e07a 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -160,29 +160,29 @@ internal static partial class DescriptorReflection { "AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End", "Options" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange), global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "PhpGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "IdempotencyLevel", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel) }, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null)}), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null)}), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End" }, null, null, null)}) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End", "Options" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options", "ReservedRange", "ReservedName" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange), global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange.Parser, new[]{ "Start", "End" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "PhpGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "IdempotencyLevel", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End" }, null, null, null, null)}) })); } #endregion @@ -1581,9 +1581,10 @@ internal sealed partial class ReservedRange : pb::IMessage { } - internal sealed partial class ExtensionRangeOptions : pb::IMessage { + internal sealed partial class ExtensionRangeOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExtensionRangeOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -1608,6 +1609,7 @@ internal sealed partial class ExtensionRangeOptions : pb::IMessage(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + } /// @@ -3770,9 +3809,10 @@ internal sealed partial class MethodDescriptorProto : pb::IMessage { + internal sealed partial class FileOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -3787,8 +3827,6 @@ internal sealed partial class FileOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FileOptions() { OnConstruction(); @@ -3821,6 +3859,7 @@ internal sealed partial class FileOptions : pb::IMessage { rubyPackage_ = other.rubyPackage_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4442,6 +4481,9 @@ internal sealed partial class FileOptions : pb::IMessage { if (PhpMetadataNamespace != other.PhpMetadataNamespace) return false; if (RubyPackage != other.RubyPackage) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -4469,6 +4511,9 @@ internal sealed partial class FileOptions : pb::IMessage { if (HasPhpMetadataNamespace) hash ^= PhpMetadataNamespace.GetHashCode(); if (HasRubyPackage) hash ^= RubyPackage.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -4563,6 +4608,9 @@ internal sealed partial class FileOptions : pb::IMessage { output.WriteString(RubyPackage); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -4632,6 +4680,9 @@ internal sealed partial class FileOptions : pb::IMessage { size += 2 + pb::CodedOutputStream.ComputeStringSize(RubyPackage); } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -4704,6 +4755,7 @@ internal sealed partial class FileOptions : pb::IMessage { RubyPackage = other.RubyPackage; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -4713,7 +4765,9 @@ internal sealed partial class FileOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 10: { JavaPackage = input.ReadString(); @@ -4803,6 +4857,28 @@ internal sealed partial class FileOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + #region Nested types /// Container for nested types declared in the FileOptions message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4830,9 +4906,10 @@ internal enum OptimizeMode { } - internal sealed partial class MessageOptions : pb::IMessage { + internal sealed partial class MessageOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -4847,8 +4924,6 @@ internal sealed partial class MessageOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public MessageOptions() { OnConstruction(); @@ -4865,6 +4940,7 @@ internal sealed partial class MessageOptions : pb::IMessage { mapEntry_ = other.mapEntry_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5053,6 +5129,9 @@ internal sealed partial class MessageOptions : pb::IMessage { if (Deprecated != other.Deprecated) return false; if (MapEntry != other.MapEntry) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -5064,6 +5143,9 @@ internal sealed partial class MessageOptions : pb::IMessage { if (HasDeprecated) hash ^= Deprecated.GetHashCode(); if (HasMapEntry) hash ^= MapEntry.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -5094,6 +5176,9 @@ internal sealed partial class MessageOptions : pb::IMessage { output.WriteBool(MapEntry); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -5115,6 +5200,9 @@ internal sealed partial class MessageOptions : pb::IMessage { size += 1 + 1; } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -5139,6 +5227,7 @@ internal sealed partial class MessageOptions : pb::IMessage { MapEntry = other.MapEntry; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -5148,7 +5237,9 @@ internal sealed partial class MessageOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 8: { MessageSetWireFormat = input.ReadBool(); @@ -5174,11 +5265,34 @@ internal sealed partial class MessageOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + } - internal sealed partial class FieldOptions : pb::IMessage { + internal sealed partial class FieldOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FieldOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -5193,8 +5307,6 @@ internal sealed partial class FieldOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public FieldOptions() { OnConstruction(); @@ -5213,6 +5325,7 @@ internal sealed partial class FieldOptions : pb::IMessage { weak_ = other.weak_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5461,6 +5574,9 @@ internal sealed partial class FieldOptions : pb::IMessage { if (Deprecated != other.Deprecated) return false; if (Weak != other.Weak) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -5474,6 +5590,9 @@ internal sealed partial class FieldOptions : pb::IMessage { if (HasDeprecated) hash ^= Deprecated.GetHashCode(); if (HasWeak) hash ^= Weak.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -5512,6 +5631,9 @@ internal sealed partial class FieldOptions : pb::IMessage { output.WriteBool(Weak); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -5539,6 +5661,9 @@ internal sealed partial class FieldOptions : pb::IMessage { size += 1 + 1; } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -5569,6 +5694,7 @@ internal sealed partial class FieldOptions : pb::IMessage { Weak = other.Weak; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -5578,7 +5704,9 @@ internal sealed partial class FieldOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 8: { Ctype = (global::Google.Protobuf.Reflection.FieldOptions.Types.CType) input.ReadEnum(); @@ -5612,6 +5740,28 @@ internal sealed partial class FieldOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + #region Nested types /// Container for nested types declared in the FieldOptions message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5645,9 +5795,10 @@ internal enum JSType { } - internal sealed partial class OneofOptions : pb::IMessage { + internal sealed partial class OneofOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneofOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -5661,8 +5812,6 @@ internal sealed partial class OneofOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public OneofOptions() { OnConstruction(); @@ -5674,6 +5823,7 @@ internal sealed partial class OneofOptions : pb::IMessage { public OneofOptions(OneofOptions other) : this() { uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5708,6 +5858,9 @@ internal sealed partial class OneofOptions : pb::IMessage { return true; } if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -5715,6 +5868,9 @@ internal sealed partial class OneofOptions : pb::IMessage { public override int GetHashCode() { int hash = 1; hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -5729,6 +5885,9 @@ internal sealed partial class OneofOptions : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -5738,6 +5897,9 @@ internal sealed partial class OneofOptions : pb::IMessage { public int CalculateSize() { int size = 0; size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -5750,6 +5912,7 @@ internal sealed partial class OneofOptions : pb::IMessage { return; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -5759,7 +5922,9 @@ internal sealed partial class OneofOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 7994: { uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); @@ -5769,11 +5934,34 @@ internal sealed partial class OneofOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + } - internal sealed partial class EnumOptions : pb::IMessage { + internal sealed partial class EnumOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -5788,8 +5976,6 @@ internal sealed partial class EnumOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EnumOptions() { OnConstruction(); @@ -5804,6 +5990,7 @@ internal sealed partial class EnumOptions : pb::IMessage { deprecated_ = other.deprecated_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5898,6 +6085,9 @@ internal sealed partial class EnumOptions : pb::IMessage { if (AllowAlias != other.AllowAlias) return false; if (Deprecated != other.Deprecated) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -5907,6 +6097,9 @@ internal sealed partial class EnumOptions : pb::IMessage { if (HasAllowAlias) hash ^= AllowAlias.GetHashCode(); if (HasDeprecated) hash ^= Deprecated.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -5929,6 +6122,9 @@ internal sealed partial class EnumOptions : pb::IMessage { output.WriteBool(Deprecated); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -5944,6 +6140,9 @@ internal sealed partial class EnumOptions : pb::IMessage { size += 1 + 1; } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -5962,6 +6161,7 @@ internal sealed partial class EnumOptions : pb::IMessage { Deprecated = other.Deprecated; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -5971,7 +6171,9 @@ internal sealed partial class EnumOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 16: { AllowAlias = input.ReadBool(); @@ -5989,11 +6191,34 @@ internal sealed partial class EnumOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + } - internal sealed partial class EnumValueOptions : pb::IMessage { + internal sealed partial class EnumValueOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumValueOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -6008,8 +6233,6 @@ internal sealed partial class EnumValueOptions : pb::IMessage get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public EnumValueOptions() { OnConstruction(); @@ -6023,6 +6246,7 @@ internal sealed partial class EnumValueOptions : pb::IMessage deprecated_ = other.deprecated_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6088,6 +6312,9 @@ internal sealed partial class EnumValueOptions : pb::IMessage } if (Deprecated != other.Deprecated) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -6096,6 +6323,9 @@ internal sealed partial class EnumValueOptions : pb::IMessage int hash = 1; if (HasDeprecated) hash ^= Deprecated.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -6114,6 +6344,9 @@ internal sealed partial class EnumValueOptions : pb::IMessage output.WriteBool(Deprecated); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -6126,6 +6359,9 @@ internal sealed partial class EnumValueOptions : pb::IMessage size += 1 + 1; } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -6141,6 +6377,7 @@ internal sealed partial class EnumValueOptions : pb::IMessage Deprecated = other.Deprecated; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -6150,7 +6387,9 @@ internal sealed partial class EnumValueOptions : pb::IMessage while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 8: { Deprecated = input.ReadBool(); @@ -6164,11 +6403,34 @@ internal sealed partial class EnumValueOptions : pb::IMessage } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + } - internal sealed partial class ServiceOptions : pb::IMessage { + internal sealed partial class ServiceOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServiceOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -6183,8 +6445,6 @@ internal sealed partial class ServiceOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public ServiceOptions() { OnConstruction(); @@ -6198,6 +6458,7 @@ internal sealed partial class ServiceOptions : pb::IMessage { deprecated_ = other.deprecated_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6263,6 +6524,9 @@ internal sealed partial class ServiceOptions : pb::IMessage { } if (Deprecated != other.Deprecated) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -6271,6 +6535,9 @@ internal sealed partial class ServiceOptions : pb::IMessage { int hash = 1; if (HasDeprecated) hash ^= Deprecated.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -6289,6 +6556,9 @@ internal sealed partial class ServiceOptions : pb::IMessage { output.WriteBool(Deprecated); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -6301,6 +6571,9 @@ internal sealed partial class ServiceOptions : pb::IMessage { size += 2 + 1; } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -6316,6 +6589,7 @@ internal sealed partial class ServiceOptions : pb::IMessage { Deprecated = other.Deprecated; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -6325,7 +6599,9 @@ internal sealed partial class ServiceOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 264: { Deprecated = input.ReadBool(); @@ -6339,11 +6615,34 @@ internal sealed partial class ServiceOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + } - internal sealed partial class MethodOptions : pb::IMessage { + internal sealed partial class MethodOptions : pb::IExtendableMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MethodOptions()); private pb::UnknownFieldSet _unknownFields; + internal pb::ExtensionSet _extensions; private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -6358,8 +6657,6 @@ internal sealed partial class MethodOptions : pb::IMessage { get { return Descriptor; } } - internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public MethodOptions() { OnConstruction(); @@ -6374,6 +6671,7 @@ internal sealed partial class MethodOptions : pb::IMessage { idempotencyLevel_ = other.idempotencyLevel_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6464,6 +6762,9 @@ internal sealed partial class MethodOptions : pb::IMessage { if (Deprecated != other.Deprecated) return false; if (IdempotencyLevel != other.IdempotencyLevel) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } return Equals(_unknownFields, other._unknownFields); } @@ -6473,6 +6774,9 @@ internal sealed partial class MethodOptions : pb::IMessage { if (HasDeprecated) hash ^= Deprecated.GetHashCode(); if (HasIdempotencyLevel) hash ^= IdempotencyLevel.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -6495,6 +6799,9 @@ internal sealed partial class MethodOptions : pb::IMessage { output.WriteEnum((int) IdempotencyLevel); } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(output); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -6510,6 +6817,9 @@ internal sealed partial class MethodOptions : pb::IMessage { size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) IdempotencyLevel); } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + if (_extensions != null) { + size += _extensions.CalculateSize(); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -6528,6 +6838,7 @@ internal sealed partial class MethodOptions : pb::IMessage { IdempotencyLevel = other.IdempotencyLevel; } uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -6537,7 +6848,9 @@ internal sealed partial class MethodOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - CustomOptions = CustomOptions.ReadOrSkipUnknownField(input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } break; case 264: { Deprecated = input.ReadBool(); @@ -6555,6 +6868,28 @@ internal sealed partial class MethodOptions : pb::IMessage { } } + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrRegister(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + #region Nested types /// Container for nested types declared in the MethodOptions message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] diff --git a/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs b/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs index 9c2160feed1..93f2fa9a4ae 100644 --- a/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs +++ b/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs @@ -45,11 +45,11 @@ internal sealed class DescriptorPool private readonly IDictionary descriptorsByName = new Dictionary(); - private readonly IDictionary fieldsByNumber = - new Dictionary(); + private readonly IDictionary, FieldDescriptor> fieldsByNumber = + new Dictionary, FieldDescriptor>(); - private readonly IDictionary enumValuesByNumber = - new Dictionary(); + private readonly IDictionary, EnumValueDescriptor> enumValuesByNumber = + new Dictionary, EnumValueDescriptor>(); private readonly HashSet dependencies; @@ -209,14 +209,14 @@ private static void ValidateSymbolName(IDescriptor descriptor) internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number) { FieldDescriptor ret; - fieldsByNumber.TryGetValue(new DescriptorIntPair(messageDescriptor, number), out ret); + fieldsByNumber.TryGetValue(new ObjectIntPair(messageDescriptor, number), out ret); return ret; } internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number) { EnumValueDescriptor ret; - enumValuesByNumber.TryGetValue(new DescriptorIntPair(enumDescriptor, number), out ret); + enumValuesByNumber.TryGetValue(new ObjectIntPair(enumDescriptor, number), out ret); return ret; } @@ -227,7 +227,8 @@ internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor /// containing type and number already exists. internal void AddFieldByNumber(FieldDescriptor field) { - DescriptorIntPair key = new DescriptorIntPair(field.ContainingType, field.FieldNumber); + // for extensions, we use the extended type, otherwise we use the containing type + ObjectIntPair key = new ObjectIntPair(field.Proto.HasExtendee ? field.ExtendeeType : field.ContainingType, field.FieldNumber); FieldDescriptor old; if (fieldsByNumber.TryGetValue(key, out old)) { @@ -246,7 +247,7 @@ internal void AddFieldByNumber(FieldDescriptor field) /// internal void AddEnumValueByNumber(EnumValueDescriptor enumValue) { - DescriptorIntPair key = new DescriptorIntPair(enumValue.EnumDescriptor, enumValue.Number); + ObjectIntPair key = new ObjectIntPair(enumValue.EnumDescriptor, enumValue.Number); if (!enumValuesByNumber.ContainsKey(key)) { enumValuesByNumber[key] = enumValue; @@ -329,40 +330,5 @@ internal IDescriptor LookupSymbol(string name, IDescriptor relativeTo) return result; } } - - /// - /// Struct used to hold the keys for the fieldByNumber table. - /// - private struct DescriptorIntPair : IEquatable - { - private readonly int number; - private readonly IDescriptor descriptor; - - internal DescriptorIntPair(IDescriptor descriptor, int number) - { - this.number = number; - this.descriptor = descriptor; - } - - public bool Equals(DescriptorIntPair other) - { - return descriptor == other.descriptor - && number == other.number; - } - - public override bool Equals(object obj) - { - if (obj is DescriptorIntPair) - { - return Equals((DescriptorIntPair) obj); - } - return false; - } - - public override int GetHashCode() - { - return descriptor.GetHashCode()*((1 << 16) - 1) + number; - } - } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs index 4c5457a70c7..36a1d0a5ecd 100644 --- a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs @@ -30,6 +30,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; using System; using System.Collections.Generic; @@ -127,6 +128,26 @@ public EnumValueDescriptor FindValueByName(string name) /// /// The (possibly empty) set of custom options for this enum. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs index 8a14b87b7ee..99c989130c8 100644 --- a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs @@ -30,6 +30,9 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; +using System; + namespace Google.Protobuf.Reflection { /// @@ -70,6 +73,27 @@ public sealed class EnumValueDescriptor : DescriptorBase /// /// The (possibly empty) set of custom options for this enum value. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ } -} \ No newline at end of file +} + \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Reflection/ExtensionAccessor.cs b/csharp/src/Google.Protobuf/Reflection/ExtensionAccessor.cs new file mode 100644 index 00000000000..81d6e35f013 --- /dev/null +++ b/csharp/src/Google.Protobuf/Reflection/ExtensionAccessor.cs @@ -0,0 +1,69 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +namespace Google.Protobuf.Reflection +{ + internal sealed class ExtensionAccessor : IFieldAccessor + { + private readonly Extension extension; + private readonly ReflectionUtil.IExtensionReflectionHelper helper; + + internal ExtensionAccessor(FieldDescriptor descriptor) + { + Descriptor = descriptor; + extension = descriptor.Extension; + helper = ReflectionUtil.CreateExtensionHelper(extension); + } + + public FieldDescriptor Descriptor { get; } + + public void Clear(IMessage message) + { + helper.ClearExtension(message); + } + + public bool HasValue(IMessage message) + { + return helper.HasExtension(message); + } + + public object GetValue(IMessage message) + { + return helper.GetExtension(message); + } + + public void SetValue(IMessage message, object value) + { + helper.SetExtension(message, value); + } + } +} diff --git a/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs b/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs new file mode 100644 index 00000000000..5ed4b53164d --- /dev/null +++ b/csharp/src/Google.Protobuf/Reflection/ExtensionCollection.cs @@ -0,0 +1,110 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace Google.Protobuf.Reflection +{ + /// + /// A collection to simplify retrieving the descriptors of extensions in a descriptor for a message + /// + public class ExtensionCollection + { + private readonly FileDescriptor file; + private readonly MessageDescriptor message; + + private IDictionary> extensionsByTypeInDeclarationOrder; + private IDictionary> extensionsByTypeInNumberOrder; + + internal ExtensionCollection(FileDescriptor file, Extension[] extensions) + { + this.file = file; + UnorderedExtensions = DescriptorUtil.ConvertAndMakeReadOnly( + file.Proto.Extension, + (extension, i) => new FieldDescriptor(extension, file, null, i, null, extensions?[i])); + } + + internal ExtensionCollection(MessageDescriptor message, Extension[] extensions) + { + this.message = message; + UnorderedExtensions = DescriptorUtil.ConvertAndMakeReadOnly( + message.Proto.Extension, + (extension, i) => new FieldDescriptor(extension, message.File, message, i, null, extensions?[i])); + } + + /// + /// Returns a readonly list of all the extensions defined in this type in + /// the order they were defined in the source .proto file + /// + public IList UnorderedExtensions { get; } + + /// + /// Returns a readonly list of all the extensions define in this type that extend + /// the provided descriptor type in the order they were defined in the source .proto file + /// + public IList GetExtensionsInDeclarationOrder(MessageDescriptor descriptor) + { + return extensionsByTypeInDeclarationOrder[descriptor]; + } + + /// + /// Returns a readonly list of all the extensions define in this type that extend + /// the provided descriptor type in accending field order + /// + public IList GetExtensionsInNumberOrder(MessageDescriptor descriptor) + { + return extensionsByTypeInNumberOrder[descriptor]; + } + + internal void CrossLink() + { + Dictionary> declarationOrder = new Dictionary>(); + foreach (FieldDescriptor descriptor in UnorderedExtensions) + { + descriptor.CrossLink(); + + IList _; + if (!declarationOrder.TryGetValue(descriptor.ExtendeeType, out _)) + declarationOrder.Add(descriptor.ExtendeeType, new List()); + + declarationOrder[descriptor.ExtendeeType].Add(descriptor); + } + + extensionsByTypeInDeclarationOrder = declarationOrder + .ToDictionary(kvp => kvp.Key, kvp => (IList)new ReadOnlyCollection(kvp.Value)); + extensionsByTypeInNumberOrder = declarationOrder + .ToDictionary(kvp => kvp.Key, kvp => (IList)new ReadOnlyCollection(kvp.Value.OrderBy(field => field.FieldNumber).ToArray())); + } + } +} diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs index 5ad192ebfc2..5a2f7f3d8e1 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs @@ -30,6 +30,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; using Google.Protobuf.Compatibility; using System; @@ -41,13 +42,14 @@ namespace Google.Protobuf.Reflection public sealed class FieldDescriptor : DescriptorBase, IComparable { private EnumDescriptor enumType; + private MessageDescriptor extendeeType; private MessageDescriptor messageType; private FieldType fieldType; private readonly string propertyName; // Annoyingly, needed in Crosslink. private IFieldAccessor accessor; /// - /// Get the field's containing message type. + /// Get the field's containing message type, or null if it is a field defined at the top level of a file as an extension. /// public MessageDescriptor ContainingType { get; } @@ -64,8 +66,10 @@ public sealed class FieldDescriptor : DescriptorBase, IComparable public bool IsRepeated => Proto.Label == FieldDescriptorProto.Types.Label.Repeated; - /// - /// Returns true if this field is a required field; false otherwise. + /// + /// Returns true if this field is a required field; false otherwise. /// public bool IsRequired => Proto.Label == FieldDescriptorProto.Types.Label.Required; @@ -196,8 +201,8 @@ private static FieldType GetFieldTypeFromProtoType(FieldDescriptorProto.Types.Ty /// /// Returns true if this field is a packed, repeated field; false otherwise. /// - public bool IsPacked => File.Proto.Syntax == "proto2" ? Proto.Options?.Packed ?? false : !Proto.Options.HasPacked || Proto.Options.Packed; - + public bool IsPacked => File.Proto.Syntax == "proto2" ? Proto.Options?.Packed ?? false : !Proto.Options.HasPacked || Proto.Options.Packed; + /// /// Returns the type of the field. /// @@ -254,10 +259,45 @@ public MessageDescriptor MessageType } } + /// + /// For extension fields, returns the extended type + /// + public MessageDescriptor ExtendeeType + { + get + { + if (!Proto.HasExtendee) + { + throw new InvalidOperationException("ExtendeeType is only valid for extension fields."); + } + return extendeeType; + } + } + /// /// The (possibly empty) set of custom options for this field. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ /// /// Look up and cross-link all field types etc. @@ -320,6 +360,11 @@ internal void CrossLink() } } + if (Proto.HasExtendee) + { + extendeeType = File.DescriptorPool.LookupSymbol(Proto.Extendee, this) as MessageDescriptor; + } + // Note: no attempt to perform any default value parsing File.DescriptorPool.AddFieldByNumber(this); @@ -340,6 +385,11 @@ private IFieldAccessor CreateAccessor() { return null; } + + if (Extension != null) + { + return new ExtensionAccessor(this); + } var property = ContainingType.ClrType.GetProperty(propertyName); if (property == null) { @@ -350,4 +400,5 @@ private IFieldAccessor CreateAccessor() : (IFieldAccessor) new SingleFieldAccessor(property, this); } } -} \ No newline at end of file +} + \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs index 992b792adaf..4c2fe54d560 100644 --- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs @@ -30,6 +30,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; using Google.Protobuf.WellKnownTypes; using System; using System.Collections.Generic; @@ -83,6 +84,8 @@ private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, IEn (service, index) => new ServiceDescriptor(service, this, index)); + Extensions = new ExtensionCollection(this, generatedCodeInfo?.Extensions); + declarations = new Lazy>(CreateDeclarationMap, LazyThreadSafetyMode.ExecutionAndPublication); } @@ -240,6 +243,11 @@ private static IList DeterminePublicDependencies(FileDescriptor /// public IList Services { get; } + /// + /// Unmodifiable list of top-level extensions declared in this file. + /// + public ExtensionCollection Extensions { get; } + /// /// Unmodifiable list of this file's dependencies (imports). /// @@ -356,6 +364,8 @@ private void CrossLink() { service.CrossLink(); } + + Extensions.CrossLink(); } /// @@ -371,10 +381,12 @@ private void CrossLink() FileDescriptor[] dependencies, GeneratedClrTypeInfo generatedCodeInfo) { + ExtensionRegistry registry = new ExtensionRegistry(); + AddAllExtensions(dependencies, generatedCodeInfo, registry); FileDescriptorProto proto; try { - proto = FileDescriptorProto.Parser.ParseFrom(descriptorData); + proto = FileDescriptorProto.Parser.WithExtensionRegistry(registry).ParseFrom(descriptorData); } catch (InvalidProtocolBufferException e) { @@ -393,6 +405,31 @@ private void CrossLink() } } + private static void AddAllExtensions(FileDescriptor[] dependencies, GeneratedClrTypeInfo generatedInfo, ExtensionRegistry registry) + { + registry.Add(dependencies.SelectMany(GetAllDependedExtensions).Concat(GetAllGeneratedExtensions(generatedInfo)).ToArray()); + } + + private static IEnumerable GetAllGeneratedExtensions(GeneratedClrTypeInfo generated) + { + return generated.Extensions.Concat(generated.NestedTypes.Where(t => t != null).SelectMany(GetAllGeneratedExtensions)); + } + + private static IEnumerable GetAllDependedExtensions(FileDescriptor descriptor) + { + return descriptor.Extensions.UnorderedExtensions + .Select(s => s.Extension) + .Concat(descriptor.Dependencies.Concat(descriptor.PublicDependencies).SelectMany(GetAllDependedExtensions)) + .Concat(descriptor.MessageTypes.SelectMany(GetAllDependedExtensionsFromMessage)); + } + + private static IEnumerable GetAllDependedExtensionsFromMessage(MessageDescriptor descriptor) + { + return descriptor.Extensions.UnorderedExtensions + .Select(s => s.Extension) + .Concat(descriptor.NestedTypes.SelectMany(GetAllDependedExtensionsFromMessage)); + } + /// /// Converts the given descriptor binary data into FileDescriptor objects. /// Note: reflection using the returned FileDescriptors is not currently supported. @@ -467,7 +504,27 @@ public override string ToString() /// /// The (possibly empty) set of custom options for this file. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ /// /// Performs initialization for the given generic type argument. diff --git a/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs index fe5db65656f..479e177130f 100644 --- a/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs +++ b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs @@ -42,6 +42,7 @@ public sealed class GeneratedClrTypeInfo { private static readonly string[] EmptyNames = new string[0]; private static readonly GeneratedClrTypeInfo[] EmptyCodeInfo = new GeneratedClrTypeInfo[0]; + private static readonly Extension[] EmptyExtensions = new Extension[0]; /// /// Irrelevant for file descriptors; the CLR type for the message for message descriptors. @@ -59,6 +60,11 @@ public sealed class GeneratedClrTypeInfo /// public string[] PropertyNames { get; } + /// + /// The extensions defined within this file/message descriptor + /// + public Extension[] Extensions { get; } + /// /// Irrelevant for file descriptors; the CLR property "base" names (in message descriptor oneof order) /// for oneofs in the message for message descriptors. It is expected that for a oneof name of "Foo", @@ -82,16 +88,35 @@ public sealed class GeneratedClrTypeInfo /// Each array parameter may be null, to indicate a lack of values. /// The parameter order is designed to make it feasible to format the generated code readably. /// - public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes) + public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, Extension[] extensions, GeneratedClrTypeInfo[] nestedTypes) { NestedTypes = nestedTypes ?? EmptyCodeInfo; NestedEnums = nestedEnums ?? ReflectionUtil.EmptyTypes; ClrType = clrType; + Extensions = extensions ?? EmptyExtensions; Parser = parser; PropertyNames = propertyNames ?? EmptyNames; OneofNames = oneofNames ?? EmptyNames; } + /// + /// Creates a GeneratedClrTypeInfo for a message descriptor, with nested types, nested enums, the CLR type, property names and oneof names. + /// Each array parameter may be null, to indicate a lack of values. + /// The parameter order is designed to make it feasible to format the generated code readably. + /// + public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes) + : this(clrType, parser, propertyNames, oneofNames, nestedEnums, null, nestedTypes) + { + } + + /// + /// Creates a GeneratedClrTypeInfo for a file descriptor, with only types, enums, and extensions. + /// + public GeneratedClrTypeInfo(Type[] nestedEnums, Extension[] extensions, GeneratedClrTypeInfo[] nestedTypes) + : this(null, null, null, null, nestedEnums, extensions, nestedTypes) + { + } + /// /// Creates a GeneratedClrTypeInfo for a file descriptor, with only types and enums. /// diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs index 68722d4d931..15bfbfadd04 100644 --- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs @@ -88,10 +88,12 @@ internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDe (type, index) => new EnumDescriptor(type, file, this, index, generatedCodeInfo?.NestedEnums[index])); + Extensions = new ExtensionCollection(this, generatedCodeInfo?.Extensions); + fieldsInDeclarationOrder = DescriptorUtil.ConvertAndMakeReadOnly( proto.Field, (field, index) => - new FieldDescriptor(field, file, this, index, generatedCodeInfo?.PropertyNames[index])); + new FieldDescriptor(field, file, this, index, generatedCodeInfo?.PropertyNames[index], null)); fieldsInNumberOrder = new ReadOnlyCollection(fieldsInDeclarationOrder.OrderBy(field => field.FieldNumber).ToArray()); // TODO: Use field => field.Proto.JsonName when we're confident it's appropriate. (And then use it in the formatter, too.) jsonFieldMap = CreateJsonFieldMap(fieldsInNumberOrder); @@ -195,6 +197,11 @@ internal override IReadOnlyList GetNestedDescriptorListForField( /// public FieldCollection Fields { get; } + /// + /// An unmodifiable list of extensions defined in this message's scrope + /// + public ExtensionCollection Extensions { get; } + /// /// An unmodifiable list of this message type's nested types. /// @@ -236,7 +243,27 @@ internal override IReadOnlyList GetNestedDescriptorListForField( /// /// The (possibly empty) set of custom options for this message. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public Collections.RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ /// /// Looks up and cross-links all fields and nested types. @@ -257,6 +284,8 @@ internal void CrossLink() { oneof.CrossLink(); } + + Extensions.CrossLink(); } /// diff --git a/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs index 19d7f8a0925..1b37d9b1722 100644 --- a/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs @@ -30,6 +30,9 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; +using System; + namespace Google.Protobuf.Reflection { /// @@ -70,7 +73,27 @@ public sealed class MethodDescriptor : DescriptorBase /// /// The (possibly empty) set of custom options for this method. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ internal MethodDescriptor(MethodDescriptorProto proto, FileDescriptor file, ServiceDescriptor parent, int index) @@ -105,4 +128,5 @@ internal void CrossLink() outputType = (MessageDescriptor) lookup; } } -} \ No newline at end of file +} + \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs index c026bea6775..9f3d805d05b 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs @@ -30,8 +30,10 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using Google.Protobuf.Collections; using Google.Protobuf.Compatibility; namespace Google.Protobuf.Reflection @@ -103,7 +105,27 @@ public MessageDescriptor ContainingType /// /// The (possibly empty) set of custom options for this oneof. /// - public CustomOptions CustomOptions => proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return proto.Options.GetExtension(extension).Clone(); + } + */ internal void CrossLink() { diff --git a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs index b22e8d1297c..ca9c808343b 100644 --- a/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs +++ b/csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs @@ -115,6 +115,13 @@ static ReflectionUtil() internal static Func CreateFuncIMessageBool(MethodInfo method) => GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageBool(method); + /// + /// Creates a delegate which will execute the given method after casting the first argument to + /// the type that declares the method, and the second argument to the first parameter type of the method. + /// + internal static IExtensionReflectionHelper CreateExtensionHelper(Extension extension) => + (IExtensionReflectionHelper)Activator.CreateInstance(typeof(ExtensionReflectionHelper<,>).MakeGenericType(extension.TargetType, extension.GetType().GenericTypeArguments[1])); + /// /// Creates a reflection helper for the given type arguments. Currently these are created on demand /// rather than cached; this will be "busy" when initially loading a message's descriptor, but after that @@ -135,6 +142,14 @@ private interface IReflectionHelper Func CreateFuncIMessageBool(MethodInfo method); } + internal interface IExtensionReflectionHelper + { + object GetExtension(IMessage message); + void SetExtension(IMessage message, object value); + bool HasExtension(IMessage message); + void ClearExtension(IMessage message); + } + private class ReflectionHelper : IReflectionHelper { @@ -182,6 +197,109 @@ public Action CreateActionIMessage(MethodInfo method) } } + private class ExtensionReflectionHelper : IExtensionReflectionHelper + where T1 : IExtendableMessage + { + private readonly Extension extension; + + public ExtensionReflectionHelper(Extension extension) + { + this.extension = extension; + } + + public object GetExtension(IMessage message) + { + if (!(message is T1)) + { + throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); + } + + T1 extensionMessage = (T1)message; + + if (extension is Extension) + { + return extensionMessage.GetExtension(extension as Extension); + } + else if (extension is RepeatedExtension) + { + return extensionMessage.GetExtension(extension as RepeatedExtension); + } + else + { + throw new InvalidCastException("The provided extension is not a valid extension identifier type"); + } + } + + public bool HasExtension(IMessage message) + { + if (!(message is T1)) + { + throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); + } + + T1 extensionMessage = (T1)message; + + if (extension is Extension) + { + return extensionMessage.HasExtension(extension as Extension); + } + else if (extension is RepeatedExtension) + { + throw new InvalidOperationException("HasValue is not implemented for repeated extensions"); + } + else + { + throw new InvalidCastException("The provided extension is not a valid extension identifier type"); + } + } + + public void SetExtension(IMessage message, object value) + { + if (!(message is T1)) + { + throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); + } + + T1 extensionMessage = (T1)message; + + if (extension is Extension) + { + extensionMessage.SetExtension(extension as Extension, (T3)value); + } + else if (extension is RepeatedExtension) + { + throw new InvalidOperationException("SetValue is not implemented for repeated extensions"); + } + else + { + throw new InvalidCastException("The provided extension is not a valid extension identifier type"); + } + } + + public void ClearExtension(IMessage message) + { + if (!(message is T1)) + { + throw new InvalidCastException("Cannot access extension on message that isn't IExtensionMessage"); + } + + T1 extensionMessage = (T1)message; + + if (extension is Extension) + { + extensionMessage.ClearExtension(extension as Extension); + } + else if (extension is RepeatedExtension) + { + extensionMessage.GetExtension(extension as RepeatedExtension).Clear(); + } + else + { + throw new InvalidCastException("The provided extension is not a valid extension identifier type"); + } + } + } + // Runtime compatibility checking code - see ReflectionHelper.CreateFuncIMessageInt32 for // details about why we're doing this. diff --git a/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs index da57055118a..54f4df7298a 100644 --- a/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs @@ -30,6 +30,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using Google.Protobuf.Collections; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -93,7 +94,27 @@ public MethodDescriptor FindMethodByName(String name) /// /// The (possibly empty) set of custom options for this service. /// - public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty; + //[Obsolete("CustomOptions are obsolete. Use GetOption")] + public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber); + + /* // uncomment this in the full proto2 support PR + /// + /// Gets a single value enum option for this descriptor + /// + public T GetOption(Extension extension) + { + var value = Proto.Options.GetExtension(extension); + return value is IDeepCloneable clonable ? clonable.Clone() : value; + } + + /// + /// Gets a repeated value enum option for this descriptor + /// + public RepeatedField GetOption(RepeatedExtension extension) + { + return Proto.Options.GetExtension(extension).Clone(); + } + */ internal void CrossLink() { @@ -103,4 +124,5 @@ internal void CrossLink() } } } -} \ No newline at end of file +} + \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs index dd9911067ed..09e0e29f0de 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs @@ -31,8 +31,8 @@ public static partial class AnyReflection { "dWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), global::Google.Protobuf.WellKnownTypes.Any.Parser, new[]{ "TypeUrl", "Value" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), global::Google.Protobuf.WellKnownTypes.Any.Parser, new[]{ "TypeUrl", "Value" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs index 438e1db8da2..06a99059194 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs @@ -43,10 +43,10 @@ public static partial class ApiReflection { "cm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), global::Google.Protobuf.WellKnownTypes.Api.Parser, new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Method), global::Google.Protobuf.WellKnownTypes.Method.Parser, new[]{ "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Mixin), global::Google.Protobuf.WellKnownTypes.Mixin.Parser, new[]{ "Name", "Root" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), global::Google.Protobuf.WellKnownTypes.Api.Parser, new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Method), global::Google.Protobuf.WellKnownTypes.Method.Parser, new[]{ "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Mixin), global::Google.Protobuf.WellKnownTypes.Mixin.Parser, new[]{ "Name", "Root" }, null, null, null, null) })); } #endregion @@ -207,7 +207,7 @@ public sealed partial class Api : pb::IMessage { /// Field number for the "syntax" field. public const int SyntaxFieldNumber = 7; - private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0; + private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.Proto2; /// /// The source syntax of the service. /// @@ -251,7 +251,7 @@ public sealed partial class Api : pb::IMessage { if (Version.Length != 0) hash ^= Version.GetHashCode(); if (sourceContext_ != null) hash ^= SourceContext.GetHashCode(); hash ^= mixins_.GetHashCode(); - if (Syntax != 0) hash ^= Syntax.GetHashCode(); + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) hash ^= Syntax.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -280,7 +280,7 @@ public sealed partial class Api : pb::IMessage { output.WriteMessage(SourceContext); } mixins_.WriteTo(output, _repeated_mixins_codec); - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { output.WriteRawTag(56); output.WriteEnum((int) Syntax); } @@ -304,7 +304,7 @@ public sealed partial class Api : pb::IMessage { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext); } size += mixins_.CalculateSize(_repeated_mixins_codec); - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax); } if (_unknownFields != null) { @@ -333,7 +333,7 @@ public sealed partial class Api : pb::IMessage { SourceContext.MergeFrom(other.SourceContext); } mixins_.Add(other.mixins_); - if (other.Syntax != 0) { + if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { Syntax = other.Syntax; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); @@ -512,7 +512,7 @@ public sealed partial class Method : pb::IMessage { /// Field number for the "syntax" field. public const int SyntaxFieldNumber = 7; - private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0; + private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.Proto2; /// /// The source syntax of this method. /// @@ -556,7 +556,7 @@ public sealed partial class Method : pb::IMessage { if (ResponseTypeUrl.Length != 0) hash ^= ResponseTypeUrl.GetHashCode(); if (ResponseStreaming != false) hash ^= ResponseStreaming.GetHashCode(); hash ^= options_.GetHashCode(); - if (Syntax != 0) hash ^= Syntax.GetHashCode(); + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) hash ^= Syntax.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -591,7 +591,7 @@ public sealed partial class Method : pb::IMessage { output.WriteBool(ResponseStreaming); } options_.WriteTo(output, _repeated_options_codec); - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { output.WriteRawTag(56); output.WriteEnum((int) Syntax); } @@ -619,7 +619,7 @@ public sealed partial class Method : pb::IMessage { size += 1 + 1; } size += options_.CalculateSize(_repeated_options_codec); - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax); } if (_unknownFields != null) { @@ -649,7 +649,7 @@ public sealed partial class Method : pb::IMessage { ResponseStreaming = other.ResponseStreaming; } options_.Add(other.options_); - if (other.Syntax != 0) { + if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { Syntax = other.Syntax; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs index 2858b532b63..7a6f50190e1 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs @@ -32,8 +32,8 @@ public static partial class DurationReflection { "bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), global::Google.Protobuf.WellKnownTypes.Duration.Parser, new[]{ "Seconds", "Nanos" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), global::Google.Protobuf.WellKnownTypes.Duration.Parser, new[]{ "Seconds", "Nanos" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs index 2113add9bca..fa435cd23ed 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs @@ -31,8 +31,8 @@ public static partial class EmptyReflection { "dG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), global::Google.Protobuf.WellKnownTypes.Empty.Parser, null, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), global::Google.Protobuf.WellKnownTypes.Empty.Parser, null, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs index 6ad31a50eac..0bbf3139716 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs @@ -32,8 +32,8 @@ public static partial class FieldMaskReflection { "cm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), global::Google.Protobuf.WellKnownTypes.FieldMask.Parser, new[]{ "Paths" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), global::Google.Protobuf.WellKnownTypes.FieldMask.Parser, new[]{ "Paths" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs index 124ddaa7123..d7076196e0f 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs @@ -32,8 +32,8 @@ public static partial class SourceContextReflection { "YnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), global::Google.Protobuf.WellKnownTypes.SourceContext.Parser, new[]{ "FileName" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), global::Google.Protobuf.WellKnownTypes.SourceContext.Parser, new[]{ "FileName" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs index 194b81e965e..b1dbe239cc9 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs @@ -41,10 +41,10 @@ public static partial class StructReflection { "cGVzYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), global::Google.Protobuf.WellKnownTypes.Struct.Parser, new[]{ "Fields" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), global::Google.Protobuf.WellKnownTypes.Value.Parser, new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), global::Google.Protobuf.WellKnownTypes.ListValue.Parser, new[]{ "Values" }, null, null, null) + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), global::Google.Protobuf.WellKnownTypes.Struct.Parser, new[]{ "Fields" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), global::Google.Protobuf.WellKnownTypes.Value.Parser, new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), global::Google.Protobuf.WellKnownTypes.ListValue.Parser, new[]{ "Values" }, null, null, null, null) })); } #endregion @@ -114,7 +114,7 @@ public sealed partial class Struct : pb::IMessage { /// Field number for the "fields" field. public const int FieldsFieldNumber = 1; private static readonly pbc::MapField.Codec _map_fields_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Value.Parser), 10); + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Value.Parser), 10); private readonly pbc::MapField fields_ = new pbc::MapField(); /// /// Unordered map of dynamically typed values. @@ -270,7 +270,7 @@ public sealed partial class Value : pb::IMessage { /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.WellKnownTypes.NullValue NullValue { - get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : 0; } + get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; } set { kind_ = value; kindCase_ = KindOneofCase.NullValue; diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs index 9df237cfc0d..12f4812af37 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs @@ -32,8 +32,8 @@ public static partial class TimestampReflection { "cHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), global::Google.Protobuf.WellKnownTypes.Timestamp.Parser, new[]{ "Seconds", "Nanos" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), global::Google.Protobuf.WellKnownTypes.Timestamp.Parser, new[]{ "Seconds", "Nanos" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs index 52bd343ba84..bfd4b8ec822 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs @@ -62,12 +62,12 @@ public static partial class TypeReflection { "bEtub3duVHlwZXNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName", "DefaultValue" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), global::Google.Protobuf.WellKnownTypes.Enum.Parser, new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), global::Google.Protobuf.WellKnownTypes.EnumValue.Parser, new[]{ "Name", "Number", "Options" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), global::Google.Protobuf.WellKnownTypes.Option.Parser, new[]{ "Name", "Value" }, null, null, null) + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName", "DefaultValue" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), global::Google.Protobuf.WellKnownTypes.Enum.Parser, new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), global::Google.Protobuf.WellKnownTypes.EnumValue.Parser, new[]{ "Name", "Number", "Options" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), global::Google.Protobuf.WellKnownTypes.Option.Parser, new[]{ "Name", "Value" }, null, null, null, null) })); } #endregion @@ -202,7 +202,7 @@ public sealed partial class Type : pb::IMessage { /// Field number for the "syntax" field. public const int SyntaxFieldNumber = 6; - private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0; + private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.Proto2; /// /// The source syntax. /// @@ -244,7 +244,7 @@ public sealed partial class Type : pb::IMessage { hash ^= oneofs_.GetHashCode(); hash ^= options_.GetHashCode(); if (sourceContext_ != null) hash ^= SourceContext.GetHashCode(); - if (Syntax != 0) hash ^= Syntax.GetHashCode(); + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) hash ^= Syntax.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -269,7 +269,7 @@ public sealed partial class Type : pb::IMessage { output.WriteRawTag(42); output.WriteMessage(SourceContext); } - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { output.WriteRawTag(48); output.WriteEnum((int) Syntax); } @@ -290,7 +290,7 @@ public sealed partial class Type : pb::IMessage { if (sourceContext_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext); } - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax); } if (_unknownFields != null) { @@ -316,7 +316,7 @@ public sealed partial class Type : pb::IMessage { } SourceContext.MergeFrom(other.SourceContext); } - if (other.Syntax != 0) { + if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { Syntax = other.Syntax; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); @@ -411,7 +411,7 @@ public sealed partial class Field : pb::IMessage { /// Field number for the "kind" field. public const int KindFieldNumber = 1; - private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = 0; + private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown; /// /// The field type. /// @@ -425,7 +425,7 @@ public sealed partial class Field : pb::IMessage { /// Field number for the "cardinality" field. public const int CardinalityFieldNumber = 2; - private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = 0; + private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown; /// /// The field cardinality. /// @@ -579,8 +579,8 @@ public sealed partial class Field : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (Kind != 0) hash ^= Kind.GetHashCode(); - if (Cardinality != 0) hash ^= Cardinality.GetHashCode(); + if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) hash ^= Kind.GetHashCode(); + if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown) hash ^= Cardinality.GetHashCode(); if (Number != 0) hash ^= Number.GetHashCode(); if (Name.Length != 0) hash ^= Name.GetHashCode(); if (TypeUrl.Length != 0) hash ^= TypeUrl.GetHashCode(); @@ -602,11 +602,11 @@ public sealed partial class Field : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (Kind != 0) { + if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) { output.WriteRawTag(8); output.WriteEnum((int) Kind); } - if (Cardinality != 0) { + if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown) { output.WriteRawTag(16); output.WriteEnum((int) Cardinality); } @@ -647,10 +647,10 @@ public sealed partial class Field : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (Kind != 0) { + if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Kind); } - if (Cardinality != 0) { + if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Cardinality); } if (Number != 0) { @@ -686,10 +686,10 @@ public sealed partial class Field : pb::IMessage { if (other == null) { return; } - if (other.Kind != 0) { + if (other.Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) { Kind = other.Kind; } - if (other.Cardinality != 0) { + if (other.Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown) { Cardinality = other.Cardinality; } if (other.Number != 0) { @@ -979,7 +979,7 @@ public sealed partial class Enum : pb::IMessage { /// Field number for the "syntax" field. public const int SyntaxFieldNumber = 5; - private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0; + private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.Proto2; /// /// The source syntax. /// @@ -1019,7 +1019,7 @@ public sealed partial class Enum : pb::IMessage { hash ^= enumvalue_.GetHashCode(); hash ^= options_.GetHashCode(); if (sourceContext_ != null) hash ^= SourceContext.GetHashCode(); - if (Syntax != 0) hash ^= Syntax.GetHashCode(); + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) hash ^= Syntax.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -1043,7 +1043,7 @@ public sealed partial class Enum : pb::IMessage { output.WriteRawTag(34); output.WriteMessage(SourceContext); } - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { output.WriteRawTag(40); output.WriteEnum((int) Syntax); } @@ -1063,7 +1063,7 @@ public sealed partial class Enum : pb::IMessage { if (sourceContext_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext); } - if (Syntax != 0) { + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax); } if (_unknownFields != null) { @@ -1088,7 +1088,7 @@ public sealed partial class Enum : pb::IMessage { } SourceContext.MergeFrom(other.SourceContext); } - if (other.Syntax != 0) { + if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { Syntax = other.Syntax; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs index 25a65aa72c9..556af3c931b 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs @@ -36,16 +36,16 @@ public static partial class WrappersReflection { "QqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FloatValue), global::Google.Protobuf.WellKnownTypes.FloatValue.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int64Value), global::Google.Protobuf.WellKnownTypes.Int64Value.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt64Value), global::Google.Protobuf.WellKnownTypes.UInt64Value.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int32Value), global::Google.Protobuf.WellKnownTypes.Int32Value.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt32Value), global::Google.Protobuf.WellKnownTypes.UInt32Value.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BoolValue), global::Google.Protobuf.WellKnownTypes.BoolValue.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.StringValue), global::Google.Protobuf.WellKnownTypes.StringValue.Parser, new[]{ "Value" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BytesValue), global::Google.Protobuf.WellKnownTypes.BytesValue.Parser, new[]{ "Value" }, null, null, null) + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FloatValue), global::Google.Protobuf.WellKnownTypes.FloatValue.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int64Value), global::Google.Protobuf.WellKnownTypes.Int64Value.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt64Value), global::Google.Protobuf.WellKnownTypes.UInt64Value.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int32Value), global::Google.Protobuf.WellKnownTypes.Int32Value.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt32Value), global::Google.Protobuf.WellKnownTypes.UInt32Value.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BoolValue), global::Google.Protobuf.WellKnownTypes.BoolValue.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.StringValue), global::Google.Protobuf.WellKnownTypes.StringValue.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BytesValue), global::Google.Protobuf.WellKnownTypes.BytesValue.Parser, new[]{ "Value" }, null, null, null, null) })); } #endregion diff --git a/csharp/src/Google.Protobuf/WireFormat.cs b/csharp/src/Google.Protobuf/WireFormat.cs index f3adeb15f93..68f0f4a1f52 100644 --- a/csharp/src/Google.Protobuf/WireFormat.cs +++ b/csharp/src/Google.Protobuf/WireFormat.cs @@ -73,7 +73,7 @@ public enum WireType : uint /// Fixed32 = 5 } - + private const int TagTypeBits = 3; private const uint TagTypeMask = (1 << TagTypeBits) - 1; @@ -99,6 +99,6 @@ public static int GetTagFieldNumber(uint tag) public static uint MakeTag(int fieldNumber, WireType wireType) { return (uint) (fieldNumber << TagTypeBits) | (uint) wireType; - } + } } } \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc index 4d9bb67224c..186fa27e5b3 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -75,9 +76,20 @@ void EnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { } void EnumFieldGenerator::GenerateCodecCode(io::Printer* printer) { - printer->Print( - variables_, - "pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x)"); + printer->Print( + variables_, + "pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x, $default_value$)"); +} + +void EnumFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::Extension<$extended_type$, $type_name$>($number$, "); + GenerateCodecCode(printer); + printer->Print(");\n"); } EnumOneofFieldGenerator::EnumOneofFieldGenerator( diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_enum_field.h index 04ca68da6e1..9f1a2ea777c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.h @@ -55,6 +55,7 @@ class EnumFieldGenerator : public PrimitiveFieldGenerator { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); }; class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator { diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index 8ac0d3ab0eb..9be7b70e0b9 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -56,24 +56,41 @@ void FieldGeneratorBase::SetCommonFieldVariables( // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which // never effects the tag size. int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); + int part_tag_size = tag_size; if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - tag_size /= 2; + part_tag_size /= 2; } uint tag = internal::WireFormat::MakeTag(descriptor_); uint8 tag_array[5]; io::CodedOutputStream::WriteTagToArray(tag, tag_array); string tag_bytes = StrCat(tag_array[0]); - for (int i = 1; i < tag_size; i++) { + for (int i = 1; i < part_tag_size; i++) { tag_bytes += ", " + StrCat(tag_array[i]); } - (*variables)["access_level"] = "public"; (*variables)["tag"] = StrCat(tag); (*variables)["tag_size"] = StrCat(tag_size); (*variables)["tag_bytes"] = tag_bytes; + if (descriptor_->type() == FieldDescriptor::Type::TYPE_GROUP) { + tag = internal::WireFormatLite::MakeTag( + descriptor_->number(), + internal::WireFormatLite::WIRETYPE_END_GROUP); + io::CodedOutputStream::WriteTagToArray(tag, tag_array); + tag_bytes = StrCat(tag_array[0]); + for (int i = 1; i < part_tag_size; i++) { + tag_bytes += ", " + StrCat(tag_array[i]); + } + + variables_["end_tag"] = StrCat(tag); + variables_["end_tag_bytes"] = tag_bytes; + } + + (*variables)["access_level"] = "public"; + (*variables)["property_name"] = property_name(); (*variables)["type_name"] = type_name(); + (*variables)["extended_type"] = GetClassName(descriptor_->containing_type()); (*variables)["name"] = name(); (*variables)["descriptor_name"] = descriptor_->name(); (*variables)["default_value"] = default_value(); @@ -139,6 +156,11 @@ void FieldGeneratorBase::GenerateCodecCode(io::Printer* printer) { // Could fail if we get called here though... } +void FieldGeneratorBase::GenerateExtensionCode(io::Printer* printer) { + // No-op: only message fields, enum fields, primitives, + // and repeated fields need this default is to not generate any code +} + void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) { if (descriptor_->options().deprecated()) { printer->Print("[global::System.ObsoleteAttribute]\n"); @@ -301,13 +323,8 @@ std::string FieldGeneratorBase::default_value() { std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor) { switch (descriptor->type()) { case FieldDescriptor::TYPE_ENUM: - if (IsProto2(descriptor_->file())) { - return GetClassName(descriptor->default_value_enum()->type()) + "." + - GetEnumValueName(descriptor->default_value_enum()->type()->name(), descriptor->default_value_enum()->name()); - } - else { - return "0"; - } + return GetClassName(descriptor->default_value_enum()->type()) + "." + + GetEnumValueName(descriptor->default_value_enum()->type()->name(), descriptor->default_value_enum()->name()); case FieldDescriptor::TYPE_MESSAGE: case FieldDescriptor::TYPE_GROUP: if (IsWrapperType(descriptor)) { diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 28a096217a9..594461da784 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -57,6 +57,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { virtual void GenerateCloningCode(io::Printer* printer) = 0; virtual void GenerateFreezingCode(io::Printer* printer); virtual void GenerateCodecCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer) = 0; virtual void GenerateMergingCode(io::Printer* printer) = 0; virtual void GenerateParsingCode(io::Printer* printer) = 0; diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index e8b5dcda416..f0684a6f7f7 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -133,6 +133,12 @@ std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) return GetFileNameBase(descriptor) + "Reflection"; } +std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) { + // TODO: Detect collisions with existing messages, + // and append an underscore if necessary. + return GetFileNameBase(descriptor) + "Extensions"; +} + // TODO(jtattermusch): can we reuse a utility function? std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter, @@ -315,6 +321,15 @@ std::string GetReflectionClassName(const FileDescriptor* descriptor) { return "global::" + result; } +std::string GetFullExtensionName(const FieldDescriptor* descriptor) { + if (descriptor->extension_scope()) { + return GetClassName(descriptor->extension_scope()) + ".Extensions." + GetPropertyName(descriptor); + } + else { + return GetExtensionClassUnqualifiedName(descriptor->file()) + "." + GetPropertyName(descriptor); + } +} + std::string GetClassName(const Descriptor* descriptor) { return ToCSharpName(descriptor->full_name(), descriptor->file()); } diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h index d351a1c9b70..df18348131c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -75,6 +75,8 @@ std::string StripDotProto(const std::string& proto_file); // Gets unqualified name of the reflection class std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor); +// Gets unqualified name of the extension class +std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor); std::string GetClassName(const EnumDescriptor* descriptor); @@ -110,6 +112,8 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, int presenceIndex, const Options* options); +std::string GetFullExtensionName(const FieldDescriptor* descriptor); + bool IsNullable(const FieldDescriptor* descriptor); // Determines whether the given message is a map entry message, diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 513f8e9d5db..6ebd89f02fe 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -63,7 +63,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, : SourceGeneratorBase(descriptor->file(), options), descriptor_(descriptor), has_bit_field_count_(0), - end_tag_(GetGroupEndTag(descriptor)) { + end_tag_(GetGroupEndTag(descriptor)), + has_extension_ranges_(descriptor->extension_range_count() > 0) { // fields by number for (int i = 0; i < descriptor_->field_count(); i++) { fields_by_number_.push_back(descriptor_->field(i)); @@ -123,7 +124,15 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print( vars, - "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$> {\n"); + "$access_level$ sealed partial class $class_name$ : "); + + if (has_extension_ranges_) { + printer->Print(vars, "pb::IExtendableMessage<$class_name$>"); + } + else { + printer->Print(vars, "pb::IMessage<$class_name$>"); + } + printer->Print(" {\n"); printer->Indent(); // All static fields and properties @@ -134,6 +143,14 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print( "private pb::UnknownFieldSet _unknownFields;\n"); + if (has_extension_ranges_) { + if (IsDescriptorProto(descriptor_->file())) { + printer->Print(vars, "internal pb::ExtensionSet<$class_name$> _extensions;\n"); // CustomOptions compatibility + } else { + printer->Print(vars, "private pb::ExtensionSet<$class_name$> _extensions;\n"); + } + } + for (int i = 0; i < has_bit_field_count_; i++) { // don't use arrays since all arrays are heap allocated, saving allocations // use ints instead of bytes since bytes lack bitwise operators, saving casts @@ -169,12 +186,6 @@ void MessageGenerator::Generate(io::Printer* printer) { " get { return Descriptor; }\n" "}\n" "\n"); - // CustomOptions property, only for options messages - if (IsDescriptorOptionMessage(descriptor_)) { - printer->Print( - "internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;\n" - "\n"); - } // Parameterless constructor and partial OnConstruction method. WriteGeneratedCodeAttributes(printer); @@ -250,6 +261,32 @@ void MessageGenerator::Generate(io::Printer* printer) { GenerateMessageSerializationMethods(printer); GenerateMergingMethods(printer); + if (has_extension_ranges_) { + printer->Print( + vars, + "public TValue GetExtension(pb::Extension<$class_name$, TValue> extension) {\n" + " return pb::ExtensionSet.Get(ref _extensions, extension);\n" + "}\n" + "public pbc::RepeatedField GetExtension(pb::RepeatedExtension<$class_name$, TValue> extension) {\n" + " return pb::ExtensionSet.Get(ref _extensions, extension);\n" + "}\n" + "public pbc::RepeatedField GetOrRegisterExtension(pb::RepeatedExtension<$class_name$, TValue> extension) {\n" + " return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);\n" + "}\n" + "public void SetExtension(pb::Extension<$class_name$, TValue> extension, TValue value) {\n" + " pb::ExtensionSet.Set(ref _extensions, extension, value);\n" + "}\n" + "public bool HasExtension(pb::Extension<$class_name$, TValue> extension) {\n" + " return pb::ExtensionSet.Has(ref _extensions, extension);\n" + "}\n" + "public void ClearExtension(pb::Extension<$class_name$, TValue> extension) {\n" + " pb::ExtensionSet.Clear(ref _extensions, extension);\n" + "}\n" + "public void ClearExtension(pb::RepeatedExtension<$class_name$, TValue> extension) {\n" + " pb::ExtensionSet.Clear(ref _extensions, extension);\n" + "}\n\n"); + } + // Nested messages and enums if (HasNestedGeneratedTypes()) { printer->Print( @@ -277,6 +314,26 @@ void MessageGenerator::Generate(io::Printer* printer) { "\n"); } + if (descriptor_->extension_count() > 0) { + printer->Print( + vars, + "#region Extensions\n" + "/// Container for extensions for other messages declared in the $class_name$ message type.\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print("internal static partial class Extensions {\n"); + printer->Indent(); + for (int i = 0; i < descriptor_->extension_count(); i++) { + std::unique_ptr generator( + CreateFieldGeneratorInternal(descriptor_->extension(i))); + generator->GenerateExtensionCode(printer); + } + printer->Outdent(); + printer->Print( + "}\n" + "#endregion\n" + "\n"); + } + printer->Outdent(); printer->Print("}\n"); printer->Print("\n"); @@ -341,6 +398,10 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { // Clone unknown fields printer->Print( "_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);\n"); + if (has_extension_ranges_) { + printer->Print( + "_extensions = pb::ExtensionSet.Clone(other._extensions);\n"); + } printer->Outdent(); printer->Print("}\n\n"); @@ -387,6 +448,12 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n", "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); } + if (has_extension_ranges_) { + printer->Print( + "if (!Equals(_extensions, other._extensions)) {\n" + " return false;\n" + "}\n"); + } printer->Outdent(); printer->Print( " return Equals(_unknownFields, other._unknownFields);\n" @@ -408,6 +475,12 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { printer->Print("hash ^= (int) $name$Case_;\n", "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false)); } + if (has_extension_ranges_) { + printer->Print( + "if (_extensions != null) {\n" + " hash ^= _extensions.GetHashCode();\n" + "}\n"); + } printer->Print( "if (_unknownFields != null) {\n" " hash ^= _unknownFields.GetHashCode();\n" @@ -436,6 +509,14 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) generator->GenerateSerializationCode(printer); } + if (has_extension_ranges_) { + // Serialize extensions + printer->Print( + "if (_extensions != null) {\n" + " _extensions.WriteTo(output);\n" + "}\n"); + } + // Serialize unknown fields printer->Print( "if (_unknownFields != null) {\n" @@ -458,6 +539,13 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) generator->GenerateSerializedSizeCode(printer); } + if (has_extension_ranges_) { + printer->Print( + "if (_extensions != null) {\n" + " size += _extensions.CalculateSize();\n" + "}\n"); + } + printer->Print( "if (_unknownFields != null) {\n" " size += _unknownFields.CalculateSize();\n" @@ -513,6 +601,11 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Outdent(); printer->Print("}\n\n"); } + // Merge extensions + if (has_extension_ranges_) { + printer->Print("pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);\n"); + } + // Merge unknown fields. printer->Print( "_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);\n"); @@ -530,23 +623,24 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { " switch(tag) {\n"); printer->Indent(); printer->Indent(); - // Option messages need to store unknown fields so that options can be parsed later. - if (IsDescriptorOptionMessage(descriptor_)) { + if (end_tag_ != 0) { + printer->Print( + "$end_tag$:\n" + " return;\n", + "end_tag", StrCat(end_tag_)); + } + if (has_extension_ranges_) { printer->Print( "default:\n" - " CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);\n" + " if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {\n" + " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" + " }\n" " break;\n"); } else { printer->Print( "default:\n" " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" " break;\n"); - if (end_tag_ != 0) { - printer->Print( - "$end_tag$:\n" - " return;\n", - "end_tag", StrCat(end_tag_)); - } } for (int i = 0; i < fields_by_number().size(); i++) { const FieldDescriptor* field = fields_by_number()[i]; diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h index 7e88ecf1321..5642dc88120 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.h +++ b/src/google/protobuf/compiler/csharp/csharp_message.h @@ -63,6 +63,7 @@ class MessageGenerator : public SourceGeneratorBase { std::vector fields_by_number_; int has_bit_field_count_; uint end_tag_; + bool has_extension_ranges_; void GenerateMessageSerializationMethods(io::Printer* printer); void GenerateMergingMethods(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index f774c236c75..41257983125 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -57,21 +57,6 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, variables_["has_property_check"] = name() + "_ != null"; variables_["has_not_property_check"] = name() + "_ == null"; } - - if (descriptor_->type() == FieldDescriptor::Type::TYPE_GROUP) { - int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()) / 2; - uint tag = internal::WireFormatLite::MakeTag( - descriptor_->number(), - internal::WireFormatLite::WIRETYPE_END_GROUP); - uint8 tag_array[5]; - io::CodedOutputStream::WriteTagToArray(tag, tag_array); - string tag_bytes = StrCat(tag_array[0]); - for (int i = 1; i < tag_size; i++) { - tag_bytes += ", " + StrCat(tag_array[i]); - } - variables_["end_tag"] = StrCat(tag); - variables_["end_tag_bytes"] = tag_bytes; - } } MessageFieldGenerator::~MessageFieldGenerator() { @@ -168,7 +153,7 @@ void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( variables_, "if ($has_property_check$) {\n" - " size += $tag_size$ + $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n" + " size += $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n" "}\n"); } } @@ -189,6 +174,16 @@ void MessageFieldGenerator::WriteToString(io::Printer* printer) { variables_, "PrintField(\"$field_name$\", has$property_name$, $name$_, writer);\n"); } +void MessageFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::Extension<$extended_type$, $type_name$>($number$, "); + GenerateCodecCode(printer); + printer->Print(");\n"); +} void MessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { printer->Print(variables_, "$name$_ = other.$has_property_check$ ? other.$name$_.Clone() : null;\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h index 224bc28ead1..2463d912ba9 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.h @@ -59,6 +59,7 @@ class MessageFieldGenerator : public FieldGeneratorBase { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); virtual void WriteEquals(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index 9e4bb49db00..eb7f70dda6b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -225,7 +225,18 @@ void PrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) { void PrimitiveFieldGenerator::GenerateCodecCode(io::Printer* printer) { printer->Print( variables_, - "pb::FieldCodec.For$capitalized_type_name$($tag$)"); + "pb::FieldCodec.For$capitalized_type_name$($tag$, $default_value$)"); +} + +void PrimitiveFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::Extension<$extended_type$, $type_name$>($number$, "); + GenerateCodecCode(printer); + printer->Print(");\n"); } PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator( diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h index 54782e15f08..5edcc42b7ba 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h @@ -60,6 +60,7 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); virtual void WriteEquals(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc index 4ed2ef3637d..38a36024f92 100644 --- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc +++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,7 @@ ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file, file_(file) { namespace_ = GetFileNamespace(file); reflectionClassname_ = GetReflectionClassUnqualifiedName(file); + extensionClassname_ = GetExtensionClassUnqualifiedName(file); } ReflectionClassGenerator::~ReflectionClassGenerator() { @@ -69,6 +71,25 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) { printer->Outdent(); printer->Print("}\n"); + if (file_->extension_count() > 0) { + printer->Print( + "/// Holder for extension identifiers generated from the top level of $file_name$\n" + "internal static partial class $class_name$ {\n", + "access_level", class_access_level(), + "class_name", extensionClassname_, + "file_name", file_->name()); + printer->Indent(); + for (int i = 0; i < file_->extension_count(); i++) { + std::unique_ptr generator( + CreateFieldGenerator(file_->extension(i), -1, this->options())); + generator->GenerateExtensionCode(printer); + } + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + } + // write children: Enums if (file_->enum_type_count() > 0) { printer->Print("#region Enums\n"); @@ -169,17 +190,10 @@ void ReflectionClassGenerator::WriteDescriptor(io::Printer* printer) { "descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,\n"); printer->Print(" new pbr::FileDescriptor[] { "); for (int i = 0; i < file_->dependency_count(); i++) { - // descriptor.proto is special: we don't allow access to the generated code, but there's - // a separately-exposed property to get at the file descriptor, specifically to allow this - // kind of dependency. - if (IsDescriptorProto(file_->dependency(i))) { - printer->Print("pbr::FileDescriptor.DescriptorProtoFileDescriptor, "); - } else { printer->Print( "$full_reflection_class_name$.Descriptor, ", "full_reflection_class_name", GetReflectionClassName(file_->dependency(i))); - } } printer->Print("},\n" " new pbr::GeneratedClrTypeInfo("); @@ -193,6 +207,16 @@ void ReflectionClassGenerator::WriteDescriptor(io::Printer* printer) { } else { printer->Print("null, "); + } + if (file_->extension_count() > 0) { + std::vector extensions; + for (int i = 0; i < file_->extension_count(); i++) { + extensions.push_back(GetFullExtensionName(file_->extension(i))); + } + printer->Print("new pb::Extension[] { $extensions$ }, ", "extensions", JoinStrings(extensions, ", ")); + } + else { + printer->Print("null, "); } if (file_->message_type_count() > 0) { printer->Print("new pbr::GeneratedClrTypeInfo[] {\n"); @@ -270,6 +294,18 @@ void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descript printer->Print("null, "); } + // Extensions + if (descriptor->extension_count() > 0) { + std::vector extensions; + for (int i = 0; i < descriptor->extension_count(); i++) { + extensions.push_back(GetFullExtensionName(descriptor->extension(i))); + } + printer->Print("new pb::Extension[] { $extensions$ }, ", "extensions", JoinStrings(extensions, ", ")); + } + else { + printer->Print("null, "); + } + // Nested types if (descriptor->nested_type_count() > 0) { // Need to specify array type explicitly here, as all elements may be null. diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h index 1a4a2f4a7d2..95547277668 100644 --- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h +++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h @@ -58,6 +58,7 @@ class ReflectionClassGenerator : public SourceGeneratorBase { std::string namespace_; std::string reflectionClassname_; + std::string extensionClassname_; void WriteIntroduction(io::Printer* printer); void WriteDescriptor(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc index b8e66abb2b2..73309a7edd1 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -117,6 +117,16 @@ void RepeatedEnumFieldGenerator::GenerateCloningCode(io::Printer* printer) { "$name$_ = other.$name$_.Clone();\n"); } +void RepeatedEnumFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::RepeatedExtension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::RepeatedExtension<$extended_type$, $type_name$>($number$, " + "pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x));\n"); +} + void RepeatedEnumFieldGenerator::GenerateFreezingCode(io::Printer* printer) { } diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h index 75de1adab33..c7a632a17d4 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h @@ -61,6 +61,7 @@ class RepeatedEnumFieldGenerator : public FieldGeneratorBase { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); virtual void WriteEquals(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index bf76c0d3785..4b4b37de1bb 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -137,6 +137,25 @@ void RepeatedMessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { void RepeatedMessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) { } +void RepeatedMessageFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::RepeatedExtension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::RepeatedExtension<$extended_type$, $type_name$>($number$, "); + if (IsWrapperType(descriptor_)) { + std::unique_ptr single_generator( + new WrapperFieldGenerator(descriptor_, -1, this->options())); + single_generator->GenerateCodecCode(printer); + } else { + std::unique_ptr single_generator( + new MessageFieldGenerator(descriptor_, -1, this->options())); + single_generator->GenerateCodecCode(printer); + } + printer->Print(");\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h index e1b5f27c17d..74f6874df26 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h @@ -61,6 +61,7 @@ class RepeatedMessageFieldGenerator : public FieldGeneratorBase { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); virtual void WriteEquals(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc index 78fcdc674f9..c1444ea124a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -118,6 +118,15 @@ void RepeatedPrimitiveFieldGenerator::GenerateCloningCode(io::Printer* printer) void RepeatedPrimitiveFieldGenerator::GenerateFreezingCode(io::Printer* printer) { } +void RepeatedPrimitiveFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::RepeatedExtension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::RepeatedExtension<$extended_type$, $type_name$>($number$, pb::FieldCodec.For$capitalized_type_name$($tag$));\n"); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h index 7d9826fcd9b..2a3be481680 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h @@ -57,6 +57,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); virtual void WriteEquals(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index f284763dfd1..add20ab9fe6 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -181,6 +181,17 @@ void WrapperFieldGenerator::GenerateCodecCode(io::Printer* printer) { } } +void WrapperFieldGenerator::GenerateExtensionCode(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddDeprecatedFlag(printer); + printer->Print( + variables_, + "$access_level$ static readonly pb::Extension<$extended_type$, $type_name$> $property_name$ =\n" + " new pb::Extension<$extended_type$, $type_name$>($number$, "); + GenerateCodecCode(printer); + printer->Print(");\n"); +} + WrapperOneofFieldGenerator::WrapperOneofFieldGenerator( const FieldDescriptor* descriptor, int presenceIndex, const Options *options) : WrapperFieldGenerator(descriptor, presenceIndex, options) { diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h index ee684dda7c5..394e27de595 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h @@ -60,6 +60,7 @@ class WrapperFieldGenerator : public FieldGeneratorBase { virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); + virtual void GenerateExtensionCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); virtual void WriteEquals(io::Printer* printer);