aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Protobuf
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2017-11-16 13:38:56 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2017-11-16 13:38:56 +0200
commit914f4db513477d9aff726546bac47545195a3e37 (patch)
treed2ff190fd84b1dfaa03eec76563c431592ece7ff /Software/Visual_Studio/Tango.Protobuf
parent65d01ff549d80fbe13ff5e966df216c9f7c03653 (diff)
downloadTango-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')
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerException.cs41
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs73
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs81
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs100
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs36
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs41
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs29
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs34
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs37
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs29
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs35
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs57
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs317
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jarbin0 -> 3190277 bytes
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exebin0 -> 3702784 bytes
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exebin0 -> 4418048 bytes
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj83
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
new file mode 100644
index 000000000..a55611eac
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar
Binary files differ
diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe
new file mode 100644
index 000000000..6c015b17a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe
Binary files differ
diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe
new file mode 100644
index 000000000..e69179c0a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe
Binary files differ
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