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.
diff --git a/csharp/src/AddressBook/AddressBook.csproj b/csharp/src/AddressBook/AddressBook.csproj index bae43b4..8f8ca7e 100644 --- a/csharp/src/AddressBook/AddressBook.csproj +++ b/csharp/src/AddressBook/AddressBook.csproj
@@ -10,10 +10,11 @@ <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>Google.Protobuf.Examples.AddressBook</RootNamespace> <AssemblyName>AddressBook</AssemblyName> - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> <StartupObject>Google.Protobuf.Examples.AddressBook.Program</StartupObject> - <TargetFrameworkProfile>Client</TargetFrameworkProfile> + <TargetFrameworkProfile> + </TargetFrameworkProfile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -26,6 +27,7 @@ <WarningLevel>4</WarningLevel> <NoStdLib>true</NoStdLib> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <Prefer32Bit>false</Prefer32Bit> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -37,6 +39,7 @@ <WarningLevel>4</WarningLevel> <NoStdLib>true</NoStdLib> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <Prefer32Bit>false</Prefer32Bit> </PropertyGroup> <ItemGroup> <Reference Include="mscorlib" />
diff --git a/csharp/src/AddressBook/app.config b/csharp/src/AddressBook/app.config index 19fac17..a80813a 100644 --- a/csharp/src/AddressBook/app.config +++ b/csharp/src/AddressBook/app.config
@@ -1,3 +1,3 @@ <?xml version="1.0"?> <configuration> - <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration> + <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj index c3c9d277..a040cda 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 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <EnvironmentFlavor>CLIENTPROFILE</EnvironmentFlavor> @@ -12,9 +12,10 @@ <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>Google.Protobuf.JsonDump</RootNamespace> <AssemblyName>Google.Protobuf.JsonDump</AssemblyName> - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> - <TargetFrameworkProfile>Client</TargetFrameworkProfile> + <TargetFrameworkProfile> + </TargetFrameworkProfile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -27,6 +28,7 @@ <WarningLevel>4</WarningLevel> <NoStdLib>true</NoStdLib> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <Prefer32Bit>false</Prefer32Bit> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -38,6 +40,7 @@ <WarningLevel>4</WarningLevel> <NoStdLib>true</NoStdLib> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> + <Prefer32Bit>false</Prefer32Bit> </PropertyGroup> <ItemGroup> <Reference Include="mscorlib" />
diff --git a/csharp/src/Google.Protobuf.JsonDump/app.config b/csharp/src/Google.Protobuf.JsonDump/app.config index e2a5a18..51278a4 100644 --- a/csharp/src/Google.Protobuf.JsonDump/app.config +++ b/csharp/src/Google.Protobuf.JsonDump/app.config
@@ -1,3 +1,3 @@ <?xml version="1.0" encoding="utf-8"?> <configuration> -<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration> +<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs index 9ca5104..68f2f1c 100644 --- a/csharp/src/Google.Protobuf/Collections/MapField.cs +++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -35,6 +35,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Collections { @@ -74,7 +75,7 @@ /// <param name="allowNullValues">Whether null values are permitted in the map or not.</param> 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 9bab41e..ccd1a9b 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 @@ 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 @@ 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 @@ } 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 0000000..934424f --- /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 0000000..fbfb47f --- /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 +{ + /// <summary> + /// 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. + /// </summary> + 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 29320ca..b1f2081 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -11,8 +11,8 @@ <RootNamespace>Google.Protobuf</RootNamespace> <AssemblyName>Google.Protobuf</AssemblyName> <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> - <TargetFrameworkProfile>Profile92</TargetFrameworkProfile> - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <TargetFrameworkProfile>Profile259</TargetFrameworkProfile> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> <SignAssembly>true</SignAssembly> <AssemblyOriginatorKeyFile>..\..\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile> @@ -60,6 +60,8 @@ <Compile Include="Collections\MapField.cs" /> <Compile Include="Collections\ReadOnlyDictionary.cs" /> <Compile Include="Collections\RepeatedField.cs" /> + <Compile Include="Compatibility\PropertyInfoExtensions.cs" /> + <Compile Include="Compatibility\TypeExtensions.cs" /> <Compile Include="FieldCodec.cs" /> <Compile Include="FrameworkPortability.cs" /> <Compile Include="Freezable.cs" /> @@ -111,6 +113,7 @@ <ItemGroup> <None Include="Google.Protobuf.nuspec" /> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs b/csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs index 0893dc3..3fccf88 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldAccessorBase.cs
@@ -32,6 +32,7 @@ using System; using System.Reflection; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Reflection {
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs index a8609b8..60f2bb8 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
@@ -32,6 +32,7 @@ using System; using System.Linq; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Reflection {
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs index 20cbea9..8631a1c 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs
@@ -32,6 +32,7 @@ using System; using System.Reflection; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Reflection {
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs index cd4c553..8571a5e 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
@@ -33,6 +33,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Reflection { @@ -91,7 +92,7 @@ { throw new DescriptorValidationException(this, "Property " + clrName + "Case not found in " + containingType.GeneratedType); } - var clearMethod = containingType.GeneratedType.GetMethod("Clear" + clrName, ReflectionUtil.EmptyTypes); + var clearMethod = containingType.GeneratedType.GetMethod("Clear" + clrName); if (clearMethod == null) { throw new DescriptorValidationException(this, "Method Clear" + clrName + " not found in " + containingType.GeneratedType);
diff --git a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs index f00a51b..851efc2 100644 --- a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
@@ -32,6 +32,7 @@ using System; using System.Reflection; +using Google.Protobuf.Compatibility; namespace Google.Protobuf.Reflection {