blob: 24c0dd8482d3108ae98850b1bba079b37c5f8ae2 [file] [log] [blame]
#region Copyright notice and license
// Copyright 2018 gRPC authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Grpc.Tools
public class ProtoCompilerOutputs : Task
/// <summary>
/// Code generator. Currently supported are "csharp", "cpp".
/// </summary>
public string Generator { get; set; }
/// <summary>
/// All Proto files in the project. The task computes possible outputs
/// from these proto files, and returns them in the PossibleOutputs list.
/// Not all of these might be actually produced by protoc; this is dealt
/// with later in the ProtoCompile task which returns the list of
/// files actually produced by the compiler.
/// </summary>
public ITaskItem[] Protobuf { get; set; }
/// <summary>
/// Output items per each potential output. We do not look at existing
/// cached dependency even if they exist, since file may be refactored,
/// affecting whether or not gRPC code file is generated from a given proto.
/// Instead, all potentially possible generated sources are collected.
/// It is a wise idea to generate empty files later for those potentials
/// that are not actually created by protoc, so the dependency checks
/// result in a minimal recompilation. The Protoc task can output the
/// list of files it actually produces, given right combination of its
/// properties.
/// Output items will have the Source metadata set on them:
/// <ItemName Include="MyProto.cs" Source="my_proto.proto" />
/// </summary>
public ITaskItem[] PossibleOutputs { get; private set; }
public override bool Execute()
var generator = GeneratorServices.GetForLanguage(Generator, Log);
if (generator == null)
// Error already logged, just return.
return false;
// Get language-specific possible output. The generator expects certain
// metadata be set on the proto item.
var possible = new List<ITaskItem>();
foreach (var proto in Protobuf)
var outputs = generator.GetPossibleOutputs(proto);
foreach (string output in outputs)
var ti = new TaskItem(output);
ti.SetMetadata(Metadata.Source, proto.ItemSpec);
PossibleOutputs = possible.ToArray();
return !Log.HasLoggedErrors;