From 0dbd5ec80d33ea2a37f5362a24fd72b2c5f51aaa Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Thu, 23 Jul 2015 15:31:34 +0100 Subject: [PATCH 1/4] First attempt at using profile 259 for Google.Protobuf. This requires .NET 4.5, and there are a few compatibility changes required around reflection. Creating a PR from this to see how our CI systems handle it. Will want to add more documentation, validation and probably tests before merging. This is in aid of issue #590. --- csharp/src/AddressBook/AddressBook.csproj | 7 +- csharp/src/AddressBook/app.config | 2 +- .../Google.Protobuf.JsonDump.csproj | 9 ++- .../src/Google.Protobuf.JsonDump/app.config | 2 +- .../Google.Protobuf/Collections/MapField.cs | 3 +- .../Collections/RepeatedField.cs | 10 +-- .../Compatibility/PropertyInfoExtensions.cs | 49 ++++++++++++++ .../Compatibility/TypeExtensions.cs | 65 +++++++++++++++++++ .../Google.Protobuf/Google.Protobuf.csproj | 7 +- .../Reflection/FieldAccessorBase.cs | 1 + .../Reflection/FieldDescriptor.cs | 1 + .../Reflection/OneofAccessor.cs | 1 + .../Reflection/OneofDescriptor.cs | 3 +- .../Reflection/SingleFieldAccessor.cs | 1 + 14 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs create mode 100644 csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs diff --git a/csharp/src/AddressBook/AddressBook.csproj b/csharp/src/AddressBook/AddressBook.csproj index bae43b40b..8f8ca7e23 100644 --- a/csharp/src/AddressBook/AddressBook.csproj +++ b/csharp/src/AddressBook/AddressBook.csproj @@ -10,10 +10,11 @@ Properties Google.Protobuf.Examples.AddressBook AddressBook - v4.0 + v4.5 512 Google.Protobuf.Examples.AddressBook.Program - Client + + true @@ -26,6 +27,7 @@ 4 true Off + false pdbonly @@ -37,6 +39,7 @@ 4 true Off + false diff --git a/csharp/src/AddressBook/app.config b/csharp/src/AddressBook/app.config index 19fac17a8..a80813afe 100644 --- a/csharp/src/AddressBook/app.config +++ b/csharp/src/AddressBook/app.config @@ -1,3 +1,3 @@ - + diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj index c3c9d277e..a040cda5f 100644 --- a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj +++ b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj @@ -1,4 +1,4 @@ - + CLIENTPROFILE @@ -12,9 +12,10 @@ Properties Google.Protobuf.JsonDump Google.Protobuf.JsonDump - v4.0 + v4.5 512 - Client + + true @@ -27,6 +28,7 @@ 4 true Off + false pdbonly @@ -38,6 +40,7 @@ 4 true Off + false diff --git a/csharp/src/Google.Protobuf.JsonDump/app.config b/csharp/src/Google.Protobuf.JsonDump/app.config index e2a5a1876..51278a456 100644 --- a/csharp/src/Google.Protobuf.JsonDump/app.config +++ b/csharp/src/Google.Protobuf.JsonDump/app.config @@ -1,3 +1,3 @@ - + diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs index 9ca5104d5..68f2f1cc2 100644 --- a/csharp/src/Google.Protobuf/Collections/MapField.cs +++ b/csharp/src/Google.Protobuf/Collections/MapField.cs @@ -35,6 +35,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Collections { @@ -74,7 +75,7 @@ namespace Google.Protobuf.Collections /// Whether null values are permitted in the map or not. public MapField(bool allowNullValues) { - if (allowNullValues && typeof(TValue).IsValueType && Nullable.GetUnderlyingType(typeof(TValue)) == null) + if (allowNullValues && typeof(TValue).IsValueType() && Nullable.GetUnderlyingType(typeof(TValue)) == null) { throw new ArgumentException("allowNullValues", "Non-nullable value types do not support null values"); } diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index 9bab41eac..ccd1a9bb3 100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs @@ -29,10 +29,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion - + +using Google.Protobuf.Reflection; using System; using System.Collections; using System.Collections.Generic; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Collections { @@ -88,7 +90,7 @@ namespace Google.Protobuf.Collections uint tag = input.LastTag; var reader = codec.ValueReader; // Value types can be packed or not. - if (typeof(T).IsValueType && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) + if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) { int length = input.ReadLength(); if (length > 0) @@ -119,7 +121,7 @@ namespace Google.Protobuf.Collections return 0; } uint tag = codec.Tag; - if (typeof(T).IsValueType && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) + if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) { int dataSize = CalculatePackedDataSize(codec); return CodedOutputStream.ComputeRawVarint32Size(tag) + @@ -165,7 +167,7 @@ namespace Google.Protobuf.Collections } var writer = codec.ValueWriter; var tag = codec.Tag; - if (typeof(T).IsValueType && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) + if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) { // Packed primitive type uint size = (uint)CalculatePackedDataSize(codec); diff --git a/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs new file mode 100644 index 000000000..934424f88 --- /dev/null +++ b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs @@ -0,0 +1,49 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System.Reflection; + +namespace Google.Protobuf.Compatibility +{ + internal static class PropertyInfoExtensions + { + internal static MethodInfo GetGetMethod(this PropertyInfo target) + { + return target.GetMethod; + } + + internal static MethodInfo GetSetMethod(this PropertyInfo target) + { + return target.SetMethod; + } + } +} diff --git a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs new file mode 100644 index 000000000..fbfb47fac --- /dev/null +++ b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs @@ -0,0 +1,65 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Reflection; + +namespace Google.Protobuf.Compatibility +{ + /// + /// Provides extension methods on Type that just proxy to TypeInfo. + /// These are used to support the new type system from .NET 4.5, without + /// having calls to GetTypeInfo all over the place. + /// + internal static class TypeExtensions + { + internal static bool IsValueType(this Type target) + { + return target.GetTypeInfo().IsValueType; + } + + internal static bool IsAssignableFrom(this Type target, Type c) + { + return target.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo()); + } + + internal static PropertyInfo GetProperty(this Type target, string name) + { + return target.GetTypeInfo().GetDeclaredProperty(name); + } + + internal static MethodInfo GetMethod(this Type target, string name) + { + return target.GetTypeInfo().GetDeclaredMethod(name); + } + } +} diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index 29320ca83..b1f20816d 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -11,8 +11,8 @@ Google.Protobuf Google.Protobuf {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Profile92 - v4.0 + Profile259 + v4.5 512 true ..\..\keys\Google.Protobuf.snk @@ -60,6 +60,8 @@ + + @@ -111,6 +113,7 @@ +