diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-11-16 13:38:56 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-11-16 13:38:56 +0200 |
| commit | 914f4db513477d9aff726546bac47545195a3e37 (patch) | |
| tree | d2ff190fd84b1dfaa03eec76563c431592ece7ff /Software/Visual_Studio/Tango.Protobuf | |
| parent | 65d01ff549d80fbe13ff5e966df216c9f7c03653 (diff) | |
| download | Tango-914f4db513477d9aff726546bac47545195a3e37.tar.gz Tango-914f4db513477d9aff726546bac47545195a3e37.zip | |
Rename "Visual Studio" to "Visual_Studio"
Rename "External Repositories" to "External_Repositories".
Diffstat (limited to 'Software/Visual_Studio/Tango.Protobuf')
18 files changed, 999 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerException.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerException.cs new file mode 100644 index 000000000..8e50e405e --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/CompilerException.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents an <see cref="IProtoCompiler"/> compilation exception. + /// </summary> + /// <seealso cref="System.Exception" /> + public class CompilerException : Exception + { + /// <summary> + /// Gets the collection of compilation errors. + /// </summary> + public List<String> Issues { get; internal set; } + + /// <summary> + /// Initializes a new instance of the <see cref="CompilerException"/> class. + /// </summary> + public CompilerException() + { + Issues = new List<string>(); + } + + public override string Message => this.ToString(); + + /// <summary> + /// Returns a <see cref="System.String" /> that represents this instance. + /// </summary> + /// <returns> + /// A <see cref="System.String" /> that represents this instance. + /// </returns> + public override string ToString() + { + return String.Join(Environment.NewLine, Issues); + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs new file mode 100644 index 000000000..7c0ee54a4 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.Protobuf +{ + /// <summary> + /// Factory class for protobuf compilers. + /// </summary> + public static class CompilerFactory + { + /// <summary> + /// Creates a protobuf compiler instance by the specified language. + /// </summary> + /// <param name="language">The language.</param> + /// <returns></returns> + /// <exception cref="ArgumentException">Could not locate protobuf compiler for language " + language.ToString()</exception> + public static IProtoCompiler CreateCompiler(CompilerLanguage language) + { + LogManager.Log("Generating protobuf compiler for " + language.ToString() + "..."); + + foreach (var cType in typeof(CompilerFactory).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && typeof(IProtoCompiler).IsAssignableFrom(x))) + { + var instance = Activator.CreateInstance(cType) as IProtoCompiler; + if (instance.Language == language) return instance; + } + + throw LogManager.Log(new ArgumentException("Could not locate protobuf compiler for language " + language.ToString())); + } + + /// <summary> + /// Gets a collection of available compilers instance. + /// </summary> + /// <returns></returns> + public static IEnumerable<IProtoCompiler> GetAvailableCompilers() + { + List<IProtoCompiler> compilers = new List<IProtoCompiler>(); + + foreach (var cType in typeof(CompilerFactory).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && typeof(IProtoCompiler).IsAssignableFrom(x))) + { + var instance = Activator.CreateInstance(cType) as IProtoCompiler; + compilers.Add(instance); + } + + return compilers; + } + + /// <summary> + /// Creates a protobuf compiler instance by the specified language string. + /// </summary> + /// <param name="language">The language.</param> + /// <returns></returns> + /// <exception cref="ArgumentException">Could not locate protobuf compiler for language " + language.ToString()</exception> + public static IProtoCompiler CreateCompiler(String language) + { + LogManager.Log("Generating protobuf compiler for " + language.ToString() + "..."); + + CompilerLanguage lan = (CompilerLanguage)Enum.Parse(typeof(CompilerLanguage), language, true); + + foreach (var cType in typeof(CompilerFactory).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && typeof(IProtoCompiler).IsAssignableFrom(x))) + { + var instance = Activator.CreateInstance(cType) as IProtoCompiler; + if (instance.Language == lan) return instance; + } + + throw LogManager.Log(new ArgumentException("Could not locate protobuf compiler for language " + language.ToString())); + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs new file mode 100644 index 000000000..244ee3857 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents an <see cref="IProtoCompiler"/> file compilation result. + /// </summary> + /// <seealso cref="Tango.Protobuf.ICompilerResult" /> + public class CompilerFileResult : ICompilerResult + { + /// <summary> + /// Gets the result language. + /// </summary> + public CompilerLanguage Language { get; private set; } + + /// <summary> + /// Gets the result name. + /// </summary> + public String Name { get; private set; } + + /// <summary> + /// Gets the result source path. + /// </summary> + public String SourcePath { get; private set; } + + /// <summary> + /// Gets the file content. + /// </summary> + public String Content { get; private set; } + + /// <summary> + /// Gets or sets the relative file path. + /// </summary> + internal String RelativePath { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="CompilerFileResult"/> class. + /// </summary> + /// <param name="language">The language.</param> + /// <param name="sourcePath">The source path.</param> + /// <param name="fileName">Name of the file.</param> + /// <param name="content">File contents.</param> + public CompilerFileResult(CompilerLanguage language, String sourcePath, String fileName, String relativePath, String content) + { + Language = language; + SourcePath = sourcePath; + Name = fileName; + RelativePath = relativePath; + Content = content; + } + + /// <summary> + /// Saves the result to the specified folder. + /// </summary> + /// <param name="folder">The folder.</param> + public void Save(String folder) + { + LogManager.Log("Saving " + Path.Combine(folder, Name) + "..."); + + Directory.CreateDirectory(folder); + File.WriteAllText(Path.Combine(folder, Name), Content); + } + + /// <summary> + /// Returns a <see cref="System.String" /> that represents this instance. + /// </summary> + /// <returns> + /// A <see cref="System.String" /> that represents this instance. + /// </returns> + public override string ToString() + { + return Name; + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs new file mode 100644 index 000000000..9fa7e7d95 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents an <see cref="IProtoCompiler"/> folder compilation result. + /// </summary> + /// <seealso cref="Tango.Protobuf.ICompilerResult" /> + public class CompilerFolderResult : ICompilerResult + { + /// <summary> + /// Initializes a new instance of the <see cref="CompilerFolderResult"/> class. + /// </summary> + /// <param name="results">The results.</param> + /// <param name="language">The language.</param> + /// <param name="sourcePath">The source path.</param> + /// <param name="relativePath">The relative path.</param> + public CompilerFolderResult(IEnumerable<ICompilerResult> results, CompilerLanguage language, String sourcePath, String relativePath) + { + Results = results; + Language = language; + SourcePath = sourcePath; + RelativePath = relativePath; + Name = Path.GetFileName(sourcePath); + } + + /// <summary> + /// Gets the compiler results. + /// </summary> + public IEnumerable<ICompilerResult> Results { get; private set; } + + /// <summary> + /// Gets the result language. + /// </summary> + public CompilerLanguage Language { get; private set; } + + /// <summary> + /// Gets the result source path. + /// </summary> + public String SourcePath { get; private set; } + + /// <summary> + /// Gets the result name. + /// </summary> + public String Name { get; private set; } + + /// <summary> + /// Gets the result relative path. + /// </summary> + public String RelativePath { get; private set; } + + /// <summary> + /// Saves the result to the specified folder. + /// </summary> + /// <param name="folder">The folder.</param> + public void Save(string folder) + { + LogManager.Log("Saving " + folder + "..."); + + foreach (var fileResult in Results.OfType<CompilerFileResult>()) + { + fileResult.Save(folder); + } + + foreach (var folderResult in Results.OfType<CompilerFolderResult>()) + { + folderResult.Save(Path.Combine(folder, folderResult.RelativePath.TrimStart('\\','\\'))); + } + } + + /// <summary> + /// Returns a <see cref="System.String" /> that represents this instance. + /// </summary> + /// <returns> + /// A <see cref="System.String" /> that represents this instance. + /// </returns> + public override string ToString() + { + String output = Name + Environment.NewLine + ":"; + + foreach (var fileResult in Results.OfType<CompilerFileResult>()) + { + output += fileResult.ToString() + Environment.NewLine; + } + + foreach (var folderResult in Results.OfType<CompilerFolderResult>()) + { + output += folderResult.ToString() + Environment.NewLine; + } + + return output; + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs new file mode 100644 index 000000000..3b4329d38 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents an enumeration for available protobuf compiler languages. + /// </summary> + public enum CompilerLanguage + { + [Description("C#")] + CSharp, + [Description("Java")] + Java, + [Description("Java Nano")] + JavaNano, + [Description("C++")] + CPP, + [Description("C")] + C, + [Description("Embedded C")] + EmbeddedC, + [Description("JavaScript")] + JS, + [Description("Python")] + Python, + [Description("PHP")] + PHP, + [Description("Ruby")] + Ruby, + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs new file mode 100644 index 000000000..18aab84c6 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf.Compilers +{ + /// <summary> + /// Represents a protobuf C Compiler. + /// </summary> + /// <seealso cref="Tango.Protobuf.ProtoCompiler" /> + public class CCompiler : ProtoCompiler + { + /// <summary> + /// Gets the compiler language. + /// </summary> + public override CompilerLanguage Language => CompilerLanguage.C; + + /// <summary> + /// Gets the protobuf compiler CLI arguments (without input/output files!). + /// </summary> + /// <returns></returns> + protected override string GetProtoArguments() + { + return "--c_out"; + } + + /// <summary> + /// Gets the protobuf compiler CLI file name (override when using a compiler other than the default 'protoc.exe'). + /// </summary> + /// <returns></returns> + /// <remarks> + /// The compiler program must be located in the compilers folder. + /// </remarks> + protected override string GetProtoCompilerName() + { + return "protoc-c"; + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs new file mode 100644 index 000000000..682dda60c --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf.Compilers +{ + /// <summary> + /// Represents a protobuf C# Compiler. + /// </summary> + /// <seealso cref="Tango.Protobuf.ProtoCompiler" /> + public class CSharpCompiler : ProtoCompiler + { + /// <summary> + /// Gets the compiler language. + /// </summary> + public override CompilerLanguage Language => CompilerLanguage.CSharp; + + /// <summary> + /// Gets the protobuf compiler CLI arguments (without input/output files!). + /// </summary> + /// <returns></returns> + protected override string GetProtoArguments() + { + return "--csharp_out"; + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs new file mode 100644 index 000000000..e8ea998d5 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf.Compilers +{ + /// <summary> + /// Represents a protobuf C# Compiler. + /// </summary> + /// <seealso cref="Tango.Protobuf.ProtoCompiler" /> + public class CppCompiler : ProtoCompiler + { + /// <summary> + /// Gets the compiler language. + /// </summary> + public override CompilerLanguage Language => CompilerLanguage.CPP; + + /// <summary> + /// Gets the protobuf compiler CLI arguments (without input/output files!). + /// </summary> + /// <returns></returns> + protected override string GetProtoArguments() + { + return "--cpp_out"; + } + + /// <summary> + /// Gets a value indicating whether this compiler uses the default folder structure when generating code. + /// </summary> + public override bool UsesDefaultStructure => true; + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs new file mode 100644 index 000000000..55f0cf77f --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Helpers; +using Tango.Logging; + +namespace Tango.Protobuf.Compilers +{ + /// <summary> + /// Represents a protobuf Java Compiler. + /// </summary> + /// <seealso cref="Tango.Protobuf.ProtoCompiler" /> + public class JavaCompiler : ProtoCompiler + { + /// <summary> + /// Gets the compiler language. + /// </summary> + public override CompilerLanguage Language => CompilerLanguage.Java; + + /// <summary> + /// Gets the protobuf compiler CLI arguments (without input/output files!). + /// </summary> + /// <returns></returns> + protected override string GetProtoArguments() + { + return "--java_out"; + } + + /// <summary> + /// Gets a value indicating whether this compiler uses the default folder structure when generating code. + /// </summary> + public override bool UsesDefaultStructure => true; + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs new file mode 100644 index 000000000..e3c3ebbd7 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf.Compilers +{ + /// <summary> + /// Represents a protobuf Python Compiler. + /// </summary> + /// <seealso cref="Tango.Protobuf.ProtoCompiler" /> + public class PythonCompiler : ProtoCompiler + { + /// <summary> + /// Gets the compiler language. + /// </summary> + public override CompilerLanguage Language => CompilerLanguage.Python; + + /// <summary> + /// Gets the protobuf compiler CLI arguments (without input/output files!). + /// </summary> + /// <returns></returns> + protected override string GetProtoArguments() + { + return "--python_out"; + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs b/Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs new file mode 100644 index 000000000..866ce64d0 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents a protobuf compiler result. + /// </summary> + public interface ICompilerResult + { + /// <summary> + /// Saves the result to the specified folder. + /// </summary> + /// <param name="folder">The folder.</param> + void Save(String folder); + + /// <summary> + /// Gets the result language. + /// </summary> + CompilerLanguage Language { get; } + + /// <summary> + /// Gets the result name. + /// </summary> + String Name { get ; } + + /// <summary> + /// Gets the result source path. + /// </summary> + String SourcePath { get; } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs new file mode 100644 index 000000000..db5303515 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents a protobuf messages compiler. + /// </summary> + public interface IProtoCompiler : IDisposable + { + /// <summary> + /// Compiles the specified .proto message file. + /// </summary> + /// <param name="inputFile">.proto file to compile</param> + /// <returns>A list of compiled results.</returns> + IEnumerable<CompilerFileResult> CompileFile(String inputFile); + + /// <summary> + /// Compiles the specified .proto message file asynchronously. + /// </summary> + /// <param name="inputFile">.proto file to compile</param> + /// <returns>A list of compiled results.</returns> + Task<IEnumerable<CompilerFileResult>> CompileFileAsync(String inputFile); + + /// <summary> + /// Compiles all files in the specified folder recursively. + /// </summary> + /// <param name="sourceFolder">The source folder</param> + /// <returns>Compilation result.</returns> + CompilerFolderResult CompileFolder(String sourceFolder); + + /// <summary> + /// Compiles all files in the specified folder recursively and asynchronously. + /// </summary> + /// <param name="sourceFolder">The source folder</param> + /// <returns>Compilation result.</returns> + Task<CompilerFolderResult> CompileFolderAsync(String sourceFolder); + + /// <summary> + /// Gets the compiler language. + /// </summary> + CompilerLanguage Language { get; } + + /// <summary> + /// Gets the proto imports folders. + /// </summary> + List<String> ImportsFolders { get; } + + /// <summary> + /// Gets a value indicating whether this compiler uses the default folder structure when generating code. + /// </summary> + bool UsesDefaultStructure { get; } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..2296973b8 --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Protobuf Components")] +[assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs new file mode 100644 index 000000000..d2bfde75c --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Helpers; +using Tango.Logging; + +namespace Tango.Protobuf +{ + /// <summary> + /// Represents a protobuf compiler base class. + /// </summary> + /// <seealso cref="Tango.Protobuf.IProtoCompiler" /> + public abstract class ProtoCompiler : IProtoCompiler + { + private const String COMPILERS_FOLDER_NAME = "ProtoCompilers"; //Compilers folder name. + protected String _compilersPath; //Compilers folder path. + + /// <summary> + /// Gets the compiler language. + /// </summary> + public abstract CompilerLanguage Language { get; } + + /// <summary> + /// Gets the proto imports folders. + /// </summary> + public List<String> ImportsFolders { get; private set; } + + /// <summary> + /// Gets a value indicating whether this compiler uses the default folder structure when generating code. + /// </summary> + public virtual bool UsesDefaultStructure { get; } + + /// <summary> + /// Initializes a new instance of the <see cref="ProtoCompiler"/> class. + /// </summary> + public ProtoCompiler() + { + ImportsFolders = new List<string>(); + _compilersPath = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), COMPILERS_FOLDER_NAME); + } + + /// <summary> + /// Compiles the specified .proto message file. + /// </summary> + /// <param name="inputFile">.proto file to compile</param> + /// <returns> + /// A list of compiled results. + /// </returns> + public virtual IEnumerable<CompilerFileResult> CompileFile(string inputFile) + { + LogManager.Log("Compiling file " + inputFile); + + String tmpPath = PathHelper.GetTempFolderPath(); + + LogManager.Log("Temp path: " + tmpPath); + + String importsString = "--proto_path \"" + Path.GetDirectoryName(inputFile) + "\" "; + + LogManager.Log("Added import string: " + importsString); + + foreach (var path in ImportsFolders) + { + String importStr = "--proto_path \"" + path + "\" "; + importsString += importStr; + LogManager.Log("Added import string: " + importStr); + } + + Process p = new Process(); + + LogManager.Log("Compilers folder path: " + _compilersPath); + + p.StartInfo.WorkingDirectory = _compilersPath; + String oldCurrentDirectory = Environment.CurrentDirectory; + Environment.CurrentDirectory = _compilersPath; + p.StartInfo.FileName = GetProtoCompilerName(); + + LogManager.Log("Protobuf executable path: " + p.StartInfo.FileName); + + p.StartInfo.Arguments = String.Format( + "{0} {1}=\"{2}\" \"{3}\"", + importsString, + GetProtoArguments(), + tmpPath, + inputFile); + + LogManager.Log("Final arguments:\n" + p.StartInfo.Arguments); + + p.StartInfo.CreateNoWindow = true; + p.StartInfo.UseShellExecute = false; + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + + p.StartInfo.RedirectStandardError = true; + p.StartInfo.RedirectStandardOutput = true; + + + LogManager.Log("Executing compilation..."); + + p.Start(); + p.WaitForExit(5000); + + Environment.CurrentDirectory = oldCurrentDirectory; + + String error = p.StandardError.ReadToEnd(); + + if (!String.IsNullOrWhiteSpace(error)) + { + var lines = error.Split(new[] { '\r', '\n' }); + throw LogManager.Log(new CompilerException() { Issues = lines.Where(x => x.Length > 0).ToList() }); + } + + List<CompilerFileResult> results = new List<CompilerFileResult>(); + + foreach (var file in Directory.GetFiles(tmpPath, "*.*", SearchOption.AllDirectories)) + { + CompilerFileResult result = new CompilerFileResult(Language, inputFile, Path.GetFileName(file), Path.GetDirectoryName(file).Replace(tmpPath, "").TrimStart('\\', '\\'), File.ReadAllText(file)); + results.Add(result); + } + + + if (PathHelper.TryDeleteFolder(tmpPath)) + { + LogManager.Log("Removed temp path: " + tmpPath); + } + else + { + LogManager.Log("Could not remove temp path: " + tmpPath); + } + + LogManager.Log(Path.GetFileName(inputFile) + "compiled!"); + + return results; + } + + /// <summary> + /// Compiles the specified .proto message file asynchronously. + /// </summary> + /// <param name="inputFile">.proto file to compile</param> + /// <returns> + /// A list of compiled results. + /// </returns> + public async Task<IEnumerable<CompilerFileResult>> CompileFileAsync(string inputFile) + { + return await new Task<IEnumerable<CompilerFileResult>>(() => { return CompileFile(inputFile); }); + } + + /// <summary> + /// Compiles all files in the specified folder recursively. + /// </summary> + /// <param name="sourceFolder">The source folder</param> + /// <returns> + /// Compilation result. + /// </returns> + public virtual CompilerFolderResult CompileFolder(string sourceFolder) + { + if (!UsesDefaultStructure) + { + LogManager.Log("Compiling folder: " + sourceFolder); + + ImportsFolders.Clear(); + ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories)); + var result = CompileFolder(sourceFolder, sourceFolder); + + LogManager.Log(Path.GetFileName(sourceFolder) + "compiled!"); + + return OnPostProcessFolderCompilation(result); + } + else + { + return CompileFolderDefault(sourceFolder); + } + } + + /// <summary> + /// Compiles all files in the specified folder recursively. + /// </summary> + /// <param name="sourceFolder">The source folder</param> + /// <returns> + /// Compilation result. + /// </returns> + protected virtual CompilerFolderResult CompileFolder(string rootFolder, string sourceFolder) + { + List<ICompilerResult> currentFolderResults = new List<ICompilerResult>(); + CompilerFolderResult currentFolder = new CompilerFolderResult(currentFolderResults, Language, sourceFolder, sourceFolder.Replace(rootFolder, "")); + + foreach (String file in Directory.GetFiles(sourceFolder, "*.proto")) + { + currentFolderResults.AddRange(CompileFile(file)); + } + foreach (string folder in Directory.GetDirectories(sourceFolder)) + { + if (Directory.GetFiles(folder, "*.proto").Length > 0) + { + currentFolderResults.Add(CompileFolder(rootFolder, folder)); + } + } + + return currentFolder; + } + + /// <summary> + /// Compiles all files in the specified folder recursively and asynchronously. + /// </summary> + /// <param name="sourceFolder">The source folder</param> + /// <returns> + /// Compilation result. + /// </returns> + public async Task<CompilerFolderResult> CompileFolderAsync(string sourceFolder) + { + return await new Task<CompilerFolderResult>(() => { return CompileFolder(sourceFolder); }); + } + + /// <summary> + /// Compiles all files in the specified folder recursively using the default structure. + /// </summary> + /// <param name="sourceFolder">The source folder</param> + /// <returns> + /// Compilation result. + /// </returns> + private CompilerFolderResult CompileFolderDefault(string sourceFolder) + { + LogManager.Log("Compiling folder: " + sourceFolder); + + Dictionary<string, CompilerFileResult> fileResults = new Dictionary<string, CompilerFileResult>(); + ImportsFolders.Clear(); + ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories)); + + String tempPath = PathHelper.GetTempFolderPath(); + + foreach (var file in Directory.GetFiles(sourceFolder, "*.proto", SearchOption.AllDirectories)) + { + foreach (var fileResult in CompileFile(file)) + { + String targetFolder = Path.Combine(tempPath, fileResult.RelativePath); + String targetFile = Path.Combine(targetFolder, fileResult.Name); + Directory.CreateDirectory(targetFolder); + File.WriteAllText(targetFile, fileResult.Content); + + fileResults.Add(targetFile, fileResult); + } + } + + var result = CompileFolderDefault(tempPath, tempPath, fileResults); + + PathHelper.TryDeleteFolder(tempPath); + + LogManager.Log(Path.GetFileName(sourceFolder) + "compiled!"); + + return OnPostProcessFolderCompilation(result); + } + + /// <summary> + /// Compiles all files in the specified folder recursively using the default structure. + /// </summary> + /// <param name="rootFolder"></param> + /// <param name="sourceFolder">The source folder</param> + /// <returns> + /// Compilation result. + /// </returns> + private CompilerFolderResult CompileFolderDefault(string rootFolder, string sourceFolder, Dictionary<string, CompilerFileResult> fileResults) + { + List<ICompilerResult> currentFolderResults = new List<ICompilerResult>(); + CompilerFolderResult currentFolder = new CompilerFolderResult(currentFolderResults, Language, sourceFolder, Path.GetFileName(sourceFolder)); + + foreach (String file in Directory.GetFiles(sourceFolder, "*.*")) + { + currentFolderResults.Add(fileResults[file]); + } + foreach (string folder in Directory.GetDirectories(sourceFolder)) + { + currentFolderResults.Add(CompileFolderDefault(rootFolder, folder, fileResults)); + } + + return currentFolder; + } + + /// <summary> + /// Override in order to manipulate the folder compilation result. + /// </summary> + /// <param name="result">The result.</param> + /// <returns></returns> + protected virtual CompilerFolderResult OnPostProcessFolderCompilation(CompilerFolderResult result) + { + return result; + } + + /// <summary> + /// Gets the protobuf compiler CLI arguments (without input/output files!). + /// </summary> + /// <returns></returns> + protected abstract String GetProtoArguments(); + + /// <summary> + /// Gets the protobuf compiler CLI file name (override when using a compiler other than the default 'protoc.exe'). + /// </summary> + /// <remarks> + /// The compiler program must be located in the compilers folder. + /// </remarks> + /// <returns></returns> + protected virtual String GetProtoCompilerName() + { + return "protoc.exe"; + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + //TODO: Dispose... + } + } +} diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar Binary files differnew file mode 100644 index 000000000..a55611eac --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe Binary files differnew file mode 100644 index 000000000..6c015b17a --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe Binary files differnew file mode 100644 index 000000000..e69179c0a --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe diff --git a/Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj b/Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj new file mode 100644 index 000000000..d2a98eb1a --- /dev/null +++ b/Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{40073806-914E-4E78-97AB-FA9639308EBE}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Tango.Protobuf</RootNamespace> + <AssemblyName>Tango.Protobuf</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\Build\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="CompilerException.cs" /> + <Compile Include="CompilerFactory.cs" /> + <Compile Include="CompilerFolderResult.cs" /> + <Compile Include="Compilers\CCompiler.cs" /> + <Compile Include="Compilers\CppCompiler.cs" /> + <Compile Include="Compilers\CSharpCompiler.cs" /> + <Compile Include="Compilers\JavaCompiler.cs" /> + <Compile Include="Compilers\PythonCompiler.cs" /> + <Compile Include="ICompilerResult.cs" /> + <Compile Include="ProtoCompiler.cs" /> + <Compile Include="IProtoCompiler.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="CompilerLanguage.cs" /> + <Compile Include="CompilerFileResult.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Logging\Tango.Logging.csproj"> + <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> + <Name>Tango.Logging</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Content Include="ProtoCompilers\protoc-1.0M4.jar"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="ProtoCompilers\protoc-c.exe"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="ProtoCompilers\protoc.exe"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file |
