static CapnpGenJob ToGenJob(ITaskItem item) { var job = new CapnpGenJob() { CapnpPath = item.GetMetadata("FullPath"), WorkingDirectory = item.GetMetadata("WorkingDirectory") }; string importPaths = item.GetMetadata("ImportPaths"); if (!string.IsNullOrWhiteSpace(importPaths)) { job.AdditionalArguments.AddRange(importPaths.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(p => $"-I\"{p.TrimEnd('\\')}\"")); } string sourcePrefix = item.GetMetadata("SourcePrefix"); if (!string.IsNullOrWhiteSpace(sourcePrefix)) { job.AdditionalArguments.Add(sourcePrefix); } string verbose = item.GetMetadata("Verbose"); if ("true".Equals(verbose, StringComparison.OrdinalIgnoreCase)) { job.AdditionalArguments.Add("--verbose"); } return(job); }
public CsFileGeneratorResult GenerateCodeBehindFile(CapnpGenJob job) { string capnpFile = job.CapnpPath; // Works around a weird capnp.exe behavior: When the input file is empty, it will spit out an exception dump // instead of a parse error. But the parse error is nice because it contains a generated ID. We want the parse error! // Workaround: Generate a temporary file that contains a single line break (such that it is not empty...) try { if (File.Exists(capnpFile) && new FileInfo(capnpFile).Length == 0) { string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".capnp"); File.WriteAllText(tempFile, Environment.NewLine); try { var jobCopy = new CapnpGenJob() { CapnpPath = tempFile, WorkingDirectory = job.WorkingDirectory }; jobCopy.AdditionalArguments.AddRange(job.AdditionalArguments); return(GenerateCodeBehindFile(jobCopy)); } finally { File.Delete(tempFile); } } } catch { } var args = new List <string>(); args.AddRange(job.AdditionalArguments); args.Add(capnpFile); var result = CapnpCompilation.InvokeCapnpAndGenerate(args, job.WorkingDirectory); if (result.IsSuccess) { if (result.GeneratedFiles.Count == 1) { return(new CsFileGeneratorResult( result.GeneratedFiles[0], capnpFile + ".cs", result.Messages)); } else { return(new CsFileGeneratorResult( "Code generation produced more than one file. This is not supported.", result.Messages)); } } else { switch (result.ErrorCategory) { case CapnpProcessFailure.NotFound: return(new CsFileGeneratorResult("Unable to find capnp.exe - please install capnproto on your system first.")); case CapnpProcessFailure.BadInput: return(new CsFileGeneratorResult("Invalid schema", result.Messages)); case CapnpProcessFailure.BadOutput: return(new CsFileGeneratorResult( "Internal error: capnp.exe produced a binary code generation request which was not understood by the backend", result.Messages)); default: throw new NotSupportedException("Invalid error category"); } } }