From 17df1f8cf59b88ca6df78ebc736ae038dd3bbfbe Mon Sep 17 00:00:00 2001
From: kkm <kkm@smartaction.com>
Date: Wed, 13 Jun 2018 18:27:07 -0700
Subject: [PATCH] fixup! Add Grpc.Tools MsBuild taks assembly, test and
 scripting

---
 .../Grpc.Tools.Tests/Grpc.Tools.Tests.csproj  |  14 +-
 src/csharp/Grpc.Tools/Common.cs               |  12 +-
 src/csharp/Grpc.Tools/DepFileUtil.cs          | 103 +++++++----
 src/csharp/Grpc.Tools/GeneratorServices.cs    |  12 +-
 src/csharp/Grpc.Tools/Grpc.Tools.csproj       |  31 ++--
 src/csharp/Grpc.Tools/ProtoCompile.cs         | 170 +++++++++---------
 src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs |   2 +-
 .../Grpc.Tools/ProtoReadDependencies.cs       |   2 +-
 .../_protobuf/Google.Protobuf.Tools.targets   |   4 +-
 9 files changed, 201 insertions(+), 149 deletions(-)

diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
index 585e4518b5..661d97d81b 100644
--- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
+++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
@@ -1,23 +1,25 @@
 <Project Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
+  <Import Project="..\Grpc.Core\Version.csproj.include" />
+
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp1.0;net45</TargetFrameworks>
+    <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
     <OutputType>Exe</OutputType>
   </PropertyGroup>
 
+  <Import Project="..\Grpc.Core\SourceLink.csproj.include" />
+
   <ItemGroup>
     <ProjectReference Include="..\Grpc.Tools\Grpc.Tools.csproj" />
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Moq" Version="4.7.145" />
-    <PackageReference Include="NUnit" Version="3.9.0" />
-    <PackageReference Include="NUnitLite" Version="3.9.0" />
+    <PackageReference Include="Moq" Version="4.8.3" />
+    <PackageReference Include="NUnit; NUnitLite" Version="3.10.1" />
   </ItemGroup>
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">
-    <PackageReference Include="Microsoft.Build.Framework" Version="15.5.180" />
-    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.5.180" />
+    <PackageReference Include="Microsoft.Build.Framework; Microsoft.Build.Utilities.Core" Version="15.6.85" />
   </ItemGroup>
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
diff --git a/src/csharp/Grpc.Tools/Common.cs b/src/csharp/Grpc.Tools/Common.cs
index df539f8c4f..1ebd386bd1 100644
--- a/src/csharp/Grpc.Tools/Common.cs
+++ b/src/csharp/Grpc.Tools/Common.cs
@@ -25,15 +25,15 @@ using System.Security;
 [assembly: InternalsVisibleTo("Grpc.Tools.Tests")]
 
 namespace Grpc.Tools {
-  // Metadata names that we refer to often.
+  // Metadata names (MSBuild item attributes) that we refer to often.
   static class Metadata {
     // On output dependency lists.
-    public static string kSource = "Source";
+    public static string Source = "Source";
     // On ProtoBuf items.
-    public static string kProtoRoot = "ProtoRoot";
-    public static string kOutputDir = "OutputDir";
-    public static string kGrpcServices = "GrpcServices";
-    public static string kGrpcOutputDir = "GrpcOutputDir";
+    public static string ProtoRoot = "ProtoRoot";
+    public static string OutputDir = "OutputDir";
+    public static string GrpcServices = "GrpcServices";
+    public static string GrpcOutputDir = "GrpcOutputDir";
   };
 
   // A few flags used to control the behavior under various platforms.
diff --git a/src/csharp/Grpc.Tools/DepFileUtil.cs b/src/csharp/Grpc.Tools/DepFileUtil.cs
index 2a931b7295..e635ad1e85 100644
--- a/src/csharp/Grpc.Tools/DepFileUtil.cs
+++ b/src/csharp/Grpc.Tools/DepFileUtil.cs
@@ -25,29 +25,38 @@ using Microsoft.Build.Utilities;
 
 namespace Grpc.Tools {
   internal static class DepFileUtil {
-/*
-   Sample dependency files. Notable features we have to deal with:
-    * Slash doubling, must normalize them.
-    * Spaces in file names. Cannot just "unwrap" the line on backslash at eof;
-      rather, treat every line as containing one file name except for one with
-      the ':' separator, as containing exactly two.
-    * Deal with ':' also being drive letter separator (second example).
-
-obj\Release\net45\/Foo.cs \
-obj\Release\net45\/FooGrpc.cs: C:/foo/include/google/protobuf/wrappers.proto\
- C:/projects/foo/src//foo.proto
-
-C:\projects\foo\src\./foo.grpc.pb.cc \
-C:\projects\foo\src\./foo.grpc.pb.h \
-C:\projects\foo\src\./foo.pb.cc \
-C:\projects\foo\src\./foo.pb.h: C:/foo/include/google/protobuf/wrappers.proto\
- C:/foo/include/google/protobuf/any.proto\
- C:/foo/include/google/protobuf/source_context.proto\
- C:/foo/include/google/protobuf/type.proto\
- foo.proto
-*/
-
-    // Read file names from the dependency file to the right of ':'.
+  /*
+     Sample dependency files. Notable features we have to deal with:
+      * Slash doubling, must normalize them.
+      * Spaces in file names. Cannot just "unwrap" the line on backslash at eof;
+        rather, treat every line as containing one file name except for one with
+        the ':' separator, as containing exactly two.
+      * Deal with ':' also being drive letter separator (second example).
+
+  obj\Release\net45\/Foo.cs \
+  obj\Release\net45\/FooGrpc.cs: C:/foo/include/google/protobuf/wrappers.proto\
+   C:/projects/foo/src//foo.proto
+
+  C:\projects\foo\src\./foo.grpc.pb.cc \
+  C:\projects\foo\src\./foo.grpc.pb.h \
+  C:\projects\foo\src\./foo.pb.cc \
+  C:\projects\foo\src\./foo.pb.h: C:/foo/include/google/protobuf/wrappers.proto\
+   C:/foo/include/google/protobuf/any.proto\
+   C:/foo/include/google/protobuf/source_context.proto\
+   C:/foo/include/google/protobuf/type.proto\
+   foo.proto
+  */
+
+    /// <summary>
+    /// Read file names from the dependency file to the right of ':'
+    /// </summary>
+    /// <param name="protoDepDir">Relative path to the dependency cache, e. g. "out"</param>
+    /// <param name="proto">Relative path to the proto item, e. g. "foo/file.proto"</param>
+    /// <param name="log">A <see cref="TaskLoggingHelper"/> for logging</param>
+    /// <returns>
+    /// Array of the proto file <b>input</b> dependencies as written by protoc, or empty
+    /// array if the dependency file does not exist or cannot be parsed.
+    /// </returns>
     public static string[] ReadDependencyInputs(string protoDepDir, string proto,
                                                 TaskLoggingHelper log) {
       string depFilename = GetDepFilenameForProto(protoDepDir, proto);
@@ -80,7 +89,20 @@ C:\projects\foo\src\./foo.pb.h: C:/foo/include/google/protobuf/wrappers.proto\
       return result.ToArray();
     }
 
-    // Read file names from the dependency file to the left of ':'.
+    /// <summary>
+    /// Read file names from the dependency file to the left of ':'
+    /// </summary>
+    /// <param name="depFilename">Path to dependency file written by protoc</param>
+    /// <param name="log">A <see cref="TaskLoggingHelper"/> for logging</param>
+    /// <returns>
+    /// Array of the protoc-generated outputs from the given dependency file
+    /// written by protoc, or empty array if the file does not exist or cannot
+    /// be parsed.
+    /// </returns>
+    /// <remarks>
+    /// Since this is called after a protoc invocation, an unparsable or missing
+    /// file causes an error-level message to be logged.
+    /// </remarks>
     public static string[] ReadDependencyOutputs(string depFilename,
                                                 TaskLoggingHelper log) {
       string[] lines = ReadDepFileLines(depFilename, true, log);
@@ -106,10 +128,31 @@ C:\projects\foo\src\./foo.pb.h: C:/foo/include/google/protobuf/wrappers.proto\
       return result.ToArray();
     }
 
-    // Get complete dependency file name from directory hash and file name,
-    // tucked onto protoDepDir, e. g.
-    // ("out", "foo/file.proto") => "out/deadbeef12345678_file.protodep".
-    // This way, the filenames are unique but still possible to make sense of.
+    /// <summary>
+    /// Construct relative dependency file name from directory hash and file name
+    /// </summary>
+    /// <param name="protoDepDir">Relative path to the dependency cache, e. g. "out"</param>
+    /// <param name="proto">Relative path to the proto item, e. g. "foo/file.proto"</param>
+    /// <returns>
+    /// Full relative path to the dependency file, e. g.
+    /// "out/deadbeef12345678_file.protodep"
+    /// </returns>
+    /// <remarks>
+    /// Since a project may contain proto files with the same filename but in different
+    /// directories, a unique filename for the dependency file is constructed based on the
+    /// proto file name both name and directory. The directory path can be arbitrary,
+    /// for example, it can be outside of the project, or an absolute path including
+    /// a drive letter, or a UNC network path. A name constructed from such a path by,
+    /// for example, replacing disallowed name characters with an underscore, may well
+    /// be over filesystem's allowed path length, since it will be located under the
+    /// project and solution directories, which are also some level deep from the root.
+    /// Instead of creating long and unwieldy names for these proto sources, we cache
+    /// the full path of the name without the filename, and append the filename to it,
+    /// as in e. g. "foo/file.proto" will yield the name "deadbeef12345678_file", where
+    /// "deadbeef12345678" is a presumed hash value of the string "foo/". This allows
+    /// the file names be short, unique (up to a hash collision), and still allowing
+    /// the user to guess their provenance.
+    /// </remarks>
     public static string GetDepFilenameForProto(string protoDepDir, string proto) {
       string dirname = Path.GetDirectoryName(proto);
       if (Platform.IsFsCaseInsensitive) {
@@ -177,7 +220,7 @@ C:\projects\foo\src\./foo.pb.h: C:/foo/include/google/protobuf/wrappers.proto\
 
     // Read entire dependency file. The 'required' parameter controls error
     // logging behavior in case the file not found. We require this file when
-    // compiling, but reading it is optional when computing depnedencies.
+    // compiling, but reading it is optional when computing dependencies.
     static string[] ReadDepFileLines(string filename, bool required,
                                      TaskLoggingHelper log) {
       try {
@@ -189,7 +232,7 @@ C:\projects\foo\src\./foo.pb.h: C:/foo/include/google/protobuf/wrappers.proto\
         if (required) {
           log.LogError($"Unable to load {filename}: {ex.GetType().Name}: {ex.Message}");
         } else {
-          log.LogMessage(MessageImportance.Low, $"Skippping {filename}: {ex.Message}");
+          log.LogMessage(MessageImportance.Low, $"Skipping {filename}: {ex.Message}");
         }
         return new string[0];
       }
diff --git a/src/csharp/Grpc.Tools/GeneratorServices.cs b/src/csharp/Grpc.Tools/GeneratorServices.cs
index e1f266aa16..52bd29a678 100644
--- a/src/csharp/Grpc.Tools/GeneratorServices.cs
+++ b/src/csharp/Grpc.Tools/GeneratorServices.cs
@@ -49,7 +49,7 @@ namespace Grpc.Tools {
     // we do not try to validate the value; scripts take care of that.
     // It is safe to assume that gRPC is requested for any other value.
     protected bool GrpcOutputPossible(ITaskItem proto) {
-      string gsm = proto.GetMetadata(Metadata.kGrpcServices);
+      string gsm = proto.GetMetadata(Metadata.GrpcServices);
       return !gsm.EqualNoCase("") && !gsm.EqualNoCase("none")
           && !gsm.EqualNoCase("false");
     }
@@ -67,12 +67,12 @@ namespace Grpc.Tools {
         Path.GetFileNameWithoutExtension(protoItem.ItemSpec));
 
       var outputs = new string[doGrpc ? 2 : 1];
-      string outdir = protoItem.GetMetadata(Metadata.kOutputDir);
+      string outdir = protoItem.GetMetadata(Metadata.OutputDir);
       string fileStem = Path.Combine(outdir, filename);
       outputs[0] = fileStem + ".cs";
       if (doGrpc) {
         // Override outdir if kGrpcOutputDir present, default to proto output.
-        outdir = protoItem.GetMetadata(Metadata.kGrpcOutputDir);
+        outdir = protoItem.GetMetadata(Metadata.GrpcOutputDir);
         if (outdir != "") {
           fileStem = Path.Combine(outdir, filename);
         }
@@ -105,20 +105,20 @@ namespace Grpc.Tools {
 
     public override string[] GetPossibleOutputs(ITaskItem protoItem) {
       bool doGrpc = GrpcOutputPossible(protoItem);
-      string root = protoItem.GetMetadata(Metadata.kProtoRoot);
+      string root = protoItem.GetMetadata(Metadata.ProtoRoot);
       string proto = protoItem.ItemSpec;
       string filename = Path.GetFileNameWithoutExtension(proto);
       // E. g., ("foo/", "foo/bar/x.proto") => "bar"
       string relative = GetRelativeDir(root, proto);
 
       var outputs = new string[doGrpc ? 4 : 2];
-      string outdir = protoItem.GetMetadata(Metadata.kOutputDir);
+      string outdir = protoItem.GetMetadata(Metadata.OutputDir);
       string fileStem = Path.Combine(outdir, relative, filename);
       outputs[0] = fileStem + ".pb.cc";
       outputs[1] = fileStem + ".pb.h";
       if (doGrpc) {
         // Override outdir if kGrpcOutputDir present, default to proto output.
-        outdir = protoItem.GetMetadata(Metadata.kGrpcOutputDir);
+        outdir = protoItem.GetMetadata(Metadata.GrpcOutputDir);
         if (outdir != "") {
           fileStem = Path.Combine(outdir, relative, filename);
         }
diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj
index 46a6d4670d..8edfb848d7 100644
--- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj
+++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj
@@ -6,7 +6,19 @@
     <AssemblyName>Protobuf.MSBuild</AssemblyName>
     <Version>$(GrpcCsharpVersion)</Version>
     <!-- If changing targets, change also paths in Google.Protobuf.Tools.targets. -->
-    <TargetFrameworks>netstandard1.3;net40</TargetFrameworks>
+    <TargetFrameworks>net45;netstandard1.3</TargetFrameworks>
+  </PropertyGroup>
+
+  <!-- This is copied verbatim from Grpc.Core/Common.csproj.include. Other settings
+       in that file conflict with the intent of this build, as it cannot be signed,
+       and may not compile Grpc.Core/Version.cs, as that file references constants
+       in Grpc.Core.dll.
+       TODO(kkm): Refactor imports. -->
+  <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
+    <!-- Workaround for https://github.com/dotnet/sdk/issues/335 -->
+    <FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
+    <FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
+    <FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>
   </PropertyGroup>
 
   <PropertyGroup Label="Asset root folders. TODO(kkm): Change with package separation.">
@@ -32,9 +44,6 @@
   </PropertyGroup>
 
   <PropertyGroup Label="NuGet package definition" Condition=" '$(Configuration)' == 'Release' ">
-    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
-    <PackageOutputPath>../../../artifacts</PackageOutputPath>
-
     <!-- TODO(kkm): Change to "build\" after splitting. -->
     <BuildOutputTargetFolder>build\_protobuf\</BuildOutputTargetFolder>
     <DevelopmentDependency>true</DevelopmentDependency>
@@ -57,10 +66,9 @@ Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package
     <None Pack="true" PackagePath="build\" Include="build\**\*.xml; build\**\*.props; build\**\*.targets;" />
 
     <!-- Protobuf assets (for Google.Protobuf.Tools) -->
-    <_ProtoTemp Include="any.proto;api.proto;descriptor.proto;duration.proto;" />
-    <_ProtoTemp Include="empty.proto;field_mask.proto;source_context.proto;" />
-    <_ProtoTemp Include="struct.proto;timestamp.proto;type.proto;wrappers.proto" />
-    <_Asset PackagePath="build/native/include/google/protobuf/" Include="@(_ProtoTemp->'$(Assets_ProtoInclude)%(Identity)')" />
+    <_ProtoAssetName Include="any;api;descriptor;duration;empty;field_mask;
+                              source_context;struct;timestamp;type;wrappers" />
+    <_Asset PackagePath="build/native/include/google/protobuf/" Include="@(_ProtoAssetName->'$(Assets_ProtoInclude)%(Identity).proto')" />
 
     <!-- TODO(kkm): GPB builds assets into "macosx", GRPC into "macos". -->
     <_Asset PackagePath="build/native/bin/windows/protoc.exe" Include="$(Assets_ProtoCompiler)windows_x86/protoc.exe" />
@@ -85,10 +93,9 @@ Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package
   </ItemGroup>
 
   <ItemGroup Condition="$(_NetStandard)">
-    <PackageReference Include="Microsoft.Build.Framework" Version="15.5.180" />
-    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.5.180" />
-    <!--  Set PrivateAssets="All" on all items, so that even implicit package
-          dependencies do not become dependencies of this package. -->
+    <PackageReference Include="Microsoft.Build.Framework; Microsoft.Build.Utilities.Core" Version="15.6.85" />
+    <!--  Set PrivateAssets="All" on all items, even those implicitly added,
+          so that they do not become dependencies of this package. -->
     <PackageReference Update="@(PackageReference)" PrivateAssets="All" />
   </ItemGroup>
 
diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs
index 76c2338ef9..e77084b1ef 100644
--- a/src/csharp/Grpc.Tools/ProtoCompile.cs
+++ b/src/csharp/Grpc.Tools/ProtoCompile.cs
@@ -32,91 +32,91 @@ namespace Grpc.Tools {
   /// any language outputs.
   /// </summary>
   public class ProtoCompile : ToolTask {
-/*
-
-Usage: /home/kkm/work/protobuf/src/.libs/lt-protoc [OPTION] PROTO_FILES
-Parse PROTO_FILES and generate output based on the options given:
-  -IPATH, --proto_path=PATH   Specify the directory in which to search for
-                              imports.  May be specified multiple times;
-                              directories will be searched in order.  If not
-                              given, the current working directory is used.
-  --version                   Show version info and exit.
-  -h, --help                  Show this text and exit.
-  --encode=MESSAGE_TYPE       Read a text-format message of the given type
-                              from standard input and write it in binary
-                              to standard output.  The message type must
-                              be defined in PROTO_FILES or their imports.
-  --decode=MESSAGE_TYPE       Read a binary message of the given type from
-                              standard input and write it in text format
-                              to standard output.  The message type must
-                              be defined in PROTO_FILES or their imports.
-  --decode_raw                Read an arbitrary protocol message from
-                              standard input and write the raw tag/value
-                              pairs in text format to standard output.  No
-                              PROTO_FILES should be given when using this
-                              flag.
-  --descriptor_set_in=FILES   Specifies a delimited list of FILES
-                              each containing a FileDescriptorSet (a
-                              protocol buffer defined in descriptor.proto).
-                              The FileDescriptor for each of the PROTO_FILES
-                              provided will be loaded from these
-                              FileDescriptorSets. If a FileDescriptor
-                              appears multiple times, the first occurrence
-                              will be used.
-  -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,
-    --descriptor_set_out=FILE defined in descriptor.proto) containing all of
-                              the input files to FILE.
-  --include_imports           When using --descriptor_set_out, also include
-                              all dependencies of the input files in the
-                              set, so that the set is self-contained.
-  --include_source_info       When using --descriptor_set_out, do not strip
-                              SourceCodeInfo from the FileDescriptorProto.
-                              This results in vastly larger descriptors that
-                              include information about the original
-                              location of each decl in the source file as
-                              well as surrounding comments.
-  --dependency_out=FILE       Write a dependency output file in the format
-                              expected by make. This writes the transitive
-                              set of input file paths to FILE
-  --error_format=FORMAT       Set the format in which to print errors.
-                              FORMAT may be 'gcc' (the default) or 'msvs'
-                              (Microsoft Visual Studio format).
-  --print_free_field_numbers  Print the free field numbers of the messages
-                              defined in the given proto files. Groups share
-                              the same field number space with the parent
-                              message. Extension ranges are counted as
-                              occupied fields numbers.
-
-  --plugin=EXECUTABLE         Specifies a plugin executable to use.
-                              Normally, protoc searches the PATH for
-                              plugins, but you may specify additional
-                              executables not in the path using this flag.
-                              Additionally, EXECUTABLE may be of the form
-                              NAME=PATH, in which case the given plugin name
-                              is mapped to the given executable even if
-                              the executable's own name differs.
-  --cpp_out=OUT_DIR           Generate C++ header and source.
-  --csharp_out=OUT_DIR        Generate C# source file.
-  --java_out=OUT_DIR          Generate Java source file.
-  --javanano_out=OUT_DIR      Generate Java Nano source file.
-  --js_out=OUT_DIR            Generate JavaScript source.
-  --objc_out=OUT_DIR          Generate Objective C header and source.
-  --php_out=OUT_DIR           Generate PHP source file.
-  --python_out=OUT_DIR        Generate Python source file.
-  --ruby_out=OUT_DIR          Generate Ruby source file.
-  @<filename>                 Read options and filenames from file. If a
-                              relative file path is specified, the file
-                              will be searched in the working directory.
-                              The --proto_path option will not affect how
-                              this argument file is searched. Content of
-                              the file will be expanded in the position of
-                              @<filename> as in the argument list. Note
-                              that shell expansion is not applied to the
-                              content of the file (i.e., you cannot use
-                              quotes, wildcards, escapes, commands, etc.).
-                              Each line corresponds to a single argument,
-                              even if it contains spaces.
-*/
+  /*
+
+  Usage: /home/kkm/work/protobuf/src/.libs/lt-protoc [OPTION] PROTO_FILES
+  Parse PROTO_FILES and generate output based on the options given:
+    -IPATH, --proto_path=PATH   Specify the directory in which to search for
+                                imports.  May be specified multiple times;
+                                directories will be searched in order.  If not
+                                given, the current working directory is used.
+    --version                   Show version info and exit.
+    -h, --help                  Show this text and exit.
+    --encode=MESSAGE_TYPE       Read a text-format message of the given type
+                                from standard input and write it in binary
+                                to standard output.  The message type must
+                                be defined in PROTO_FILES or their imports.
+    --decode=MESSAGE_TYPE       Read a binary message of the given type from
+                                standard input and write it in text format
+                                to standard output.  The message type must
+                                be defined in PROTO_FILES or their imports.
+    --decode_raw                Read an arbitrary protocol message from
+                                standard input and write the raw tag/value
+                                pairs in text format to standard output.  No
+                                PROTO_FILES should be given when using this
+                                flag.
+    --descriptor_set_in=FILES   Specifies a delimited list of FILES
+                                each containing a FileDescriptorSet (a
+                                protocol buffer defined in descriptor.proto).
+                                The FileDescriptor for each of the PROTO_FILES
+                                provided will be loaded from these
+                                FileDescriptorSets. If a FileDescriptor
+                                appears multiple times, the first occurrence
+                                will be used.
+    -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,
+      --descriptor_set_out=FILE defined in descriptor.proto) containing all of
+                                the input files to FILE.
+    --include_imports           When using --descriptor_set_out, also include
+                                all dependencies of the input files in the
+                                set, so that the set is self-contained.
+    --include_source_info       When using --descriptor_set_out, do not strip
+                                SourceCodeInfo from the FileDescriptorProto.
+                                This results in vastly larger descriptors that
+                                include information about the original
+                                location of each decl in the source file as
+                                well as surrounding comments.
+    --dependency_out=FILE       Write a dependency output file in the format
+                                expected by make. This writes the transitive
+                                set of input file paths to FILE
+    --error_format=FORMAT       Set the format in which to print errors.
+                                FORMAT may be 'gcc' (the default) or 'msvs'
+                                (Microsoft Visual Studio format).
+    --print_free_field_numbers  Print the free field numbers of the messages
+                                defined in the given proto files. Groups share
+                                the same field number space with the parent
+                                message. Extension ranges are counted as
+                                occupied fields numbers.
+
+    --plugin=EXECUTABLE         Specifies a plugin executable to use.
+                                Normally, protoc searches the PATH for
+                                plugins, but you may specify additional
+                                executables not in the path using this flag.
+                                Additionally, EXECUTABLE may be of the form
+                                NAME=PATH, in which case the given plugin name
+                                is mapped to the given executable even if
+                                the executable's own name differs.
+    --cpp_out=OUT_DIR           Generate C++ header and source.
+    --csharp_out=OUT_DIR        Generate C# source file.
+    --java_out=OUT_DIR          Generate Java source file.
+    --javanano_out=OUT_DIR      Generate Java Nano source file.
+    --js_out=OUT_DIR            Generate JavaScript source.
+    --objc_out=OUT_DIR          Generate Objective C header and source.
+    --php_out=OUT_DIR           Generate PHP source file.
+    --python_out=OUT_DIR        Generate Python source file.
+    --ruby_out=OUT_DIR          Generate Ruby source file.
+    @<filename>                 Read options and filenames from file. If a
+                                relative file path is specified, the file
+                                will be searched in the working directory.
+                                The --proto_path option will not affect how
+                                this argument file is searched. Content of
+                                the file will be expanded in the position of
+                                @<filename> as in the argument list. Note
+                                that shell expansion is not applied to the
+                                content of the file (i.e., you cannot use
+                                quotes, wildcards, escapes, commands, etc.).
+                                Each line corresponds to a single argument,
+                                even if it contains spaces.
+  */
     static string[] s_supportedGenerators = new[] {
       "cpp", "csharp", "java",
       "javanano", "js", "objc",
diff --git a/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs b/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs
index 9afea9255e..74aaa8bd3d 100644
--- a/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs
+++ b/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs
@@ -68,7 +68,7 @@ namespace Grpc.Tools {
         var outputs = generator.GetPossibleOutputs(proto);
         foreach (string output in outputs) {
           var ti = new TaskItem(output);
-          ti.SetMetadata(Metadata.kSource, proto.ItemSpec);
+          ti.SetMetadata(Metadata.Source, proto.ItemSpec);
           possible.Add(ti);
         }
       }
diff --git a/src/csharp/Grpc.Tools/ProtoReadDependencies.cs b/src/csharp/Grpc.Tools/ProtoReadDependencies.cs
index 2ee0389146..ea931b0826 100644
--- a/src/csharp/Grpc.Tools/ProtoReadDependencies.cs
+++ b/src/csharp/Grpc.Tools/ProtoReadDependencies.cs
@@ -55,7 +55,7 @@ namespace Grpc.Tools {
           string[] deps = DepFileUtil.ReadDependencyInputs(ProtoDepDir, proto.ItemSpec, Log);
           foreach (string dep in deps) {
             var ti = new TaskItem(dep);
-            ti.SetMetadata(Metadata.kSource, proto.ItemSpec);
+            ti.SetMetadata(Metadata.Source, proto.ItemSpec);
             dependencies.Add(ti);
           }
         }
diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets
index 5a8d3f2027..2ed515c8db 100644
--- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets
+++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets
@@ -7,7 +7,7 @@
     <!-- Configuration is passing the smoke test. -->
     <Protobuf_ProjectSupported Condition=" '$(Protobuf_Generator)' != '' ">true</Protobuf_ProjectSupported>
     <_Protobuf_MsBuildAssembly Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netstandard1.3\Protobuf.MSBuild.dll</_Protobuf_MsBuildAssembly>
-    <_Protobuf_MsBuildAssembly Condition=" '$(MSBuildRuntimeType)' != 'Core' ">net40\Protobuf.MSBuild.dll</_Protobuf_MsBuildAssembly>
+    <_Protobuf_MsBuildAssembly Condition=" '$(MSBuildRuntimeType)' != 'Core' ">net45\Protobuf.MSBuild.dll</_Protobuf_MsBuildAssembly>
   </PropertyGroup>
 
   <UsingTask AssemblyFile="$(_Protobuf_MsBuildAssembly)" TaskName="Grpc.Tools.ProtoToolsPlatform" />
@@ -370,7 +370,7 @@
                                   Design-time support
    =================================================================================-->
 
-  <!-- Add all .proto files to the SourceFilesProjectOutputGroupOutput, so that
+  <!-- Add all .proto files to the SourceFilesProjectOutputGroupOutput, so that:
        * Visual Studio triggers a build when any of them changed;
        * The Pack target includes .proto files into the source package.  -->
   <Target Name="_Protobuf_SourceFilesProjectOutputGroup"
-- 
GitLab