diff --git a/csharp/src/ProtocolBuffers.Test/ByteStringTest.cs b/csharp/src/ProtocolBuffers.Test/ByteStringTest.cs index f445fcfe73..685e130a74 100644 --- a/csharp/src/ProtocolBuffers.Test/ByteStringTest.cs +++ b/csharp/src/ProtocolBuffers.Test/ByteStringTest.cs @@ -50,6 +50,7 @@ namespace Google.Protobuf EqualityTester.AssertInequality(b1, b3); EqualityTester.AssertInequality(b1, b4); EqualityTester.AssertInequality(b1, null); +#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1) Assert.IsTrue(b1 == b1); Assert.IsTrue(b1 == b2); Assert.IsFalse(b1 == b3); @@ -58,6 +59,7 @@ namespace Google.Protobuf Assert.IsTrue((ByteString) null == null); Assert.IsFalse(b1 != b1); Assert.IsFalse(b1 != b2); +#pragma warning disable 1718 Assert.IsTrue(b1 != b3); Assert.IsTrue(b1 != b4); Assert.IsTrue(b1 != null); diff --git a/csharp/src/ProtocolBuffers.Test/Collections/MapFieldTest.cs b/csharp/src/ProtocolBuffers.Test/Collections/MapFieldTest.cs index d43bed3e70..46d3bd9aaa 100644 --- a/csharp/src/ProtocolBuffers.Test/Collections/MapFieldTest.cs +++ b/csharp/src/ProtocolBuffers.Test/Collections/MapFieldTest.cs @@ -103,32 +103,35 @@ namespace Google.Protobuf.Collections } [Test] - public void Add_ForbidsNullKeys() + public void NullValues() { - var map = new MapField(); - Assert.Throws(() => map.Add(null, new ForeignMessage())); + TestNullValues(0); + TestNullValues(""); + TestNullValues(new TestAllTypes()); } - [Test] - public void Add_AcceptsNullMessageValues() + private void TestNullValues(T nonNullValue) { - var map = new MapField(); - map.Add("missing", null); - Assert.IsNull(map["missing"]); - } + var map = new MapField(false); + var nullValue = (T) (object) null; + Assert.Throws(() => map.Add(0, nullValue)); + Assert.Throws(() => map[0] = nullValue); + map.Add(1, nonNullValue); + map[1] = nonNullValue; - [Test] - public void Add_ForbidsNullStringValues() - { - var map = new MapField(); - Assert.Throws(() => map.Add("missing", null)); + // Doesn't throw... + map = new MapField(true); + map.Add(0, nullValue); + map[0] = nullValue; + map.Add(1, nonNullValue); + map[1] = nonNullValue; } [Test] - public void Add_ForbidsNullByteStringValues() + public void Add_ForbidsNullKeys() { - var map = new MapField(); - Assert.Throws(() => map.Add("missing", null)); + var map = new MapField(); + Assert.Throws(() => map.Add(null, new ForeignMessage())); } [Test] @@ -137,29 +140,7 @@ namespace Google.Protobuf.Collections var map = new MapField(); Assert.Throws(() => map[null] = new ForeignMessage()); } - - [Test] - public void Indexer_AcceptsNullMessageValues() - { - var map = new MapField(); - map["missing"] = null; - Assert.IsNull(map["missing"]); - } - - [Test] - public void Indexer_ForbidsNullStringValues() - { - var map = new MapField(); - Assert.Throws(() => map["missing"] = null); - } - - [Test] - public void Indexer_ForbidsNullByteStringValues() - { - var map = new MapField(); - Assert.Throws(() => map["missing"] = null); - } - + [Test] public void AddPreservesInsertionOrder() { @@ -528,6 +509,30 @@ namespace Google.Protobuf.Collections Assert.Throws(() => dictionary["a"] = "c"); } + [Test] + public void AllowNullValues_Property() + { + // Non-message reference type values are non-nullable by default, but can be overridden + Assert.IsFalse(new MapField().AllowsNullValues); + Assert.IsFalse(new MapField(false).AllowsNullValues); + Assert.IsTrue(new MapField(true).AllowsNullValues); + + // Non-nullable value type values are never nullable + Assert.IsFalse(new MapField().AllowsNullValues); + Assert.IsFalse(new MapField(false).AllowsNullValues); + Assert.Throws(() => new MapField(true)); + + // Message type values are nullable by default, but can be overridden + Assert.IsTrue(new MapField().AllowsNullValues); + Assert.IsFalse(new MapField(false).AllowsNullValues); + Assert.IsTrue(new MapField(true).AllowsNullValues); + + // Nullable value type values are nullable by default, but can be overridden + Assert.IsTrue(new MapField().AllowsNullValues); + Assert.IsFalse(new MapField(false).AllowsNullValues); + Assert.IsTrue(new MapField(true).AllowsNullValues); + } + private static KeyValuePair NewKeyValuePair(TKey key, TValue value) { return new KeyValuePair(key, value); diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestWellKnownTypes.cs index a995b2c667..af7d83ba4a 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestWellKnownTypes.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestWellKnownTypes.cs @@ -55,7 +55,7 @@ namespace Google.Protobuf.TestProtos { "cm90b2J1Zi5VSW50MzJWYWx1ZRIuCgpib29sX2ZpZWxkGBAgASgLMhouZ29v", "Z2xlLnByb3RvYnVmLkJvb2xWYWx1ZRIyCgxzdHJpbmdfZmllbGQYESABKAsy", "HC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSMAoLYnl0ZXNfZmllbGQY", - "EiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSLNAwoWUmVwZWF0", + "EiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSKVBwoWUmVwZWF0", "ZWRXZWxsS25vd25UeXBlcxInCglhbnlfZmllbGQYASADKAsyFC5nb29nbGUu", "cHJvdG9idWYuQW55EicKCWFwaV9maWVsZBgCIAMoCzIULmdvb2dsZS5wcm90", "b2J1Zi5BcGkSMQoOZHVyYXRpb25fZmllbGQYAyADKAsyGS5nb29nbGUucHJv", @@ -66,93 +66,103 @@ namespace Google.Protobuf.TestProtos { "dHJ1Y3RfZmllbGQYByADKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EjMK", "D3RpbWVzdGFtcF9maWVsZBgIIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1l", "c3RhbXASKQoKdHlwZV9maWVsZBgJIAMoCzIVLmdvb2dsZS5wcm90b2J1Zi5U", - "eXBlIsUHChNPbmVvZldlbGxLbm93blR5cGVzEikKCWFueV9maWVsZBgBIAEo", - "CzIULmdvb2dsZS5wcm90b2J1Zi5BbnlIABIpCglhcGlfZmllbGQYAiABKAsy", - "FC5nb29nbGUucHJvdG9idWYuQXBpSAASMwoOZHVyYXRpb25fZmllbGQYAyAB", - "KAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25IABItCgtlbXB0eV9maWVs", - "ZBgEIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjYKEGZpZWxkX21h", - "c2tfZmllbGQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrSAAS", - "PgoUc291cmNlX2NvbnRleHRfZmllbGQYBiABKAsyHi5nb29nbGUucHJvdG9i", - "dWYuU291cmNlQ29udGV4dEgAEi8KDHN0cnVjdF9maWVsZBgHIAEoCzIXLmdv", - "b2dsZS5wcm90b2J1Zi5TdHJ1Y3RIABI1Cg90aW1lc3RhbXBfZmllbGQYCCAB", - "KAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAASKwoKdHlwZV9maWVs", - "ZBgJIAEoCzIVLmdvb2dsZS5wcm90b2J1Zi5UeXBlSAASNAoMZG91YmxlX2Zp", - "ZWxkGAogASgLMhwuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlSAASMgoL", - "ZmxvYXRfZmllbGQYCyABKAsyGy5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1", - "ZUgAEjIKC2ludDY0X2ZpZWxkGAwgASgLMhsuZ29vZ2xlLnByb3RvYnVmLklu", - "dDY0VmFsdWVIABI0Cgx1aW50NjRfZmllbGQYDSABKAsyHC5nb29nbGUucHJv", - "dG9idWYuVUludDY0VmFsdWVIABIyCgtpbnQzMl9maWVsZBgOIAEoCzIbLmdv", - "b2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlSAASNAoMdWludDMyX2ZpZWxkGA8g", - "ASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlSAASMAoKYm9vbF9m", - "aWVsZBgQIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVIABI0Cgxz", - "dHJpbmdfZmllbGQYESABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFs", - "dWVIABIyCgtieXRlc19maWVsZBgSIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5C", - "eXRlc1ZhbHVlSABCDQoLb25lb2ZfZmllbGQilhYKEU1hcFdlbGxLbm93blR5", - "cGVzEkUKCWFueV9maWVsZBgBIAMoCzIyLnByb3RvYnVmX3VuaXR0ZXN0Lk1h", - "cFdlbGxLbm93blR5cGVzLkFueUZpZWxkRW50cnkSRQoJYXBpX2ZpZWxkGAIg", - "AygLMjIucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuQXBp", - "RmllbGRFbnRyeRJPCg5kdXJhdGlvbl9maWVsZBgDIAMoCzI3LnByb3RvYnVm", - "X3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkR1cmF0aW9uRmllbGRFbnRy", - "eRJJCgtlbXB0eV9maWVsZBgEIAMoCzI0LnByb3RvYnVmX3VuaXR0ZXN0Lk1h", - "cFdlbGxLbm93blR5cGVzLkVtcHR5RmllbGRFbnRyeRJSChBmaWVsZF9tYXNr", - "X2ZpZWxkGAUgAygLMjgucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3du", - "VHlwZXMuRmllbGRNYXNrRmllbGRFbnRyeRJaChRzb3VyY2VfY29udGV4dF9m", - "aWVsZBgGIAMoCzI8LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5", - "cGVzLlNvdXJjZUNvbnRleHRGaWVsZEVudHJ5EksKDHN0cnVjdF9maWVsZBgH", - "IAMoCzI1LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLlN0", - "cnVjdEZpZWxkRW50cnkSUQoPdGltZXN0YW1wX2ZpZWxkGAggAygLMjgucHJv", - "dG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuVGltZXN0YW1wRmll", - "bGRFbnRyeRJHCgp0eXBlX2ZpZWxkGAkgAygLMjMucHJvdG9idWZfdW5pdHRl", - "c3QuTWFwV2VsbEtub3duVHlwZXMuVHlwZUZpZWxkRW50cnkSSwoMZG91Ymxl", - "X2ZpZWxkGAogAygLMjUucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3du", - "VHlwZXMuRG91YmxlRmllbGRFbnRyeRJJCgtmbG9hdF9maWVsZBgLIAMoCzI0", - "LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkZsb2F0Rmll", - "bGRFbnRyeRJJCgtpbnQ2NF9maWVsZBgMIAMoCzI0LnByb3RvYnVmX3VuaXR0", - "ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkludDY0RmllbGRFbnRyeRJLCgx1aW50", - "NjRfZmllbGQYDSADKAsyNS5wcm90b2J1Zl91bml0dGVzdC5NYXBXZWxsS25v", - "d25UeXBlcy5VaW50NjRGaWVsZEVudHJ5EkkKC2ludDMyX2ZpZWxkGA4gAygL", - "MjQucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuSW50MzJG", - "aWVsZEVudHJ5EksKDHVpbnQzMl9maWVsZBgPIAMoCzI1LnByb3RvYnVmX3Vu", - "aXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLlVpbnQzMkZpZWxkRW50cnkSRwoK", - "Ym9vbF9maWVsZBgQIAMoCzIzLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxL", - "bm93blR5cGVzLkJvb2xGaWVsZEVudHJ5EksKDHN0cmluZ19maWVsZBgRIAMo", - "CzI1LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLlN0cmlu", - "Z0ZpZWxkRW50cnkSSQoLYnl0ZXNfZmllbGQYEiADKAsyNC5wcm90b2J1Zl91", - "bml0dGVzdC5NYXBXZWxsS25vd25UeXBlcy5CeXRlc0ZpZWxkRW50cnkaRQoN", - "QW55RmllbGRFbnRyeRILCgNrZXkYASABKAUSIwoFdmFsdWUYAiABKAsyFC5n", - "b29nbGUucHJvdG9idWYuQW55OgI4ARpFCg1BcGlGaWVsZEVudHJ5EgsKA2tl", - "eRgBIAEoBRIjCgV2YWx1ZRgCIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BcGk6", - "AjgBGk8KEkR1cmF0aW9uRmllbGRFbnRyeRILCgNrZXkYASABKAUSKAoFdmFs", - "dWUYAiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb246AjgBGkkKD0Vt", - "cHR5RmllbGRFbnRyeRILCgNrZXkYASABKAUSJQoFdmFsdWUYAiABKAsyFi5n", - "b29nbGUucHJvdG9idWYuRW1wdHk6AjgBGlEKE0ZpZWxkTWFza0ZpZWxkRW50", - "cnkSCwoDa2V5GAEgASgFEikKBXZhbHVlGAIgASgLMhouZ29vZ2xlLnByb3Rv", - "YnVmLkZpZWxkTWFzazoCOAEaWQoXU291cmNlQ29udGV4dEZpZWxkRW50cnkS", - "CwoDa2V5GAEgASgFEi0KBXZhbHVlGAIgASgLMh4uZ29vZ2xlLnByb3RvYnVm", - "LlNvdXJjZUNvbnRleHQ6AjgBGksKEFN0cnVjdEZpZWxkRW50cnkSCwoDa2V5", - "GAEgASgFEiYKBXZhbHVlGAIgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVj", - "dDoCOAEaUQoTVGltZXN0YW1wRmllbGRFbnRyeRILCgNrZXkYASABKAUSKQoF", - "dmFsdWUYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wOgI4ARpH", - "Cg5UeXBlRmllbGRFbnRyeRILCgNrZXkYASABKAUSJAoFdmFsdWUYAiABKAsy", - "FS5nb29nbGUucHJvdG9idWYuVHlwZToCOAEaUAoQRG91YmxlRmllbGRFbnRy", - "eRILCgNrZXkYASABKAUSKwoFdmFsdWUYAiABKAsyHC5nb29nbGUucHJvdG9i", - "dWYuRG91YmxlVmFsdWU6AjgBGk4KD0Zsb2F0RmllbGRFbnRyeRILCgNrZXkY", - "ASABKAUSKgoFdmFsdWUYAiABKAsyGy5nb29nbGUucHJvdG9idWYuRmxvYXRW", - "YWx1ZToCOAEaTgoPSW50NjRGaWVsZEVudHJ5EgsKA2tleRgBIAEoBRIqCgV2", - "YWx1ZRgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlOgI4ARpQ", - "ChBVaW50NjRGaWVsZEVudHJ5EgsKA2tleRgBIAEoBRIrCgV2YWx1ZRgCIAEo", - "CzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZToCOAEaTgoPSW50MzJG", - "aWVsZEVudHJ5EgsKA2tleRgBIAEoBRIqCgV2YWx1ZRgCIAEoCzIbLmdvb2ds", - "ZS5wcm90b2J1Zi5JbnQzMlZhbHVlOgI4ARpQChBVaW50MzJGaWVsZEVudHJ5", - "EgsKA2tleRgBIAEoBRIrCgV2YWx1ZRgCIAEoCzIcLmdvb2dsZS5wcm90b2J1", - "Zi5VSW50MzJWYWx1ZToCOAEaTAoOQm9vbEZpZWxkRW50cnkSCwoDa2V5GAEg", - "ASgFEikKBXZhbHVlGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1", - "ZToCOAEaUAoQU3RyaW5nRmllbGRFbnRyeRILCgNrZXkYASABKAUSKwoFdmFs", - "dWUYAiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU6AjgBGk4K", - "D0J5dGVzRmllbGRFbnRyeRILCgNrZXkYASABKAUSKgoFdmFsdWUYAiABKAsy", - "Gy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZToCOAFCOQoYY29tLmdvb2ds", - "ZS5wcm90b2J1Zi50ZXN0UAGqAhpHb29nbGUuUHJvdG9idWYuVGVzdFByb3Rv", - "c2IGcHJvdG8z")); + "eXBlEjIKDGRvdWJsZV9maWVsZBgKIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5E", + "b3VibGVWYWx1ZRIwCgtmbG9hdF9maWVsZBgLIAMoCzIbLmdvb2dsZS5wcm90", + "b2J1Zi5GbG9hdFZhbHVlEjAKC2ludDY0X2ZpZWxkGAwgAygLMhsuZ29vZ2xl", + "LnByb3RvYnVmLkludDY0VmFsdWUSMgoMdWludDY0X2ZpZWxkGA0gAygLMhwu", + "Z29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEjAKC2ludDMyX2ZpZWxkGA4g", + "AygLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSMgoMdWludDMyX2Zp", + "ZWxkGA8gAygLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlEi4KCmJv", + "b2xfZmllbGQYECADKAsyGi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlEjIK", + "DHN0cmluZ19maWVsZBgRIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdW", + "YWx1ZRIwCgtieXRlc19maWVsZBgSIAMoCzIbLmdvb2dsZS5wcm90b2J1Zi5C", + "eXRlc1ZhbHVlIsUHChNPbmVvZldlbGxLbm93blR5cGVzEikKCWFueV9maWVs", + "ZBgBIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnlIABIpCglhcGlfZmllbGQY", + "AiABKAsyFC5nb29nbGUucHJvdG9idWYuQXBpSAASMwoOZHVyYXRpb25fZmll", + "bGQYAyABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25IABItCgtlbXB0", + "eV9maWVsZBgEIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eUgAEjYKEGZp", + "ZWxkX21hc2tfZmllbGQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRN", + "YXNrSAASPgoUc291cmNlX2NvbnRleHRfZmllbGQYBiABKAsyHi5nb29nbGUu", + "cHJvdG9idWYuU291cmNlQ29udGV4dEgAEi8KDHN0cnVjdF9maWVsZBgHIAEo", + "CzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIABI1Cg90aW1lc3RhbXBfZmll", + "bGQYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAASKwoKdHlw", + "ZV9maWVsZBgJIAEoCzIVLmdvb2dsZS5wcm90b2J1Zi5UeXBlSAASNAoMZG91", + "YmxlX2ZpZWxkGAogASgLMhwuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVl", + "SAASMgoLZmxvYXRfZmllbGQYCyABKAsyGy5nb29nbGUucHJvdG9idWYuRmxv", + "YXRWYWx1ZUgAEjIKC2ludDY0X2ZpZWxkGAwgASgLMhsuZ29vZ2xlLnByb3Rv", + "YnVmLkludDY0VmFsdWVIABI0Cgx1aW50NjRfZmllbGQYDSABKAsyHC5nb29n", + "bGUucHJvdG9idWYuVUludDY0VmFsdWVIABIyCgtpbnQzMl9maWVsZBgOIAEo", + "CzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlSAASNAoMdWludDMyX2Zp", + "ZWxkGA8gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlSAASMAoK", + "Ym9vbF9maWVsZBgQIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVI", + "ABI0CgxzdHJpbmdfZmllbGQYESABKAsyHC5nb29nbGUucHJvdG9idWYuU3Ry", + "aW5nVmFsdWVIABIyCgtieXRlc19maWVsZBgSIAEoCzIbLmdvb2dsZS5wcm90", + "b2J1Zi5CeXRlc1ZhbHVlSABCDQoLb25lb2ZfZmllbGQilhYKEU1hcFdlbGxL", + "bm93blR5cGVzEkUKCWFueV9maWVsZBgBIAMoCzIyLnByb3RvYnVmX3VuaXR0", + "ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkFueUZpZWxkRW50cnkSRQoJYXBpX2Zp", + "ZWxkGAIgAygLMjIucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlw", + "ZXMuQXBpRmllbGRFbnRyeRJPCg5kdXJhdGlvbl9maWVsZBgDIAMoCzI3LnBy", + "b3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkR1cmF0aW9uRmll", + "bGRFbnRyeRJJCgtlbXB0eV9maWVsZBgEIAMoCzI0LnByb3RvYnVmX3VuaXR0", + "ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkVtcHR5RmllbGRFbnRyeRJSChBmaWVs", + "ZF9tYXNrX2ZpZWxkGAUgAygLMjgucHJvdG9idWZfdW5pdHRlc3QuTWFwV2Vs", + "bEtub3duVHlwZXMuRmllbGRNYXNrRmllbGRFbnRyeRJaChRzb3VyY2VfY29u", + "dGV4dF9maWVsZBgGIAMoCzI8LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxL", + "bm93blR5cGVzLlNvdXJjZUNvbnRleHRGaWVsZEVudHJ5EksKDHN0cnVjdF9m", + "aWVsZBgHIAMoCzI1LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5", + "cGVzLlN0cnVjdEZpZWxkRW50cnkSUQoPdGltZXN0YW1wX2ZpZWxkGAggAygL", + "MjgucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuVGltZXN0", + "YW1wRmllbGRFbnRyeRJHCgp0eXBlX2ZpZWxkGAkgAygLMjMucHJvdG9idWZf", + "dW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuVHlwZUZpZWxkRW50cnkSSwoM", + "ZG91YmxlX2ZpZWxkGAogAygLMjUucHJvdG9idWZfdW5pdHRlc3QuTWFwV2Vs", + "bEtub3duVHlwZXMuRG91YmxlRmllbGRFbnRyeRJJCgtmbG9hdF9maWVsZBgL", + "IAMoCzI0LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkZs", + "b2F0RmllbGRFbnRyeRJJCgtpbnQ2NF9maWVsZBgMIAMoCzI0LnByb3RvYnVm", + "X3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkludDY0RmllbGRFbnRyeRJL", + "Cgx1aW50NjRfZmllbGQYDSADKAsyNS5wcm90b2J1Zl91bml0dGVzdC5NYXBX", + "ZWxsS25vd25UeXBlcy5VaW50NjRGaWVsZEVudHJ5EkkKC2ludDMyX2ZpZWxk", + "GA4gAygLMjQucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMu", + "SW50MzJGaWVsZEVudHJ5EksKDHVpbnQzMl9maWVsZBgPIAMoCzI1LnByb3Rv", + "YnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLlVpbnQzMkZpZWxkRW50", + "cnkSRwoKYm9vbF9maWVsZBgQIAMoCzIzLnByb3RvYnVmX3VuaXR0ZXN0Lk1h", + "cFdlbGxLbm93blR5cGVzLkJvb2xGaWVsZEVudHJ5EksKDHN0cmluZ19maWVs", + "ZBgRIAMoCzI1LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVz", + "LlN0cmluZ0ZpZWxkRW50cnkSSQoLYnl0ZXNfZmllbGQYEiADKAsyNC5wcm90", + "b2J1Zl91bml0dGVzdC5NYXBXZWxsS25vd25UeXBlcy5CeXRlc0ZpZWxkRW50", + "cnkaRQoNQW55RmllbGRFbnRyeRILCgNrZXkYASABKAUSIwoFdmFsdWUYAiAB", + "KAsyFC5nb29nbGUucHJvdG9idWYuQW55OgI4ARpFCg1BcGlGaWVsZEVudHJ5", + "EgsKA2tleRgBIAEoBRIjCgV2YWx1ZRgCIAEoCzIULmdvb2dsZS5wcm90b2J1", + "Zi5BcGk6AjgBGk8KEkR1cmF0aW9uRmllbGRFbnRyeRILCgNrZXkYASABKAUS", + "KAoFdmFsdWUYAiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb246AjgB", + "GkkKD0VtcHR5RmllbGRFbnRyeRILCgNrZXkYASABKAUSJQoFdmFsdWUYAiAB", + "KAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHk6AjgBGlEKE0ZpZWxkTWFza0Zp", + "ZWxkRW50cnkSCwoDa2V5GAEgASgFEikKBXZhbHVlGAIgASgLMhouZ29vZ2xl", + "LnByb3RvYnVmLkZpZWxkTWFzazoCOAEaWQoXU291cmNlQ29udGV4dEZpZWxk", + "RW50cnkSCwoDa2V5GAEgASgFEi0KBXZhbHVlGAIgASgLMh4uZ29vZ2xlLnBy", + "b3RvYnVmLlNvdXJjZUNvbnRleHQ6AjgBGksKEFN0cnVjdEZpZWxkRW50cnkS", + "CwoDa2V5GAEgASgFEiYKBXZhbHVlGAIgASgLMhcuZ29vZ2xlLnByb3RvYnVm", + "LlN0cnVjdDoCOAEaUQoTVGltZXN0YW1wRmllbGRFbnRyeRILCgNrZXkYASAB", + "KAUSKQoFdmFsdWUYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1w", + "OgI4ARpHCg5UeXBlRmllbGRFbnRyeRILCgNrZXkYASABKAUSJAoFdmFsdWUY", + "AiABKAsyFS5nb29nbGUucHJvdG9idWYuVHlwZToCOAEaUAoQRG91YmxlRmll", + "bGRFbnRyeRILCgNrZXkYASABKAUSKwoFdmFsdWUYAiABKAsyHC5nb29nbGUu", + "cHJvdG9idWYuRG91YmxlVmFsdWU6AjgBGk4KD0Zsb2F0RmllbGRFbnRyeRIL", + "CgNrZXkYASABKAUSKgoFdmFsdWUYAiABKAsyGy5nb29nbGUucHJvdG9idWYu", + "RmxvYXRWYWx1ZToCOAEaTgoPSW50NjRGaWVsZEVudHJ5EgsKA2tleRgBIAEo", + "BRIqCgV2YWx1ZRgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVl", + "OgI4ARpQChBVaW50NjRGaWVsZEVudHJ5EgsKA2tleRgBIAEoBRIrCgV2YWx1", + "ZRgCIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZToCOAEaTgoP", + "SW50MzJGaWVsZEVudHJ5EgsKA2tleRgBIAEoBRIqCgV2YWx1ZRgCIAEoCzIb", + "Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlOgI4ARpQChBVaW50MzJGaWVs", + "ZEVudHJ5EgsKA2tleRgBIAEoBRIrCgV2YWx1ZRgCIAEoCzIcLmdvb2dsZS5w", + "cm90b2J1Zi5VSW50MzJWYWx1ZToCOAEaTAoOQm9vbEZpZWxkRW50cnkSCwoD", + "a2V5GAEgASgFEikKBXZhbHVlGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJv", + "b2xWYWx1ZToCOAEaUAoQU3RyaW5nRmllbGRFbnRyeRILCgNrZXkYASABKAUS", + "KwoFdmFsdWUYAiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU6", + "AjgBGk4KD0J5dGVzRmllbGRFbnRyeRILCgNrZXkYASABKAUSKgoFdmFsdWUY", + "AiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZToCOAFCOQoYY29t", + "Lmdvb2dsZS5wcm90b2J1Zi50ZXN0UAGqAhpHb29nbGUuUHJvdG9idWYuVGVz", + "dFByb3Rvc2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.Proto.Any.Descriptor, @@ -171,7 +181,7 @@ namespace Google.Protobuf.TestProtos { new string[] { "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", }, new string[] { }); internal__static_protobuf_unittest_RepeatedWellKnownTypes__FieldAccessorTable = new pbr::FieldAccessorTable(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), descriptor.MessageTypes[1], - new string[] { "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", }, new string[] { }); + new string[] { "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", }, new string[] { }); internal__static_protobuf_unittest_OneofWellKnownTypes__FieldAccessorTable = new pbr::FieldAccessorTable(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), descriptor.MessageTypes[2], new string[] { "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", }, new string[] { "OneofField", }); @@ -339,92 +349,101 @@ namespace Google.Protobuf.TestProtos { } public const int DoubleFieldFieldNumber = 10; - private global::Google.Protobuf.WellKnownTypes.DoubleValue doubleField_; + private static readonly pb::FieldCodec _single_doubleField_codec = pb::FieldCodec.ForStructWrapper(82); + private double? doubleField_; public double? DoubleField { - get { return doubleField_ == null ? (double?) null : doubleField_.Value; } + get { return doubleField_; } set { pb::Freezable.CheckMutable(this); - doubleField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.DoubleValue { Value = value.Value }; + doubleField_ = value; } } public const int FloatFieldFieldNumber = 11; - private global::Google.Protobuf.WellKnownTypes.FloatValue floatField_; + private static readonly pb::FieldCodec _single_floatField_codec = pb::FieldCodec.ForStructWrapper(90); + private float? floatField_; public float? FloatField { - get { return floatField_ == null ? (float?) null : floatField_.Value; } + get { return floatField_; } set { pb::Freezable.CheckMutable(this); - floatField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.FloatValue { Value = value.Value }; + floatField_ = value; } } public const int Int64FieldFieldNumber = 12; - private global::Google.Protobuf.WellKnownTypes.Int64Value int64Field_; + private static readonly pb::FieldCodec _single_int64Field_codec = pb::FieldCodec.ForStructWrapper(98); + private long? int64Field_; public long? Int64Field { - get { return int64Field_ == null ? (long?) null : int64Field_.Value; } + get { return int64Field_; } set { pb::Freezable.CheckMutable(this); - int64Field_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.Int64Value { Value = value.Value }; + int64Field_ = value; } } public const int Uint64FieldFieldNumber = 13; - private global::Google.Protobuf.WellKnownTypes.UInt64Value uint64Field_; + private static readonly pb::FieldCodec _single_uint64Field_codec = pb::FieldCodec.ForStructWrapper(106); + private ulong? uint64Field_; public ulong? Uint64Field { - get { return uint64Field_ == null ? (ulong?) null : uint64Field_.Value; } + get { return uint64Field_; } set { pb::Freezable.CheckMutable(this); - uint64Field_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.UInt64Value { Value = value.Value }; + uint64Field_ = value; } } public const int Int32FieldFieldNumber = 14; - private global::Google.Protobuf.WellKnownTypes.Int32Value int32Field_; + private static readonly pb::FieldCodec _single_int32Field_codec = pb::FieldCodec.ForStructWrapper(114); + private int? int32Field_; public int? Int32Field { - get { return int32Field_ == null ? (int?) null : int32Field_.Value; } + get { return int32Field_; } set { pb::Freezable.CheckMutable(this); - int32Field_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.Int32Value { Value = value.Value }; + int32Field_ = value; } } public const int Uint32FieldFieldNumber = 15; - private global::Google.Protobuf.WellKnownTypes.UInt32Value uint32Field_; + private static readonly pb::FieldCodec _single_uint32Field_codec = pb::FieldCodec.ForStructWrapper(122); + private uint? uint32Field_; public uint? Uint32Field { - get { return uint32Field_ == null ? (uint?) null : uint32Field_.Value; } + get { return uint32Field_; } set { pb::Freezable.CheckMutable(this); - uint32Field_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.UInt32Value { Value = value.Value }; + uint32Field_ = value; } } public const int BoolFieldFieldNumber = 16; - private global::Google.Protobuf.WellKnownTypes.BoolValue boolField_; + private static readonly pb::FieldCodec _single_boolField_codec = pb::FieldCodec.ForStructWrapper(130); + private bool? boolField_; public bool? BoolField { - get { return boolField_ == null ? (bool?) null : boolField_.Value; } + get { return boolField_; } set { pb::Freezable.CheckMutable(this); - boolField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.BoolValue { Value = value.Value }; + boolField_ = value; } } public const int StringFieldFieldNumber = 17; - private global::Google.Protobuf.WellKnownTypes.StringValue stringField_; + private static readonly pb::FieldCodec _single_stringField_codec = pb::FieldCodec.ForClassWrapper(138); + private string stringField_; public string StringField { - get { return stringField_ == null ? (string) null : stringField_.Value; } + get { return stringField_; } set { pb::Freezable.CheckMutable(this); - stringField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.StringValue { Value = value }; + stringField_ = value; } } public const int BytesFieldFieldNumber = 18; - private global::Google.Protobuf.WellKnownTypes.BytesValue bytesField_; + private static readonly pb::FieldCodec _single_bytesField_codec = pb::FieldCodec.ForClassWrapper(146); + private pb::ByteString bytesField_; public pb::ByteString BytesField { - get { return bytesField_ == null ? (pb::ByteString) null : bytesField_.Value; } + get { return bytesField_; } set { pb::Freezable.CheckMutable(this); - bytesField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.BytesValue { Value = value }; + bytesField_ = value; } } @@ -525,40 +544,31 @@ namespace Google.Protobuf.TestProtos { output.WriteMessage(TypeField); } if (doubleField_ != null) { - output.WriteRawTag(82); - output.WriteMessage(doubleField_); + _single_doubleField_codec.WriteTagAndValue(output, DoubleField); } if (floatField_ != null) { - output.WriteRawTag(90); - output.WriteMessage(floatField_); + _single_floatField_codec.WriteTagAndValue(output, FloatField); } if (int64Field_ != null) { - output.WriteRawTag(98); - output.WriteMessage(int64Field_); + _single_int64Field_codec.WriteTagAndValue(output, Int64Field); } if (uint64Field_ != null) { - output.WriteRawTag(106); - output.WriteMessage(uint64Field_); + _single_uint64Field_codec.WriteTagAndValue(output, Uint64Field); } if (int32Field_ != null) { - output.WriteRawTag(114); - output.WriteMessage(int32Field_); + _single_int32Field_codec.WriteTagAndValue(output, Int32Field); } if (uint32Field_ != null) { - output.WriteRawTag(122); - output.WriteMessage(uint32Field_); + _single_uint32Field_codec.WriteTagAndValue(output, Uint32Field); } if (boolField_ != null) { - output.WriteRawTag(130, 1); - output.WriteMessage(boolField_); + _single_boolField_codec.WriteTagAndValue(output, BoolField); } if (stringField_ != null) { - output.WriteRawTag(138, 1); - output.WriteMessage(stringField_); + _single_stringField_codec.WriteTagAndValue(output, StringField); } if (bytesField_ != null) { - output.WriteRawTag(146, 1); - output.WriteMessage(bytesField_); + _single_bytesField_codec.WriteTagAndValue(output, BytesField); } } @@ -592,31 +602,31 @@ namespace Google.Protobuf.TestProtos { size += 1 + pb::CodedOutputStream.ComputeMessageSize(TypeField); } if (doubleField_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(doubleField_); + size += _single_doubleField_codec.CalculateSizeWithTag(DoubleField); } if (floatField_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(floatField_); + size += _single_floatField_codec.CalculateSizeWithTag(FloatField); } if (int64Field_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(int64Field_); + size += _single_int64Field_codec.CalculateSizeWithTag(Int64Field); } if (uint64Field_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(uint64Field_); + size += _single_uint64Field_codec.CalculateSizeWithTag(Uint64Field); } if (int32Field_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(int32Field_); + size += _single_int32Field_codec.CalculateSizeWithTag(Int32Field); } if (uint32Field_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(uint32Field_); + size += _single_uint32Field_codec.CalculateSizeWithTag(Uint32Field); } if (boolField_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(boolField_); + size += _single_boolField_codec.CalculateSizeWithTag(BoolField); } if (stringField_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(stringField_); + size += _single_stringField_codec.CalculateSizeWithTag(StringField); } if (bytesField_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(bytesField_); + size += _single_bytesField_codec.CalculateSizeWithTag(BytesField); } return size; } @@ -680,58 +690,49 @@ namespace Google.Protobuf.TestProtos { TypeField.MergeFrom(other.TypeField); } if (other.doubleField_ != null) { - if (doubleField_ == null) { - doubleField_ = new global::Google.Protobuf.WellKnownTypes.DoubleValue(); + if (doubleField_ == null || other.DoubleField != 0D) { + DoubleField = other.DoubleField; } - doubleField_.MergeFrom(other.doubleField_); } if (other.floatField_ != null) { - if (floatField_ == null) { - floatField_ = new global::Google.Protobuf.WellKnownTypes.FloatValue(); + if (floatField_ == null || other.FloatField != 0F) { + FloatField = other.FloatField; } - floatField_.MergeFrom(other.floatField_); } if (other.int64Field_ != null) { - if (int64Field_ == null) { - int64Field_ = new global::Google.Protobuf.WellKnownTypes.Int64Value(); + if (int64Field_ == null || other.Int64Field != 0L) { + Int64Field = other.Int64Field; } - int64Field_.MergeFrom(other.int64Field_); } if (other.uint64Field_ != null) { - if (uint64Field_ == null) { - uint64Field_ = new global::Google.Protobuf.WellKnownTypes.UInt64Value(); + if (uint64Field_ == null || other.Uint64Field != 0UL) { + Uint64Field = other.Uint64Field; } - uint64Field_.MergeFrom(other.uint64Field_); } if (other.int32Field_ != null) { - if (int32Field_ == null) { - int32Field_ = new global::Google.Protobuf.WellKnownTypes.Int32Value(); + if (int32Field_ == null || other.Int32Field != 0) { + Int32Field = other.Int32Field; } - int32Field_.MergeFrom(other.int32Field_); } if (other.uint32Field_ != null) { - if (uint32Field_ == null) { - uint32Field_ = new global::Google.Protobuf.WellKnownTypes.UInt32Value(); + if (uint32Field_ == null || other.Uint32Field != 0) { + Uint32Field = other.Uint32Field; } - uint32Field_.MergeFrom(other.uint32Field_); } if (other.boolField_ != null) { - if (boolField_ == null) { - boolField_ = new global::Google.Protobuf.WellKnownTypes.BoolValue(); + if (boolField_ == null || other.BoolField != false) { + BoolField = other.BoolField; } - boolField_.MergeFrom(other.boolField_); } if (other.stringField_ != null) { - if (stringField_ == null) { - stringField_ = new global::Google.Protobuf.WellKnownTypes.StringValue(); + if (stringField_ == null || other.StringField != "") { + StringField = other.StringField; } - stringField_.MergeFrom(other.stringField_); } if (other.bytesField_ != null) { - if (bytesField_ == null) { - bytesField_ = new global::Google.Protobuf.WellKnownTypes.BytesValue(); + if (bytesField_ == null || other.BytesField != pb::ByteString.Empty) { + BytesField = other.BytesField; } - bytesField_.MergeFrom(other.bytesField_); } } @@ -810,66 +811,66 @@ namespace Google.Protobuf.TestProtos { break; } case 82: { - if (doubleField_ == null) { - doubleField_ = new global::Google.Protobuf.WellKnownTypes.DoubleValue(); + double? value = _single_doubleField_codec.Read(input); + if (doubleField_ == null || value != 0D) { + DoubleField = value; } - input.ReadMessage(doubleField_); break; } case 90: { - if (floatField_ == null) { - floatField_ = new global::Google.Protobuf.WellKnownTypes.FloatValue(); + float? value = _single_floatField_codec.Read(input); + if (floatField_ == null || value != 0F) { + FloatField = value; } - input.ReadMessage(floatField_); break; } case 98: { - if (int64Field_ == null) { - int64Field_ = new global::Google.Protobuf.WellKnownTypes.Int64Value(); + long? value = _single_int64Field_codec.Read(input); + if (int64Field_ == null || value != 0L) { + Int64Field = value; } - input.ReadMessage(int64Field_); break; } case 106: { - if (uint64Field_ == null) { - uint64Field_ = new global::Google.Protobuf.WellKnownTypes.UInt64Value(); + ulong? value = _single_uint64Field_codec.Read(input); + if (uint64Field_ == null || value != 0UL) { + Uint64Field = value; } - input.ReadMessage(uint64Field_); break; } case 114: { - if (int32Field_ == null) { - int32Field_ = new global::Google.Protobuf.WellKnownTypes.Int32Value(); + int? value = _single_int32Field_codec.Read(input); + if (int32Field_ == null || value != 0) { + Int32Field = value; } - input.ReadMessage(int32Field_); break; } case 122: { - if (uint32Field_ == null) { - uint32Field_ = new global::Google.Protobuf.WellKnownTypes.UInt32Value(); + uint? value = _single_uint32Field_codec.Read(input); + if (uint32Field_ == null || value != 0) { + Uint32Field = value; } - input.ReadMessage(uint32Field_); break; } case 130: { - if (boolField_ == null) { - boolField_ = new global::Google.Protobuf.WellKnownTypes.BoolValue(); + bool? value = _single_boolField_codec.Read(input); + if (boolField_ == null || value != false) { + BoolField = value; } - input.ReadMessage(boolField_); break; } case 138: { - if (stringField_ == null) { - stringField_ = new global::Google.Protobuf.WellKnownTypes.StringValue(); + string value = _single_stringField_codec.Read(input); + if (stringField_ == null || value != "") { + StringField = value; } - input.ReadMessage(stringField_); break; } case 146: { - if (bytesField_ == null) { - bytesField_ = new global::Google.Protobuf.WellKnownTypes.BytesValue(); + pb::ByteString value = _single_bytesField_codec.Read(input); + if (bytesField_ == null || value != pb::ByteString.Empty) { + BytesField = value; } - input.ReadMessage(bytesField_); break; } } @@ -883,8 +884,8 @@ namespace Google.Protobuf.TestProtos { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RepeatedWellKnownTypes()); public static pb::MessageParser Parser { get { return _parser; } } - private static readonly string[] _fieldNames = new string[] { "any_field", "api_field", "duration_field", "empty_field", "field_mask_field", "source_context_field", "struct_field", "timestamp_field", "type_field" }; - private static readonly uint[] _fieldTags = new uint[] { 10, 18, 26, 34, 42, 50, 58, 66, 74 }; + private static readonly string[] _fieldNames = new string[] { "any_field", "api_field", "bool_field", "bytes_field", "double_field", "duration_field", "empty_field", "field_mask_field", "float_field", "int32_field", "int64_field", "source_context_field", "string_field", "struct_field", "timestamp_field", "type_field", "uint32_field", "uint64_field" }; + private static readonly uint[] _fieldTags = new uint[] { 10, 18, 130, 146, 82, 26, 34, 42, 90, 114, 98, 50, 138, 58, 66, 74, 122, 106 }; public static pbr::MessageDescriptor Descriptor { get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypes.Descriptor.MessageTypes[1]; } } @@ -912,6 +913,15 @@ namespace Google.Protobuf.TestProtos { structField_ = other.structField_.Clone(); timestampField_ = other.timestampField_.Clone(); typeField_ = other.typeField_.Clone(); + doubleField_ = other.doubleField_.Clone(); + floatField_ = other.floatField_.Clone(); + int64Field_ = other.int64Field_.Clone(); + uint64Field_ = other.uint64Field_.Clone(); + int32Field_ = other.int32Field_.Clone(); + uint32Field_ = other.uint32Field_.Clone(); + boolField_ = other.boolField_.Clone(); + stringField_ = other.stringField_.Clone(); + bytesField_ = other.bytesField_.Clone(); } public RepeatedWellKnownTypes Clone() { @@ -932,6 +942,15 @@ namespace Google.Protobuf.TestProtos { structField_.Freeze(); timestampField_.Freeze(); typeField_.Freeze(); + doubleField_.Freeze(); + floatField_.Freeze(); + int64Field_.Freeze(); + uint64Field_.Freeze(); + int32Field_.Freeze(); + uint32Field_.Freeze(); + boolField_.Freeze(); + stringField_.Freeze(); + bytesField_.Freeze(); } public const int AnyFieldFieldNumber = 1; @@ -1006,6 +1025,78 @@ namespace Google.Protobuf.TestProtos { get { return typeField_; } } + public const int DoubleFieldFieldNumber = 10; + private static readonly pb::FieldCodec _repeated_doubleField_codec + = pb::FieldCodec.ForStructWrapper(82); + private readonly pbc::RepeatedField doubleField_ = new pbc::RepeatedField(); + public pbc::RepeatedField DoubleField { + get { return doubleField_; } + } + + public const int FloatFieldFieldNumber = 11; + private static readonly pb::FieldCodec _repeated_floatField_codec + = pb::FieldCodec.ForStructWrapper(90); + private readonly pbc::RepeatedField floatField_ = new pbc::RepeatedField(); + public pbc::RepeatedField FloatField { + get { return floatField_; } + } + + public const int Int64FieldFieldNumber = 12; + private static readonly pb::FieldCodec _repeated_int64Field_codec + = pb::FieldCodec.ForStructWrapper(98); + private readonly pbc::RepeatedField int64Field_ = new pbc::RepeatedField(); + public pbc::RepeatedField Int64Field { + get { return int64Field_; } + } + + public const int Uint64FieldFieldNumber = 13; + private static readonly pb::FieldCodec _repeated_uint64Field_codec + = pb::FieldCodec.ForStructWrapper(106); + private readonly pbc::RepeatedField uint64Field_ = new pbc::RepeatedField(); + public pbc::RepeatedField Uint64Field { + get { return uint64Field_; } + } + + public const int Int32FieldFieldNumber = 14; + private static readonly pb::FieldCodec _repeated_int32Field_codec + = pb::FieldCodec.ForStructWrapper(114); + private readonly pbc::RepeatedField int32Field_ = new pbc::RepeatedField(); + public pbc::RepeatedField Int32Field { + get { return int32Field_; } + } + + public const int Uint32FieldFieldNumber = 15; + private static readonly pb::FieldCodec _repeated_uint32Field_codec + = pb::FieldCodec.ForStructWrapper(122); + private readonly pbc::RepeatedField uint32Field_ = new pbc::RepeatedField(); + public pbc::RepeatedField Uint32Field { + get { return uint32Field_; } + } + + public const int BoolFieldFieldNumber = 16; + private static readonly pb::FieldCodec _repeated_boolField_codec + = pb::FieldCodec.ForStructWrapper(130); + private readonly pbc::RepeatedField boolField_ = new pbc::RepeatedField(); + public pbc::RepeatedField BoolField { + get { return boolField_; } + } + + public const int StringFieldFieldNumber = 17; + private static readonly pb::FieldCodec _repeated_stringField_codec + = pb::FieldCodec.ForClassWrapper(138); + private readonly pbc::RepeatedField stringField_ = new pbc::RepeatedField(); + public pbc::RepeatedField StringField { + get { return stringField_; } + } + + public const int BytesFieldFieldNumber = 18; + private static readonly pb::FieldCodec _repeated_bytesField_codec + = pb::FieldCodec.ForClassWrapper(146); + private readonly pbc::RepeatedField bytesField_ = new pbc::RepeatedField(); + public pbc::RepeatedField BytesField { + get { return bytesField_; } + } + public override bool Equals(object other) { return Equals(other as RepeatedWellKnownTypes); } @@ -1026,6 +1117,15 @@ namespace Google.Protobuf.TestProtos { if(!structField_.Equals(other.structField_)) return false; if(!timestampField_.Equals(other.timestampField_)) return false; if(!typeField_.Equals(other.typeField_)) return false; + if(!doubleField_.Equals(other.doubleField_)) return false; + if(!floatField_.Equals(other.floatField_)) return false; + if(!int64Field_.Equals(other.int64Field_)) return false; + if(!uint64Field_.Equals(other.uint64Field_)) return false; + if(!int32Field_.Equals(other.int32Field_)) return false; + if(!uint32Field_.Equals(other.uint32Field_)) return false; + if(!boolField_.Equals(other.boolField_)) return false; + if(!stringField_.Equals(other.stringField_)) return false; + if(!bytesField_.Equals(other.bytesField_)) return false; return true; } @@ -1040,6 +1140,15 @@ namespace Google.Protobuf.TestProtos { hash ^= structField_.GetHashCode(); hash ^= timestampField_.GetHashCode(); hash ^= typeField_.GetHashCode(); + hash ^= doubleField_.GetHashCode(); + hash ^= floatField_.GetHashCode(); + hash ^= int64Field_.GetHashCode(); + hash ^= uint64Field_.GetHashCode(); + hash ^= int32Field_.GetHashCode(); + hash ^= uint32Field_.GetHashCode(); + hash ^= boolField_.GetHashCode(); + hash ^= stringField_.GetHashCode(); + hash ^= bytesField_.GetHashCode(); return hash; } @@ -1057,6 +1166,15 @@ namespace Google.Protobuf.TestProtos { structField_.WriteTo(output, _repeated_structField_codec); timestampField_.WriteTo(output, _repeated_timestampField_codec); typeField_.WriteTo(output, _repeated_typeField_codec); + doubleField_.WriteTo(output, _repeated_doubleField_codec); + floatField_.WriteTo(output, _repeated_floatField_codec); + int64Field_.WriteTo(output, _repeated_int64Field_codec); + uint64Field_.WriteTo(output, _repeated_uint64Field_codec); + int32Field_.WriteTo(output, _repeated_int32Field_codec); + uint32Field_.WriteTo(output, _repeated_uint32Field_codec); + boolField_.WriteTo(output, _repeated_boolField_codec); + stringField_.WriteTo(output, _repeated_stringField_codec); + bytesField_.WriteTo(output, _repeated_bytesField_codec); } public int CalculateSize() { @@ -1070,6 +1188,15 @@ namespace Google.Protobuf.TestProtos { size += structField_.CalculateSize(_repeated_structField_codec); size += timestampField_.CalculateSize(_repeated_timestampField_codec); size += typeField_.CalculateSize(_repeated_typeField_codec); + size += doubleField_.CalculateSize(_repeated_doubleField_codec); + size += floatField_.CalculateSize(_repeated_floatField_codec); + size += int64Field_.CalculateSize(_repeated_int64Field_codec); + size += uint64Field_.CalculateSize(_repeated_uint64Field_codec); + size += int32Field_.CalculateSize(_repeated_int32Field_codec); + size += uint32Field_.CalculateSize(_repeated_uint32Field_codec); + size += boolField_.CalculateSize(_repeated_boolField_codec); + size += stringField_.CalculateSize(_repeated_stringField_codec); + size += bytesField_.CalculateSize(_repeated_bytesField_codec); return size; } @@ -1086,6 +1213,15 @@ namespace Google.Protobuf.TestProtos { structField_.Add(other.structField_); timestampField_.Add(other.timestampField_); typeField_.Add(other.typeField_); + doubleField_.Add(other.doubleField_); + floatField_.Add(other.floatField_); + int64Field_.Add(other.int64Field_); + uint64Field_.Add(other.uint64Field_); + int32Field_.Add(other.int32Field_); + uint32Field_.Add(other.uint32Field_); + boolField_.Add(other.boolField_); + stringField_.Add(other.stringField_); + bytesField_.Add(other.bytesField_); } public void MergeFrom(pb::CodedInputStream input) { @@ -1135,6 +1271,42 @@ namespace Google.Protobuf.TestProtos { typeField_.AddEntriesFrom(input, _repeated_typeField_codec); break; } + case 82: { + doubleField_.AddEntriesFrom(input, _repeated_doubleField_codec); + break; + } + case 90: { + floatField_.AddEntriesFrom(input, _repeated_floatField_codec); + break; + } + case 98: { + int64Field_.AddEntriesFrom(input, _repeated_int64Field_codec); + break; + } + case 106: { + uint64Field_.AddEntriesFrom(input, _repeated_uint64Field_codec); + break; + } + case 114: { + int32Field_.AddEntriesFrom(input, _repeated_int32Field_codec); + break; + } + case 122: { + uint32Field_.AddEntriesFrom(input, _repeated_uint32Field_codec); + break; + } + case 130: { + boolField_.AddEntriesFrom(input, _repeated_boolField_codec); + break; + } + case 138: { + stringField_.AddEntriesFrom(input, _repeated_stringField_codec); + break; + } + case 146: { + bytesField_.AddEntriesFrom(input, _repeated_bytesField_codec); + break; + } } } } @@ -1328,91 +1500,100 @@ namespace Google.Protobuf.TestProtos { } public const int DoubleFieldFieldNumber = 10; + private static readonly pb::FieldCodec _oneof_doubleField_codec = pb::FieldCodec.ForStructWrapper(82); public double? DoubleField { - get { return oneofFieldCase_ == OneofFieldOneofCase.DoubleField ? ((global::Google.Protobuf.WellKnownTypes.DoubleValue) oneofField_).Value : (double?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.DoubleField ? (double?) oneofField_ : (double?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.DoubleValue { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.DoubleField; } } public const int FloatFieldFieldNumber = 11; + private static readonly pb::FieldCodec _oneof_floatField_codec = pb::FieldCodec.ForStructWrapper(90); public float? FloatField { - get { return oneofFieldCase_ == OneofFieldOneofCase.FloatField ? ((global::Google.Protobuf.WellKnownTypes.FloatValue) oneofField_).Value : (float?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.FloatField ? (float?) oneofField_ : (float?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.FloatValue { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.FloatField; } } public const int Int64FieldFieldNumber = 12; + private static readonly pb::FieldCodec _oneof_int64Field_codec = pb::FieldCodec.ForStructWrapper(98); public long? Int64Field { - get { return oneofFieldCase_ == OneofFieldOneofCase.Int64Field ? ((global::Google.Protobuf.WellKnownTypes.Int64Value) oneofField_).Value : (long?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.Int64Field ? (long?) oneofField_ : (long?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.Int64Value { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.Int64Field; } } public const int Uint64FieldFieldNumber = 13; + private static readonly pb::FieldCodec _oneof_uint64Field_codec = pb::FieldCodec.ForStructWrapper(106); public ulong? Uint64Field { - get { return oneofFieldCase_ == OneofFieldOneofCase.Uint64Field ? ((global::Google.Protobuf.WellKnownTypes.UInt64Value) oneofField_).Value : (ulong?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.Uint64Field ? (ulong?) oneofField_ : (ulong?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.UInt64Value { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.Uint64Field; } } public const int Int32FieldFieldNumber = 14; + private static readonly pb::FieldCodec _oneof_int32Field_codec = pb::FieldCodec.ForStructWrapper(114); public int? Int32Field { - get { return oneofFieldCase_ == OneofFieldOneofCase.Int32Field ? ((global::Google.Protobuf.WellKnownTypes.Int32Value) oneofField_).Value : (int?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.Int32Field ? (int?) oneofField_ : (int?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.Int32Value { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.Int32Field; } } public const int Uint32FieldFieldNumber = 15; + private static readonly pb::FieldCodec _oneof_uint32Field_codec = pb::FieldCodec.ForStructWrapper(122); public uint? Uint32Field { - get { return oneofFieldCase_ == OneofFieldOneofCase.Uint32Field ? ((global::Google.Protobuf.WellKnownTypes.UInt32Value) oneofField_).Value : (uint?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.Uint32Field ? (uint?) oneofField_ : (uint?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.UInt32Value { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.Uint32Field; } } public const int BoolFieldFieldNumber = 16; + private static readonly pb::FieldCodec _oneof_boolField_codec = pb::FieldCodec.ForStructWrapper(130); public bool? BoolField { - get { return oneofFieldCase_ == OneofFieldOneofCase.BoolField ? ((global::Google.Protobuf.WellKnownTypes.BoolValue) oneofField_).Value : (bool?) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.BoolField ? (bool?) oneofField_ : (bool?) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.BoolValue { Value = value.Value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.BoolField; } } public const int StringFieldFieldNumber = 17; + private static readonly pb::FieldCodec _oneof_stringField_codec = pb::FieldCodec.ForClassWrapper(138); public string StringField { - get { return oneofFieldCase_ == OneofFieldOneofCase.StringField ? ((global::Google.Protobuf.WellKnownTypes.StringValue) oneofField_).Value : (string) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.StringField ? (string) oneofField_ : (string) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.StringValue { Value = value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.StringField; } } public const int BytesFieldFieldNumber = 18; + private static readonly pb::FieldCodec _oneof_bytesField_codec = pb::FieldCodec.ForClassWrapper(146); public pb::ByteString BytesField { - get { return oneofFieldCase_ == OneofFieldOneofCase.BytesField ? ((global::Google.Protobuf.WellKnownTypes.BytesValue) oneofField_).Value : (pb::ByteString) null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.BytesField ? (pb::ByteString) oneofField_ : (pb::ByteString) null; } set { pb::Freezable.CheckMutable(this); - oneofField_ = value == null ? null : new global::Google.Protobuf.WellKnownTypes.BytesValue { Value = value }; + oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.BytesField; } } @@ -1547,40 +1728,31 @@ namespace Google.Protobuf.TestProtos { output.WriteMessage(TypeField); } if (oneofFieldCase_ == OneofFieldOneofCase.DoubleField) { - output.WriteRawTag(82); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.DoubleValue) oneofField_); + _oneof_doubleField_codec.WriteTagAndValue(output, (double?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.FloatField) { - output.WriteRawTag(90); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.FloatValue) oneofField_); + _oneof_floatField_codec.WriteTagAndValue(output, (float?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.Int64Field) { - output.WriteRawTag(98); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.Int64Value) oneofField_); + _oneof_int64Field_codec.WriteTagAndValue(output, (long?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.Uint64Field) { - output.WriteRawTag(106); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.UInt64Value) oneofField_); + _oneof_uint64Field_codec.WriteTagAndValue(output, (ulong?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.Int32Field) { - output.WriteRawTag(114); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.Int32Value) oneofField_); + _oneof_int32Field_codec.WriteTagAndValue(output, (int?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.Uint32Field) { - output.WriteRawTag(122); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.UInt32Value) oneofField_); + _oneof_uint32Field_codec.WriteTagAndValue(output, (uint?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.BoolField) { - output.WriteRawTag(130, 1); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.BoolValue) oneofField_); + _oneof_boolField_codec.WriteTagAndValue(output, (bool?) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.StringField) { - output.WriteRawTag(138, 1); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.StringValue) oneofField_); + _oneof_stringField_codec.WriteTagAndValue(output, (string) oneofField_); } if (oneofFieldCase_ == OneofFieldOneofCase.BytesField) { - output.WriteRawTag(146, 1); - output.WriteMessage((global::Google.Protobuf.WellKnownTypes.BytesValue) oneofField_); + _oneof_bytesField_codec.WriteTagAndValue(output, (pb::ByteString) oneofField_); } } @@ -1614,31 +1786,31 @@ namespace Google.Protobuf.TestProtos { size += 1 + pb::CodedOutputStream.ComputeMessageSize(TypeField); } if (oneofFieldCase_ == OneofFieldOneofCase.DoubleField) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.DoubleValue) oneofField_)); + size += _oneof_doubleField_codec.CalculateSizeWithTag(DoubleField); } if (oneofFieldCase_ == OneofFieldOneofCase.FloatField) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.FloatValue) oneofField_)); + size += _oneof_floatField_codec.CalculateSizeWithTag(FloatField); } if (oneofFieldCase_ == OneofFieldOneofCase.Int64Field) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.Int64Value) oneofField_)); + size += _oneof_int64Field_codec.CalculateSizeWithTag(Int64Field); } if (oneofFieldCase_ == OneofFieldOneofCase.Uint64Field) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.UInt64Value) oneofField_)); + size += _oneof_uint64Field_codec.CalculateSizeWithTag(Uint64Field); } if (oneofFieldCase_ == OneofFieldOneofCase.Int32Field) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.Int32Value) oneofField_)); + size += _oneof_int32Field_codec.CalculateSizeWithTag(Int32Field); } if (oneofFieldCase_ == OneofFieldOneofCase.Uint32Field) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.UInt32Value) oneofField_)); + size += _oneof_uint32Field_codec.CalculateSizeWithTag(Uint32Field); } if (oneofFieldCase_ == OneofFieldOneofCase.BoolField) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.BoolValue) oneofField_)); + size += _oneof_boolField_codec.CalculateSizeWithTag(BoolField); } if (oneofFieldCase_ == OneofFieldOneofCase.StringField) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.StringValue) oneofField_)); + size += _oneof_stringField_codec.CalculateSizeWithTag(StringField); } if (oneofFieldCase_ == OneofFieldOneofCase.BytesField) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(((global::Google.Protobuf.WellKnownTypes.BytesValue) oneofField_)); + size += _oneof_bytesField_codec.CalculateSizeWithTag(BytesField); } return size; } @@ -1799,93 +1971,39 @@ namespace Google.Protobuf.TestProtos { break; } case 82: { - global::Google.Protobuf.WellKnownTypes.DoubleValue subBuilder = new global::Google.Protobuf.WellKnownTypes.DoubleValue(); - if (oneofFieldCase_ == OneofFieldOneofCase.DoubleField) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.DoubleValue) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.DoubleField; - oneofField_ = subBuilder; + DoubleField = _oneof_doubleField_codec.Read(input); break; } case 90: { - global::Google.Protobuf.WellKnownTypes.FloatValue subBuilder = new global::Google.Protobuf.WellKnownTypes.FloatValue(); - if (oneofFieldCase_ == OneofFieldOneofCase.FloatField) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.FloatValue) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.FloatField; - oneofField_ = subBuilder; + FloatField = _oneof_floatField_codec.Read(input); break; } case 98: { - global::Google.Protobuf.WellKnownTypes.Int64Value subBuilder = new global::Google.Protobuf.WellKnownTypes.Int64Value(); - if (oneofFieldCase_ == OneofFieldOneofCase.Int64Field) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.Int64Value) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.Int64Field; - oneofField_ = subBuilder; + Int64Field = _oneof_int64Field_codec.Read(input); break; } case 106: { - global::Google.Protobuf.WellKnownTypes.UInt64Value subBuilder = new global::Google.Protobuf.WellKnownTypes.UInt64Value(); - if (oneofFieldCase_ == OneofFieldOneofCase.Uint64Field) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.UInt64Value) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.Uint64Field; - oneofField_ = subBuilder; + Uint64Field = _oneof_uint64Field_codec.Read(input); break; } case 114: { - global::Google.Protobuf.WellKnownTypes.Int32Value subBuilder = new global::Google.Protobuf.WellKnownTypes.Int32Value(); - if (oneofFieldCase_ == OneofFieldOneofCase.Int32Field) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.Int32Value) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.Int32Field; - oneofField_ = subBuilder; + Int32Field = _oneof_int32Field_codec.Read(input); break; } case 122: { - global::Google.Protobuf.WellKnownTypes.UInt32Value subBuilder = new global::Google.Protobuf.WellKnownTypes.UInt32Value(); - if (oneofFieldCase_ == OneofFieldOneofCase.Uint32Field) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.UInt32Value) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.Uint32Field; - oneofField_ = subBuilder; + Uint32Field = _oneof_uint32Field_codec.Read(input); break; } case 130: { - global::Google.Protobuf.WellKnownTypes.BoolValue subBuilder = new global::Google.Protobuf.WellKnownTypes.BoolValue(); - if (oneofFieldCase_ == OneofFieldOneofCase.BoolField) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.BoolValue) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.BoolField; - oneofField_ = subBuilder; + BoolField = _oneof_boolField_codec.Read(input); break; } case 138: { - global::Google.Protobuf.WellKnownTypes.StringValue subBuilder = new global::Google.Protobuf.WellKnownTypes.StringValue(); - if (oneofFieldCase_ == OneofFieldOneofCase.StringField) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.StringValue) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.StringField; - oneofField_ = subBuilder; + StringField = _oneof_stringField_codec.Read(input); break; } case 146: { - global::Google.Protobuf.WellKnownTypes.BytesValue subBuilder = new global::Google.Protobuf.WellKnownTypes.BytesValue(); - if (oneofFieldCase_ == OneofFieldOneofCase.BytesField) { - subBuilder.MergeFrom((global::Google.Protobuf.WellKnownTypes.BytesValue) oneofField_); - } - input.ReadMessage(subBuilder); - oneofFieldCase_ = OneofFieldOneofCase.BytesField; - oneofField_ = subBuilder; + BytesField = _oneof_bytesField_codec.Read(input); break; } } @@ -2042,72 +2160,72 @@ namespace Google.Protobuf.TestProtos { public const int DoubleFieldFieldNumber = 10; private static readonly pbc::MapField.Codec _map_doubleField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser), 82); - private readonly pbc::MapField doubleField_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 82); + private readonly pbc::MapField doubleField_ = new pbc::MapField(true); public pbc::MapField DoubleField { get { return doubleField_; } } public const int FloatFieldFieldNumber = 11; private static readonly pbc::MapField.Codec _map_floatField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.FloatValue.Parser), 90); - private readonly pbc::MapField floatField_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 90); + private readonly pbc::MapField floatField_ = new pbc::MapField(true); public pbc::MapField FloatField { get { return floatField_; } } public const int Int64FieldFieldNumber = 12; private static readonly pbc::MapField.Codec _map_int64Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.Int64Value.Parser), 98); - private readonly pbc::MapField int64Field_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 98); + private readonly pbc::MapField int64Field_ = new pbc::MapField(true); public pbc::MapField Int64Field { get { return int64Field_; } } public const int Uint64FieldFieldNumber = 13; private static readonly pbc::MapField.Codec _map_uint64Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.UInt64Value.Parser), 106); - private readonly pbc::MapField uint64Field_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 106); + private readonly pbc::MapField uint64Field_ = new pbc::MapField(true); public pbc::MapField Uint64Field { get { return uint64Field_; } } public const int Int32FieldFieldNumber = 14; private static readonly pbc::MapField.Codec _map_int32Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.Int32Value.Parser), 114); - private readonly pbc::MapField int32Field_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 114); + private readonly pbc::MapField int32Field_ = new pbc::MapField(true); public pbc::MapField Int32Field { get { return int32Field_; } } public const int Uint32FieldFieldNumber = 15; private static readonly pbc::MapField.Codec _map_uint32Field_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.UInt32Value.Parser), 122); - private readonly pbc::MapField uint32Field_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 122); + private readonly pbc::MapField uint32Field_ = new pbc::MapField(true); public pbc::MapField Uint32Field { get { return uint32Field_; } } public const int BoolFieldFieldNumber = 16; private static readonly pbc::MapField.Codec _map_boolField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.BoolValue.Parser), 130); - private readonly pbc::MapField boolField_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper(18), 130); + private readonly pbc::MapField boolField_ = new pbc::MapField(true); public pbc::MapField BoolField { get { return boolField_; } } public const int StringFieldFieldNumber = 17; private static readonly pbc::MapField.Codec _map_stringField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.StringValue.Parser), 138); - private readonly pbc::MapField stringField_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper(18), 138); + private readonly pbc::MapField stringField_ = new pbc::MapField(true); public pbc::MapField StringField { get { return stringField_; } } public const int BytesFieldFieldNumber = 18; private static readonly pbc::MapField.Codec _map_bytesField_codec - = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForWrapperType(18, global::Google.Protobuf.WellKnownTypes.BytesValue.Parser), 146); - private readonly pbc::MapField bytesField_ = new pbc::MapField(); + = new pbc::MapField.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper(18), 146); + private readonly pbc::MapField bytesField_ = new pbc::MapField(true); public pbc::MapField BytesField { get { return bytesField_; } } diff --git a/csharp/src/ProtocolBuffers.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/ProtocolBuffers.Test/WellKnownTypes/WrappersTest.cs index 185a277c7f..c85223f38a 100644 --- a/csharp/src/ProtocolBuffers.Test/WellKnownTypes/WrappersTest.cs +++ b/csharp/src/ProtocolBuffers.Test/WellKnownTypes/WrappersTest.cs @@ -30,8 +30,10 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion +using System; using Google.Protobuf.TestProtos; using NUnit.Framework; +using System.Collections; namespace Google.Protobuf.WellKnownTypes { @@ -52,6 +54,36 @@ namespace Google.Protobuf.WellKnownTypes Assert.IsNull(message.Uint64Field); } + [Test] + public void NonDefaultSingleValues() + { + var message = new TestWellKnownTypes + { + StringField = "x", + BytesField = ByteString.CopyFrom(1, 2, 3), + BoolField = true, + FloatField = 12.5f, + DoubleField = 12.25d, + Int32Field = 1, + Int64Field = 2, + Uint32Field = 3, + Uint64Field = 4 + }; + + var bytes = message.ToByteArray(); + var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes); + + Assert.AreEqual("x", parsed.StringField); + Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField); + Assert.AreEqual(true, parsed.BoolField); + Assert.AreEqual(12.5f, parsed.FloatField); + Assert.AreEqual(12.25d, parsed.DoubleField); + Assert.AreEqual(1, parsed.Int32Field); + Assert.AreEqual(2L, parsed.Int64Field); + Assert.AreEqual(3U, parsed.Uint32Field); + Assert.AreEqual(4UL, parsed.Uint64Field); + } + [Test] public void NonNullDefaultIsPreservedThroughSerialization() { @@ -71,15 +103,152 @@ namespace Google.Protobuf.WellKnownTypes var bytes = message.ToByteArray(); var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes); - Assert.AreEqual("", message.StringField); - Assert.AreEqual(ByteString.Empty, message.BytesField); - Assert.AreEqual(false, message.BoolField); - Assert.AreEqual(0f, message.FloatField); - Assert.AreEqual(0d, message.DoubleField); - Assert.AreEqual(0, message.Int32Field); - Assert.AreEqual(0L, message.Int64Field); - Assert.AreEqual(0U, message.Uint32Field); - Assert.AreEqual(0UL, message.Uint64Field); + Assert.AreEqual("", parsed.StringField); + Assert.AreEqual(ByteString.Empty, parsed.BytesField); + Assert.AreEqual(false, parsed.BoolField); + Assert.AreEqual(0f, parsed.FloatField); + Assert.AreEqual(0d, parsed.DoubleField); + Assert.AreEqual(0, parsed.Int32Field); + Assert.AreEqual(0L, parsed.Int64Field); + Assert.AreEqual(0U, parsed.Uint32Field); + Assert.AreEqual(0UL, parsed.Uint64Field); + } + + [Test] + public void RepeatedWrappersProhibitNullItems() + { + var message = new RepeatedWellKnownTypes(); + Assert.Throws(() => message.BoolField.Add((bool?) null)); + Assert.Throws(() => message.Int32Field.Add((int?) null)); + Assert.Throws(() => message.StringField.Add((string) null)); + Assert.Throws(() => message.BytesField.Add((ByteString) null)); + } + + [Test] + public void RepeatedWrappersSerializeDeserialize() + { + var message = new RepeatedWellKnownTypes + { + BoolField = { true, false }, + BytesField = { ByteString.CopyFrom(1, 2, 3), ByteString.CopyFrom(4, 5, 6), ByteString.Empty }, + DoubleField = { 12.5, -1.5, 0d }, + FloatField = { 123.25f, -20f, 0f }, + Int32Field = { int.MaxValue, int.MinValue, 0 }, + Int64Field = { long.MaxValue, long.MinValue, 0L }, + StringField = { "First", "Second", "" }, + Uint32Field = { uint.MaxValue, uint.MinValue, 0U }, + Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL }, + }; + var bytes = message.ToByteArray(); + var parsed = RepeatedWellKnownTypes.Parser.ParseFrom(bytes); + + Assert.AreEqual(message, parsed); + // Just to test a single value for sanity... + Assert.AreEqual("Second", message.StringField[1]); + } + + [Test] + public void MapWrappersSerializeDeserialize() + { + var message = new MapWellKnownTypes + { + BoolField = { { 10, false }, { 20, true } }, + BytesField = { + { -1, ByteString.CopyFrom(1, 2, 3) }, + { 10, ByteString.CopyFrom(4, 5, 6) }, + { 1000, ByteString.Empty }, + { 10000, null } + }, + DoubleField = { { 1, 12.5 }, { 10, -1.5 }, { 20, 0d } }, + FloatField = { { 2, 123.25f }, { 3, -20f }, { 4, 0f } }, + Int32Field = { { 5, int.MaxValue }, { 6, int.MinValue }, { 7, 0 } }, + Int64Field = { { 8, long.MaxValue }, { 9, long.MinValue }, { 10, 0L } }, + StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" }, { 14, null } }, + Uint32Field = { { 15, uint.MaxValue }, { 16, uint.MinValue }, { 17, 0U } }, + Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } }, + }; + } + + [Test] + public void Reflection_SingleValues() + { + var message = new TestWellKnownTypes + { + StringField = "x", + BytesField = ByteString.CopyFrom(1, 2, 3), + BoolField = true, + FloatField = 12.5f, + DoubleField = 12.25d, + Int32Field = 1, + Int64Field = 2, + Uint32Field = 3, + Uint64Field = 4 + }; + var fields = ((IReflectedMessage) message).Fields; + + Assert.AreEqual("x", fields[TestWellKnownTypes.StringFieldFieldNumber].GetValue(message)); + Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), fields[TestWellKnownTypes.BytesFieldFieldNumber].GetValue(message)); + Assert.AreEqual(true, fields[TestWellKnownTypes.BoolFieldFieldNumber].GetValue(message)); + Assert.AreEqual(12.5f, fields[TestWellKnownTypes.FloatFieldFieldNumber].GetValue(message)); + Assert.AreEqual(12.25d, fields[TestWellKnownTypes.DoubleFieldFieldNumber].GetValue(message)); + Assert.AreEqual(1, fields[TestWellKnownTypes.Int32FieldFieldNumber].GetValue(message)); + Assert.AreEqual(2L, fields[TestWellKnownTypes.Int64FieldFieldNumber].GetValue(message)); + Assert.AreEqual(3U, fields[TestWellKnownTypes.Uint32FieldFieldNumber].GetValue(message)); + Assert.AreEqual(4UL, fields[TestWellKnownTypes.Uint64FieldFieldNumber].GetValue(message)); + + // And a couple of null fields... + message.StringField = null; + message.FloatField = null; + Assert.IsNull(fields[TestWellKnownTypes.StringFieldFieldNumber].GetValue(message)); + Assert.IsNull(fields[TestWellKnownTypes.FloatFieldFieldNumber].GetValue(message)); + } + + [Test] + public void Reflection_RepeatedFields() + { + // Just a single example... note that we can't have a null value here + var message = new RepeatedWellKnownTypes { Int32Field = { 1, 2 } }; + var fields = ((IReflectedMessage) message).Fields; + var list = (IList) fields[RepeatedWellKnownTypes.Int32FieldFieldNumber].GetValue(message); + CollectionAssert.AreEqual(new[] { 1, 2 }, list); + } + + [Test] + public void Reflection_MapFields() + { + // Just a single example... note that we can't have a null value here + var message = new MapWellKnownTypes { Int32Field = { { 1, 2 }, { 3, null } } }; + var fields = ((IReflectedMessage) message).Fields; + var dictionary = (IDictionary) fields[MapWellKnownTypes.Int32FieldFieldNumber].GetValue(message); + Assert.AreEqual(2, dictionary[1]); + Assert.IsNull(dictionary[3]); + Assert.IsTrue(dictionary.Contains(3)); + } + + // Merging is odd with wrapper types, due to the way that default values aren't emitted in + // the binary stream. In fact we cheat a little bit - a message with an explicitly present default + // value will have that default value ignored. + [Test] + [TestCase("x", "y", "y")] + [TestCase("x", "", "x")] + [TestCase("x", null, "x")] + [TestCase("", "y", "y")] + [TestCase("", "", "")] + [TestCase("", null, "")] + [TestCase(null, "y", "y")] + [TestCase(null, "", "")] + [TestCase(null, null, null)] + public void Merging(string original, string merged, string expected) + { + var originalMessage = new TestWellKnownTypes { StringField = original }; + var mergingMessage = new TestWellKnownTypes { StringField = merged }; + originalMessage.MergeFrom(mergingMessage); + Assert.AreEqual(expected, originalMessage.StringField); + + // Try it using MergeFrom(CodedInputStream) too... + originalMessage = new TestWellKnownTypes { StringField = original }; + originalMessage.MergeFrom(mergingMessage.ToByteArray()); + Assert.AreEqual(expected, originalMessage.StringField); } } } diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs index a3e7c1bba1..bf221c9c0a 100644 --- a/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs +++ b/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs @@ -129,8 +129,7 @@ namespace Google.Protobuf public static int ComputeStringSize(String value) { int byteArraySize = Utf8Encoding.GetByteCount(value); - return ComputeRawVarint32Size((uint) byteArraySize) + - byteArraySize; + return ComputeLengthSize(byteArraySize) + byteArraySize; } /// @@ -149,7 +148,7 @@ namespace Google.Protobuf public static int ComputeMessageSize(IMessage value) { int size = value.CalculateSize(); - return ComputeRawVarint32Size((uint) size) + size; + return ComputeLengthSize(size) + size; } /// @@ -158,8 +157,7 @@ namespace Google.Protobuf /// public static int ComputeBytesSize(ByteString value) { - return ComputeRawVarint32Size((uint) value.Length) + - value.Length; + return ComputeLengthSize(value.Length) + value.Length; } /// diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.cs index 53f04c77e7..b91d6d70b8 100644 --- a/csharp/src/ProtocolBuffers/CodedOutputStream.cs +++ b/csharp/src/ProtocolBuffers/CodedOutputStream.cs @@ -274,7 +274,7 @@ namespace Google.Protobuf /// The value to write public void WriteMessage(IMessage value) { - WriteRawVarint32((uint) value.CalculateSize()); + WriteLength(value.CalculateSize()); value.WriteTo(this); } @@ -285,7 +285,7 @@ namespace Google.Protobuf /// The value to write public void WriteBytes(ByteString value) { - WriteRawVarint32((uint) value.Length); + WriteLength(value.Length); value.WriteRawBytesTo(this); } diff --git a/csharp/src/ProtocolBuffers/Collections/MapField.cs b/csharp/src/ProtocolBuffers/Collections/MapField.cs index 0f379eaa65..ead4573767 100644 --- a/csharp/src/ProtocolBuffers/Collections/MapField.cs +++ b/csharp/src/ProtocolBuffers/Collections/MapField.cs @@ -51,14 +51,38 @@ namespace Google.Protobuf.Collections public sealed class MapField : IDeepCloneable>, IFreezable, IDictionary, IEquatable>, IDictionary { // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.) + private bool allowNullValues; private bool frozen; private readonly Dictionary>> map = new Dictionary>>(); private readonly LinkedList> list = new LinkedList>(); + /// + /// Constructs a new map field, defaulting the value nullability to only allow null values for message types + /// and non-nullable value types. + /// + public MapField() : this(typeof(IMessage).IsAssignableFrom(typeof(TValue)) || Nullable.GetUnderlyingType(typeof(TValue)) != null) + { + } + + /// + /// Constructs a new map field, overriding the choice of whether null values are permitted in the map. + /// This is used by wrapper types, where maps with string and bytes wrappers as the value types + /// support null values. + /// + /// Whether null values are permitted in the map or not. + public MapField(bool allowNullValues) + { + if (allowNullValues && typeof(TValue).IsValueType && Nullable.GetUnderlyingType(typeof(TValue)) == null) + { + throw new ArgumentException("allowNullValues", "Non-nullable value types do not support null values"); + } + this.allowNullValues = allowNullValues; + } + public MapField Clone() { - var clone = new MapField(); + var clone = new MapField(allowNullValues); // Keys are never cloneable. Values might be. if (typeof(IDeepCloneable).IsAssignableFrom(typeof(TValue))) { @@ -138,7 +162,8 @@ namespace Google.Protobuf.Collections set { ThrowHelper.ThrowIfNull(key, "key"); - if (value == null && (typeof(TValue) == typeof(ByteString) || typeof(TValue) == typeof(string))) + // value == null check here is redundant, but avoids boxing. + if (value == null && !allowNullValues) { ThrowHelper.ThrowIfNull(value, "value"); } @@ -225,6 +250,11 @@ namespace Google.Protobuf.Collections } } + /// + /// Returns whether or not this map allows values to be null. + /// + public bool AllowsNullValues { get { return allowNullValues; } } + public int Count { get { return list.Count; } } public bool IsReadOnly { get { return frozen; } } diff --git a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs index 8375ae0b39..9bab41eac5 100644 --- a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs +++ b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs @@ -123,7 +123,7 @@ namespace Google.Protobuf.Collections { int dataSize = CalculatePackedDataSize(codec); return CodedOutputStream.ComputeRawVarint32Size(tag) + - CodedOutputStream.ComputeRawVarint32Size((uint)dataSize) + + CodedOutputStream.ComputeLengthSize(dataSize) + dataSize; } else diff --git a/csharp/src/ProtocolBuffers/FieldCodec.cs b/csharp/src/ProtocolBuffers/FieldCodec.cs index c72a3e7b31..caf032864e 100644 --- a/csharp/src/ProtocolBuffers/FieldCodec.cs +++ b/csharp/src/ProtocolBuffers/FieldCodec.cs @@ -29,7 +29,7 @@ // (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.Generic; @@ -43,7 +43,7 @@ namespace Google.Protobuf // TODO: Avoid the "dual hit" of lambda expressions: create open delegates instead. (At least test...) public static FieldCodec ForString(uint tag) { - return new FieldCodec(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag); + return new FieldCodec(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag); } public static FieldCodec ForBytes(uint tag) @@ -131,6 +131,106 @@ namespace Google.Protobuf return new FieldCodec(input => { T message = parser.CreateTemplate(); input.ReadMessage(message); return message; }, (output, value) => output.WriteMessage(value), message => CodedOutputStream.ComputeMessageSize(message), tag); } + + /// + /// Creates a codec for a wrapper type of a class - which must be string or ByteString. + /// + public static FieldCodec ForClassWrapper(uint tag) where T : class + { + var nestedCodec = WrapperCodecs.GetCodec(); + return new FieldCodec( + input => WrapperCodecs.Read(input, nestedCodec), + (output, value) => WrapperCodecs.Write(output, value, nestedCodec), + value => WrapperCodecs.CalculateSize(value, nestedCodec), + tag, + null); // Default value for the wrapper + } + + /// + /// Creates a codec for a wrapper type of a struct - which must be Int32, Int64, UInt32, UInt64, + /// Bool, Single or Double. + /// + public static FieldCodec ForStructWrapper(uint tag) where T : struct + { + var nestedCodec = WrapperCodecs.GetCodec(); + return new FieldCodec( + input => WrapperCodecs.Read(input, nestedCodec), + (output, value) => WrapperCodecs.Write(output, value.Value, nestedCodec), + value => value == null ? 0 : WrapperCodecs.CalculateSize(value.Value, nestedCodec), + tag, + null); // Default value for the wrapper + } + + // Helper code to create codecs for wrapper types. Somewhat ugly with all the + private static class WrapperCodecs + { + private static readonly Dictionary Codecs = new Dictionary + { + { typeof(bool), ForBool(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, + { typeof(int), ForInt32(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, + { typeof(long), ForInt64(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, + { typeof(uint), ForUInt32(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, + { typeof(ulong), ForUInt64(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, + { typeof(float), ForFloat(WireFormat.MakeTag(1, WireFormat.WireType.Fixed32)) }, + { typeof(double), ForDouble(WireFormat.MakeTag(1, WireFormat.WireType.Fixed64)) }, + { typeof(string), ForString(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited)) }, + { typeof(ByteString), ForBytes(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited)) } + }; + + /// + /// Returns a field codec which effectively wraps a value of type T in a message. + /// + /// + internal static FieldCodec GetCodec() + { + object value; + if (!Codecs.TryGetValue(typeof(T), out value)) + { + throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T)); + } + return (FieldCodec) value; + } + + internal static T Read(CodedInputStream input, FieldCodec codec) + { + int length = input.ReadLength(); + int oldLimit = input.PushLimit(length); + + uint tag; + T value = codec.DefaultValue; + while (input.ReadTag(out tag)) + { + if (tag == 0) + { + throw InvalidProtocolBufferException.InvalidTag(); + } + if (tag == codec.Tag) + { + value = codec.Read(input); + } + if (WireFormat.IsEndGroupTag(tag)) + { + break; + } + } + input.CheckLastTagWas(0); + input.PopLimit(oldLimit); + + return value; + } + + internal static void Write(CodedOutputStream output, T value, FieldCodec codec) + { + output.WriteLength(codec.CalculateSizeWithTag(value)); + codec.WriteTagAndValue(output, value); + } + + internal static int CalculateSize(T value, FieldCodec codec) + { + int fieldLength = codec.CalculateSizeWithTag(value); + return CodedOutputStream.ComputeLengthSize(fieldLength) + fieldLength; + } + } } /// @@ -144,31 +244,19 @@ namespace Google.Protobuf /// public sealed class FieldCodec { - private static readonly Func IsDefault; - private static readonly T Default; + private static readonly T DefaultDefault; static FieldCodec() { if (typeof(T) == typeof(string)) { - Default = (T)(object)""; - IsDefault = CreateDefaultValueCheck(x => x.Length == 0); + DefaultDefault = (T)(object)""; } else if (typeof(T) == typeof(ByteString)) { - Default = (T)(object)ByteString.Empty; - IsDefault = CreateDefaultValueCheck(x => x.Length == 0); - } - else if (!typeof(T).IsValueType) - { - // Default default - IsDefault = CreateDefaultValueCheck(x => x == null); - } - else - { - // Default default - IsDefault = CreateDefaultValueCheck(x => EqualityComparer.Default.Equals(x, default(T))); + DefaultDefault = (T)(object)ByteString.Empty; } + // Otherwise it's the default value of the CLR type } private static Func CreateDefaultValueCheck(Func check) @@ -182,18 +270,32 @@ namespace Google.Protobuf private readonly uint tag; private readonly int tagSize; private readonly int fixedSize; + // Default value for this codec. Usually the same for every instance of the same type, but + // for string/ByteString wrapper fields the codec's default value is null, whereas for + // other string/ByteString fields it's "" or ByteString.Empty. + private readonly T defaultValue; internal FieldCodec( Func reader, Action writer, Func sizeCalculator, - uint tag) + uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault) + { + } + + internal FieldCodec( + Func reader, + Action writer, + Func sizeCalculator, + uint tag, + T defaultValue) { this.reader = reader; this.writer = writer; this.sizeCalculator = sizeCalculator; this.fixedSize = 0; this.tag = tag; + this.defaultValue = defaultValue; tagSize = CodedOutputStream.ComputeRawVarint32Size(tag); } @@ -234,7 +336,7 @@ namespace Google.Protobuf public uint Tag { get { return tag; } } - public T DefaultValue { get { return Default; } } + public T DefaultValue { get { return defaultValue; } } /// /// Write a tag and the given value, *if* the value is not the default. @@ -260,6 +362,11 @@ namespace Google.Protobuf public int CalculateSizeWithTag(T value) { return IsDefault(value) ? 0 : sizeCalculator(value) + tagSize; - } + } + + private bool IsDefault(T value) + { + return EqualityComparer.Default.Equals(value, defaultValue); + } } } diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index f36e6fdecf..1f583e0886 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -309,14 +309,23 @@ std::string FieldGeneratorBase::GetBytesDefaultValueInternal() { } std::string FieldGeneratorBase::default_value() { - switch (descriptor_->type()) { + return default_value(descriptor_); +} + +std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor) { + switch (descriptor->type()) { case FieldDescriptor::TYPE_ENUM: - return type_name() + "." + descriptor_->default_value_enum()->name(); + return type_name() + "." + descriptor->default_value_enum()->name(); case FieldDescriptor::TYPE_MESSAGE: case FieldDescriptor::TYPE_GROUP: - return type_name() + ".DefaultInstance"; + if (IsWrapperType(descriptor)) { + const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0); + return default_value(wrapped_field); + } else { + return "null"; + } case FieldDescriptor::TYPE_DOUBLE: { - double value = descriptor_->default_value_double(); + double value = descriptor->default_value_double(); if (value == numeric_limits::infinity()) { return "double.PositiveInfinity"; } else if (value == -numeric_limits::infinity()) { @@ -327,7 +336,7 @@ std::string FieldGeneratorBase::default_value() { return SimpleDtoa(value) + "D"; } case FieldDescriptor::TYPE_FLOAT: { - float value = descriptor_->default_value_float(); + float value = descriptor->default_value_float(); if (value == numeric_limits::infinity()) { return "float.PositiveInfinity"; } else if (value == -numeric_limits::infinity()) { @@ -338,17 +347,17 @@ std::string FieldGeneratorBase::default_value() { return SimpleFtoa(value) + "F"; } case FieldDescriptor::TYPE_INT64: - return SimpleItoa(descriptor_->default_value_int64()) + "L"; + return SimpleItoa(descriptor->default_value_int64()) + "L"; case FieldDescriptor::TYPE_UINT64: - return SimpleItoa(descriptor_->default_value_uint64()) + "UL"; + return SimpleItoa(descriptor->default_value_uint64()) + "UL"; case FieldDescriptor::TYPE_INT32: - return SimpleItoa(descriptor_->default_value_int32()); + return SimpleItoa(descriptor->default_value_int32()); case FieldDescriptor::TYPE_FIXED64: - return SimpleItoa(descriptor_->default_value_uint64()) + "UL"; + return SimpleItoa(descriptor->default_value_uint64()) + "UL"; case FieldDescriptor::TYPE_FIXED32: - return SimpleItoa(descriptor_->default_value_uint32()); + return SimpleItoa(descriptor->default_value_uint32()); case FieldDescriptor::TYPE_BOOL: - if (descriptor_->default_value_bool()) { + if (descriptor->default_value_bool()) { return "true"; } else { return "false"; @@ -358,15 +367,15 @@ std::string FieldGeneratorBase::default_value() { case FieldDescriptor::TYPE_BYTES: return GetBytesDefaultValueInternal(); case FieldDescriptor::TYPE_UINT32: - return SimpleItoa(descriptor_->default_value_uint32()); + return SimpleItoa(descriptor->default_value_uint32()); case FieldDescriptor::TYPE_SFIXED32: - return SimpleItoa(descriptor_->default_value_int32()); + return SimpleItoa(descriptor->default_value_int32()); case FieldDescriptor::TYPE_SFIXED64: - return SimpleItoa(descriptor_->default_value_int64()) + "L"; + return SimpleItoa(descriptor->default_value_int64()) + "L"; case FieldDescriptor::TYPE_SINT32: - return SimpleItoa(descriptor_->default_value_int32()); + return SimpleItoa(descriptor->default_value_int32()); case FieldDescriptor::TYPE_SINT64: - return SimpleItoa(descriptor_->default_value_int64()) + "L"; + return SimpleItoa(descriptor->default_value_int64()) + "L"; default: GOOGLE_LOG(FATAL)<< "Unknown field type."; return ""; diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index bffa206239..4761dc4992 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -82,6 +82,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { bool has_default_value(); bool is_nullable_type(); std::string default_value(); + std::string default_value(const FieldDescriptor* descriptor); std::string number(); std::string capitalized_type_name(); std::string field_ordinal(); diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index 32c05232c4..cba24a59a3 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -61,6 +61,7 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { descriptor_->message_type()->FindFieldByName("value"); variables_["key_type_name"] = type_name(key_descriptor); variables_["value_type_name"] = type_name(value_descriptor); + variables_["true_for_wrappers"] = IsWrapperType(value_descriptor) ? "true" : ""; scoped_ptr key_generator(CreateFieldGenerator(key_descriptor, 1)); scoped_ptr value_generator(CreateFieldGenerator(value_descriptor, 2)); @@ -74,7 +75,7 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, ", $tag$);\n" - "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>();\n"); + "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>($true_for_wrappers$);\n"); AddDeprecatedFlag(printer); printer->Print( variables_, 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 6d4e698434..d939fc7983 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -39,6 +39,8 @@ #include #include +#include +#include namespace google { namespace protobuf { @@ -58,7 +60,18 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" - " = pb::FieldCodec.ForMessage($tag$, $type_name$.Parser);\n"); + " = "); + // Don't want to duplicate the codec code here... maybe we should have a + // "create single field generator for this repeated field" + // function, but it doesn't seem worth it for just this. + if (IsWrapperType(descriptor_)) { + scoped_ptr single_generator(new WrapperFieldGenerator(descriptor_, fieldOrdinal_)); + single_generator->GenerateCodecCode(printer); + } else { + scoped_ptr single_generator(new MessageFieldGenerator(descriptor_, fieldOrdinal_)); + single_generator->GenerateCodecCode(printer); + } + printer->Print(";\n"); printer->Print( variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index eb3791ec84..75ef5e50c2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -50,35 +50,34 @@ WrapperFieldGenerator::WrapperFieldGenerator(const FieldDescriptor* descriptor, : FieldGeneratorBase(descriptor, fieldOrdinal) { variables_["has_property_check"] = name() + "_ != null"; variables_["has_not_property_check"] = name() + "_ == null"; - variables_["message_type_name"] = GetClassName(descriptor->message_type()); const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0); is_value_type = wrapped_field->type() != FieldDescriptor::TYPE_STRING && wrapped_field->type() != FieldDescriptor::TYPE_BYTES; - variables_["deref"] = is_value_type ? ".Value" : ""; - // This will always be a single byte, because it's always field 1. - variables_["message_tag_bytes"] = SimpleItoa(FixedMakeTag(wrapped_field)); + if (is_value_type) { + variables_["nonnullable_type_name"] = type_name(wrapped_field); + } } WrapperFieldGenerator::~WrapperFieldGenerator() { } void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) { - // Back the underlying property with an underlying message. This isn't efficient, - // but it makes it easier to be compliant with what platforms which don't support wrapper - // types would do. Currently, each time the value is changed, we create a new instance. - // With suitable care to avoid aliasing, we could probably check whether or not we've already - // got an instance, and simply mutate the existing one. + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _single_$name$_codec = "); + GenerateCodecCode(printer); printer->Print( variables_, - "private $message_type_name$ $name$_;\n"); + ";\n" + "private $type_name$ $name$_;\n"); AddDeprecatedFlag(printer); printer->Print( variables_, "$access_level$ $type_name$ $property_name$ {\n" - " get { return $name$_ == null ? ($type_name$) null : $name$_.Value; }\n" + " get { return $name$_; }\n" " set {\n" " pb::Freezable.CheckMutable(this);\n" - " $name$_ = value == null ? null : new $message_type_name$ { Value = value$deref$ };\n" + " $name$_ = value;\n" " }\n" "}\n"); } @@ -87,28 +86,26 @@ void WrapperFieldGenerator::GenerateMergingCode(io::Printer* printer) { printer->Print( variables_, "if (other.$has_property_check$) {\n" - " if ($has_not_property_check$) {\n" - " $name$_ = new $message_type_name$();\n" + " if ($has_not_property_check$ || other.$property_name$ != $default_value$) {\n" + " $property_name$ = other.$property_name$;\n" " }\n" - " $name$_.MergeFrom(other.$name$_);\n" "}\n"); } void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, - "if ($has_not_property_check$) {\n" - " $name$_ = new $message_type_name$();\n" - "}\n" - "input.ReadMessage($name$_);\n"); // No need to support TYPE_GROUP... + "$type_name$ value = _single_$name$_codec.Read(input);\n" + "if ($has_not_property_check$ || value != $default_value$) {\n" + " $property_name$ = value;\n" + "}\n"); } void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer) { printer->Print( variables_, "if ($has_property_check$) {\n" - " output.WriteRawTag($tag_bytes$);\n" - " output.WriteMessage($name$_);\n" + " _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n" "}\n"); } @@ -116,7 +113,7 @@ void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( variables_, "if ($has_property_check$) {\n" - " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($name$_);\n" + " size += _single_$name$_codec.CalculateSizeWithTag($property_name$);\n" "}\n"); } @@ -137,16 +134,20 @@ void WrapperFieldGenerator::WriteToString(io::Printer* printer) { } void WrapperFieldGenerator::GenerateCloningCode(io::Printer* printer) { - // This will effectively perform a deep clone - it will create a new - // underlying message if necessary printer->Print(variables_, "$property_name$ = other.$property_name$;\n"); } void WrapperFieldGenerator::GenerateCodecCode(io::Printer* printer) { - printer->Print( - variables_, - "pb::FieldCodec.ForWrapperType<$type_name$, $message_type_name$>($tag$, $message_type_name$.Parser)"); + if (is_value_type) { + printer->Print( + variables_, + "pb::FieldCodec.ForStructWrapper<$nonnullable_type_name$>($tag$)"); + } else { + printer->Print( + variables_, + "pb::FieldCodec.ForClassWrapper<$type_name$>($tag$)"); + } } WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(const FieldDescriptor* descriptor, @@ -159,48 +160,46 @@ WrapperOneofFieldGenerator::~WrapperOneofFieldGenerator() { } void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { + // Note: deliberately _oneof_$name$_codec, not _$oneof_name$_codec... we have one codec per field. + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _oneof_$name$_codec = "); + GenerateCodecCode(printer); + printer->Print(";\n"); AddDeprecatedFlag(printer); printer->Print( variables_, "$access_level$ $type_name$ $property_name$ {\n" - " get { return $has_property_check$ ? (($message_type_name$) $oneof_name$_).Value : ($type_name$) null; }\n" + " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : ($type_name$) null; }\n" " set {\n" " pb::Freezable.CheckMutable(this);\n" - " $oneof_name$_ = value == null ? null : new $message_type_name$ { Value = value$deref$ };\n" + " $oneof_name$_ = value;\n" " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" " }\n" "}\n"); } - - void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, - "$message_type_name$ subBuilder = new $message_type_name$();\n" - "if ($has_property_check$) {\n" - " subBuilder.MergeFrom(($message_type_name$) $oneof_name$_);\n" - "}\n" - "input.ReadMessage(subBuilder);\n" - // Don't set the property, which would create a new and equivalent message; just set the two fields. - "$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n" - "$oneof_name$_ = subBuilder;\n"); + "$property_name$ = _oneof_$name$_codec.Read(input);\n"); } void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + // TODO: I suspect this is wrong... printer->Print( variables_, "if ($has_property_check$) {\n" - " output.WriteRawTag($tag_bytes$);\n" - " output.WriteMessage(($message_type_name$) $oneof_name$_);\n" + " _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n" "}\n"); } void WrapperOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { + // TODO: I suspect this is wrong... printer->Print( variables_, "if ($has_property_check$) {\n" - " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize((($message_type_name$) $oneof_name$_));\n" + " size += _oneof_$name$_codec.CalculateSizeWithTag($property_name$);\n" "}\n"); } diff --git a/src/google/protobuf/unittest_well_known_types.proto b/src/google/protobuf/unittest_well_known_types.proto index 4771c09462..2cb7775ccf 100644 --- a/src/google/protobuf/unittest_well_known_types.proto +++ b/src/google/protobuf/unittest_well_known_types.proto @@ -52,16 +52,16 @@ message RepeatedWellKnownTypes { repeated google.protobuf.Struct struct_field = 7; repeated google.protobuf.Timestamp timestamp_field = 8; repeated google.protobuf.Type type_field = 9; - // TODO: Do these even make sense? Should they be prohibited? -// repeated google.protobuf.DoubleValue double_field = 10; -// repeated google.protobuf.FloatValue float_field = 11; -// repeated google.protobuf.Int64Value int64_field = 12; -// repeated google.protobuf.UInt64Value uint64_field = 13; -// repeated google.protobuf.Int32Value int32_field = 14; -// repeated google.protobuf.UInt32Value uint32_field = 15; -// repeated google.protobuf.BoolValue bool_field = 16; -// repeated google.protobuf.StringValue string_field = 17; -// repeated google.protobuf.BytesValue bytes_field = 18; + // These don't actually make a lot of sense, but they're not prohibited... + repeated google.protobuf.DoubleValue double_field = 10; + repeated google.protobuf.FloatValue float_field = 11; + repeated google.protobuf.Int64Value int64_field = 12; + repeated google.protobuf.UInt64Value uint64_field = 13; + repeated google.protobuf.Int32Value int32_field = 14; + repeated google.protobuf.UInt32Value uint32_field = 15; + repeated google.protobuf.BoolValue bool_field = 16; + repeated google.protobuf.StringValue string_field = 17; + repeated google.protobuf.BytesValue bytes_field = 18; } message OneofWellKnownTypes {