/// <inheritdoc/> protected override Task InitializeAsync(CancellationToken cancellationToken) { var proto = ""; //todo var fileDescriptorSet = new FileDescriptorSet(); fileDescriptorSet.Add("" /* todo */, true, new StringReader(proto)); fileDescriptorSet.Process(); var errors = fileDescriptorSet.GetErrors(); foreach (var file in fileDescriptorSet.Files) { foreach (var service in file.Services) { foreach (var method in service.Methods) { //todo: if method.Deprecated => display warning } } } var channel = GrpcChannel.ForAddress($"{EnvironmentVariables.Api.HostName.Value}:8080"); var serviceName = ""; var client = new GrpcClient(channel, serviceName); return(Task.CompletedTask); }
static void Generate(string inpath, string[] inprotos, string outpath) { var set = new FileDescriptorSet(); set.AddImportPath(inpath); foreach (var inproto in inprotos) { set.Add(inproto, true); } set.Process(); var errors = set.GetErrors(); CSharpCodeGenerator.ClearTypeNames(); var files = CSharpCodeGenerator.Default.Generate(set); int idx = 1; foreach (var file in files) { EditorUtility.DisplayProgressBar("Generate", file.Name, idx / (1.0f * inprotos.Length)); var path = Path.Combine(outpath, file.Name); File.WriteAllText(path, file.Text); Debug.Log($"generated: {path}"); } EditorUtility.ClearProgressBar(); AssetDatabase.Refresh(); }
public static List <FileDescriptorProto>?Parse(string file, string @namespace) { // https://github.com/protobuf-net/protobuf-net/blob/master/src/protogen/Program.cs#L136 var filePath = Path.GetFullPath(file); var directoryPath = Path.GetDirectoryName(filePath); var fileDescriptorSet = new FileDescriptorSet { DefaultPackage = @namespace }; fileDescriptorSet.AddImportPath(directoryPath); if (!fileDescriptorSet.Add(file, true)) { Console.WriteLine($"Couldn't add file: {file}"); return(null); } fileDescriptorSet.Process(); var errors = fileDescriptorSet.GetErrors(); if (errors.Length > 0) { foreach (var error in errors) { throw new InvalidOperationException(error.ToString()); } } return(fileDescriptorSet.Files); }
/// <summary> /// Eexecute this code generator against a set of code file /// </summary> public CompilerResult Compile(params CodeFile[] files) { var set = new FileDescriptorSet(); foreach (var file in files) { using (var reader = new StringReader(file.Text)) { Console.WriteLine($"Parsing {file.Name}..."); set.Add(file.Name, true, reader); } } set.Process(); var results = new List <CodeFile>(); var newErrors = new List <Error>(); try { results.AddRange(Generate(set)); } catch (Exception ex) { set.Errors.Add(new Error(default(Token), ex.Message, true)); } var errors = set.GetErrors(); return(new CompilerResult(errors, results.ToArray())); }
public GenerateResult Generate(string schema = null, string tooling = null) { if (string.IsNullOrWhiteSpace(schema)) { return(null); } var result = new GenerateResult(); try { using (var reader = new StringReader(schema)) { var set = new FileDescriptorSet { ImportValidator = path => ValidateImport(path), }; set.AddImportPath(Path.Combine(_host.WebRootPath, "protoc")); set.Add("my.proto", true, reader); set.Process(); var errors = set.GetErrors(); if (!ProtocTooling.IsDefined(tooling)) { if (errors.Length > 0) { result.ParserExceptions = errors; } result.Files = CSharpCodeGenerator.Default.Generate(set).ToArray(); } else { // we're going to offer protoc! hold me... if (errors.Length != 0 && schema.Contains("import")) { // code output disabled because of import } else { result.Files = RunProtoc(_host, schema, tooling, out errors); if (errors.Length > 0) { result.ParserExceptions = errors; } } } } } catch (Exception ex) { result.Exception = ex; } return(result); }
public void EmbeddedImportsWork() { var set = new FileDescriptorSet(); using (var file = File.OpenText("basic.proto")) { Assert.True(set.Add("basic.proto", true, file)); } set.Process(); var err = set.GetErrors(); Assert.Empty(err); }
public void Parsed_ShouldReturnParsedSchemaContents() { string contents = SchemaFixtureUtils.GetProtoBuf("ValidSchema"); var schema = new ProtoBufSchema( Guid.NewGuid(), new SchemaGroupAggregate.Schemas.Version(1), contents); FileDescriptorSet descriptor = schema.Parsed; Assert.NotNull(descriptor); Assert.Empty(descriptor.GetErrors()); }
public IActionResult Generate([FromBody] GeneratorViewModel generatorViewModel) { using (var reader = new StringReader(generatorViewModel.ProtoContent)) { var set = new FileDescriptorSet { ImportValidator = path => ValidateImport(path), }; set.AddImportPath(Path.Combine(_host.WebRootPath, "protoc")); set.Add("my.proto", true, reader); set.Process(); var errors = set.GetErrors(); if (errors.Length != 0) { //code parsing is supposed to happening client side, so we don't send error here return(BadRequest()); } if (generatorViewModel.IsProtobugGen()) { return(Ok( generatorViewModel .GetCodeGenerator() .Generate(set, generatorViewModel.GetNameNormalizerForConvention(), generatorViewModel.GetOptions()) .ToList())); } // we're going to offer protoc! hold me... if (generatorViewModel.ProtoContent.Contains("import")) { // code output disabled because of import return(BadRequest()); } else { var files = RunProtoc(_host, generatorViewModel.ProtoContent, generatorViewModel.GetProtocTooling(), out var stdout, out var stderr, out var exitCode); if (exitCode != 0) { return(base.StatusCode(500, new { stderr, stdout, exitCode })); } return(Ok(files)); } } }
public void BuildTypeHierarchyForServices() { var set = new FileDescriptorSet(); using (var file = File.OpenText("basic_service.proto")) { Assert.True(set.Add("basic_service.proto", true, file)); } set.Process(); var err = set.GetErrors(); Assert.Empty(err); Assert.Equal(".HelloWorld.HelloService", set.Files[0].Services[0].FullyQualifiedName); Assert.Equal(".HelloWorld.HelloService.SayHello", set.Files[0].Services[0].Methods[0].FullyQualifiedName); }
public void CanParseCustomOptionsFromExternalSchema() { var set = new FileDescriptorSet(); set.AddImportPath("./Schemas"); Assert.True(set.Add("nanopb_test.proto")); set.Process(); Assert.Empty(set.GetErrors()); var bar = set.Files.Single(x => x.Name == "nanopb_test.proto") .MessageTypes.Single() .Fields.Single(x => x.Number == 3); // normally you'd just use an "if (Extensible.TryGetValue(...)" here; I'm proving it for the test Assert.True(Extensible.TryGetValue <NanoPBOptions>(RuntimeTypeModel.Default, bar.Options, 1010, out var options)); Assert.True(options.ShouldSerializeMaxSize()); // this is "actively set" vs "set via the default" etc Assert.Equal(42, options.MaxSize); }
public IActionResult Generate([FromBody] GeneratorViewModel generatorViewModel) { using var reader = new StringReader(generatorViewModel.ProtoContent); var set = new FileDescriptorSet { ImportValidator = path => ValidateImport(path), }; set.AddImportPath(Path.Combine(_host.WebRootPath, "protoc")); set.Add("my.proto", true, reader); set.Process(); var errors = set.GetErrors(); if (errors.Length != 0) { //code parsing is supposed to happening client side, so we don't send error here return(BadRequest()); } if (generatorViewModel.IsProtogen()) { return(Ok( generatorViewModel .GetCodeGenerator() .Generate(set, generatorViewModel.GetNameNormalizerForConvention(), generatorViewModel.GetOptions()) .ToList())); } // if we got this far, it means that we resolved all the imports, so // we don't need to worry about protoc going out-of-bounds with external files // (since we constrain with ValidateImport), so: off to 'protoc' we go! var files = RunProtoc(_host, generatorViewModel.ProtoContent, generatorViewModel.GetProtocTooling(), out var stdout, out var stderr, out var exitCode); if (exitCode != 0) { return(base.StatusCode(500, new { stderr, stdout, exitCode })); } return(Ok(files)); }
private static void Generate(string inpath, string[] inprotos, string outpath) { if (!Directory.Exists(outpath)) { Directory.CreateDirectory(outpath); } var set = new FileDescriptorSet(); set.AddImportPath(inpath); foreach (var inproto in inprotos) { var s = inproto; if (!inproto.Contains(".proto")) { s += ".proto"; } set.Add(s, true); } set.Process(); var errors = set.GetErrors(); CSharpCodeGenerator.ClearTypeNames(); var files = CSharpCodeGenerator.Default.Generate(set); foreach (var file in files) { CSharpCodeGenerator.ClearTypeNames(); var path = Path.Combine(outpath, file.Name); File.WriteAllText(path, file.Text); Log.Print($"Generated cs file for {file.Name.Replace(".cs",".proto")} successfully to: {path}"); } EditorUtility.DisplayDialog("Complete", "Proto文件已转CS,详细请看控制台输出" + "\n" + "Proto files has been convert into CS files, please go to console and view details", "Close window"); win.Close(); }
static void Generate(string inpath,string[] inprotos,string outpath) { var set = new FileDescriptorSet(); set.AddImportPath(inpath); foreach (var inproto in inprotos) { set.Add (inproto, true); } set.Process(); var errors = set.GetErrors(); CSharpCodeGenerator.ClearTypeNames (); var files = CSharpCodeGenerator.Default.Generate(set); foreach (var file in files) { var path = Path.Combine(outpath, file.Name); File.WriteAllText(path, file.Text); Debug.Log($"generated: {path}"); } }
public void CompareProtoToParser(string path, bool includeImports) { if (path == "google/protobuf/map_unittest_proto3.proto") { return; // TODO known oddity } var schemaPath = Path.Combine(Directory.GetCurrentDirectory(), SchemaPath); _output.WriteLine(Path.GetDirectoryName( Path.Combine(schemaPath, path).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))); bool includeComments = IncludeComments(path); var protocBinPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "protoc.bin")); int exitCode; string protocExe = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"windows\protoc" : RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? @"macosx/protoc" : ""; if (string.IsNullOrWhiteSpace(protocExe)) { throw new PlatformNotSupportedException(RuntimeInformation.OSDescription); } using (var proc = new Process()) { var psi = proc.StartInfo; psi.FileName = protocExe; psi.Arguments = $"--experimental_allow_proto3_optional --descriptor_set_out={protocBinPath} {path}"; if (includeComments) { psi.Arguments += " --include_source_info"; } if (includeImports) { psi.Arguments += " --include_imports"; } psi.RedirectStandardError = psi.RedirectStandardOutput = true; psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.WorkingDirectory = schemaPath; proc.Start(); var stdout = proc.StandardOutput.ReadToEndAsync(); var stderr = proc.StandardError.ReadToEndAsync(); if (!proc.WaitForExit(5000)) { try { proc.Kill(); } catch { } } exitCode = proc.ExitCode; string err = "", @out = ""; if (stdout.Wait(1000)) { @out = stdout.Result; } if (stderr.Wait(1000)) { err = stderr.Result; } if (!string.IsNullOrWhiteSpace(@out)) { _output.WriteLine("stdout: "); _output.WriteLine(@out); } if (!string.IsNullOrWhiteSpace(err)) { _output.WriteLine("stderr: "); _output.WriteLine(err); } } FileDescriptorSet set; string protocJson = null, jsonPath; if (exitCode == 0) { using var file = File.OpenRead(protocBinPath); set = CustomProtogenSerializer.Instance.Deserialize <FileDescriptorSet>(file); protocJson = JsonConvert.SerializeObject(set, Formatting.Indented, jsonSettings); jsonPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "protoc.json")); File.WriteAllText(jsonPath, protocJson); } set = new FileDescriptorSet(); set.AddImportPath(schemaPath); bool isProto3 = set.Add(path, includeInOutput: true) && set.Files[0].Syntax == "proto3"; if (isProto3) { using var proc = new Process(); var psi = proc.StartInfo; psi.FileName = protocExe; psi.Arguments = $"--experimental_allow_proto3_optional --csharp_out={Path.GetDirectoryName(protocBinPath)} {path}"; psi.RedirectStandardError = psi.RedirectStandardOutput = true; psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.WorkingDirectory = schemaPath; proc.Start(); var stdout = proc.StandardOutput.ReadToEndAsync(); var stderr = proc.StandardError.ReadToEndAsync(); if (!proc.WaitForExit(5000)) { try { proc.Kill(); } catch { } } exitCode = proc.ExitCode; string err = "", @out = ""; if (stdout.Wait(1000)) { @out = stdout.Result; } if (stderr.Wait(1000)) { err = stderr.Result; } if (!string.IsNullOrWhiteSpace(@out)) { _output.WriteLine("stdout (C#): "); _output.WriteLine(@out); } if (!string.IsNullOrWhiteSpace(err)) { _output.WriteLine("stderr (C#): "); _output.WriteLine(err); } _output.WriteLine("exit code(C#): " + exitCode); } set.Process(); set.ApplyFileDependencyOrder(); var parserBinPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "parser.bin")); using (var file = File.Create(parserBinPath)) { set.Serialize(CustomProtogenSerializer.Instance, file, includeImports); } var parserJson = set.Serialize((s, _) => JsonConvert.SerializeObject(s, Formatting.Indented, jsonSettings), includeImports); var errors = set.GetErrors(); Exception genError = null; try { var options = new Dictionary <string, string> { { "services", "true" }, }; foreach (var file in CSharpCodeGenerator.Default.Generate(set, options: options)) { var newExtension = "parser" + Path.GetExtension(file.Name); var newFileName = Path.ChangeExtension(file.Name, newExtension); File.WriteAllText(Path.Combine(schemaPath, newFileName), file.Text); } } catch (Exception ex) { genError = ex; _output.WriteLine(ex.Message); _output.WriteLine(ex.StackTrace); } jsonPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "parser.json")); File.WriteAllText(jsonPath, parserJson); if (errors.Length > 0) { _output.WriteLine("Parser errors:"); foreach (var err in errors) { _output.WriteLine(err.ToString()); } } _output.WriteLine("Protoc exited with code " + exitCode); var errorCount = errors.Count(x => x.IsError); if (exitCode == 0) { Assert.Equal(0, errorCount); } else { Assert.NotEqual(0, errorCount); } var parserBytes = File.ReadAllBytes(parserBinPath); using (var ms = new MemoryStream(parserBytes)) { var selfLoad = CustomProtogenSerializer.Instance.Deserialize <FileDescriptorSet>(ms); var selfLoadJson = JsonConvert.SerializeObject(selfLoad, Formatting.Indented, jsonSettings); // should still be the same! Assert.Equal(parserJson, selfLoadJson); } var parserHex = GetPrettyHex(parserBytes); File.WriteAllText(Path.ChangeExtension(parserBinPath, "parser.hex"), parserHex); if (exitCode == 0) { var protocHex = GetPrettyHex(File.ReadAllBytes(protocBinPath)); File.WriteAllText(Path.ChangeExtension(protocBinPath, "protoc.hex"), protocHex); switch (path) { case "google/protobuf/unittest_custom_options.proto": case "advancedOptions.proto": // these are special cases; the two encoders choose slightly different // layouts for the same data; both are valid; I'm happy that this is OK // - this was why the "decode" tool (on the website) was written! break; case "google/protobuf/unittest.proto": // ^^^ different layout of an integer; "2e+8" vs "200000000" - I'm fine with it // // the following end up importing unittest.proto, so have the same symptom case "google/protobuf/map_unittest.proto" when(includeImports): case "google/protobuf/unittest_optimize_for.proto" when(includeImports): case "google/protobuf/unittest_embed_optimize_for.proto" when(includeImports): case "google/protobuf/unittest_lite_imports_nonlite.proto" when(includeImports): case "google/protobuf/unittest_no_field_presence.proto" when(includeImports): break; default: // compare results Assert.Equal(protocJson, parserJson); Assert.Equal(protocHex, parserHex); break; } } Assert.Null(genError); }
public override bool Execute() { var codegen = GetCodeGenForLanguage(Language); if (ProtoDef == null || ProtoDef.Length == 0) { return(true); } var set = new FileDescriptorSet { DefaultPackage = DefaultNamespace }; if (ImportPaths == null || ImportPaths.Length == 0) { set.AddImportPath(Directory.GetCurrentDirectory()); } else { foreach (var dir in ImportPaths) { if (Directory.Exists(dir.ItemSpec)) { set.AddImportPath(dir.ItemSpec); } else { this.Log.LogError($"Directory not found: {dir}"); return(false); } } } foreach (var input in ProtoDef) { if (!set.Add(input.ItemSpec, true)) { Log.LogError($"File not found: {input}"); return(false); } } set.Process(); var errors = set.GetErrors(); if (errors != null && errors.Length > 0) { foreach (var error in errors) { var endCol = error.LineNumber + error.Text.Length; int errNum = error.ErrorNumber; var errCode = errNum == 0 ? null : ("PBN" + errNum.ToString("0000")); if (error.IsError) { this.Log.LogError("protogen", errCode, null, error.File, error.LineNumber, error.ColumnNumber, error.LineNumber, endCol, error.Message); } else if (error.IsWarning) { this.Log.LogWarning("protogen", errCode, null, error.File, error.LineNumber, error.ColumnNumber, error.LineNumber, endCol, error.Message); } } return(false); } var options = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); var codeFiles = new List <ITaskItem>(); var files = codegen.Generate(set, options: options); foreach (var file in files) { var path = Path.Combine(OutputPath, file.Name); var dir = Path.GetDirectoryName(path); Directory.CreateDirectory(dir); File.WriteAllText(path, file.Text); codeFiles.Add(new TaskItem(path)); } this.ProtoCodeFile = codeFiles.Cast <ITaskItem>().ToArray(); return(true); }
public void CompareProtoToParser(string path) { var schemaPath = Path.Combine(Directory.GetCurrentDirectory(), SchemaPath); _output.WriteLine(Path.GetDirectoryName( Path.Combine(schemaPath, path).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))); bool includeComments = IncludeComments(path); var protocBinPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "protoc.bin")); int exitCode; using (var proc = new Process()) { var psi = proc.StartInfo; psi.FileName = "protoc"; psi.Arguments = $"--descriptor_set_out={protocBinPath} {path}"; if (includeComments) { psi.Arguments += " --include_source_info"; } psi.RedirectStandardError = psi.RedirectStandardOutput = true; psi.UseShellExecute = false; psi.WorkingDirectory = schemaPath; proc.Start(); var stdout = proc.StandardOutput.ReadToEndAsync(); var stderr = proc.StandardError.ReadToEndAsync(); if (!proc.WaitForExit(5000)) { try { proc.Kill(); } catch { } } exitCode = proc.ExitCode; string err = "", @out = ""; if (stdout.Wait(1000)) { @out = stdout.Result; } if (stderr.Wait(1000)) { err = stderr.Result; } if (!string.IsNullOrWhiteSpace(@out)) { _output.WriteLine("stdout: "); _output.WriteLine(@out); } if (!string.IsNullOrWhiteSpace(err)) { _output.WriteLine("stderr: "); _output.WriteLine(err); } } FileDescriptorSet set; string protocJson = null, jsonPath; if (exitCode == 0) { using (var file = File.OpenRead(protocBinPath)) { set = Serializer.Deserialize <FileDescriptorSet>(file); protocJson = JsonConvert.SerializeObject(set, Formatting.Indented, jsonSettings); jsonPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "protoc.json")); File.WriteAllText(jsonPath, protocJson); } } set = new FileDescriptorSet(); set.AddImportPath(schemaPath); bool isProto3 = set.Add(path, includeInOutput: true) && set.Files[0].Syntax == "proto3"; if (isProto3) { using (var proc = new Process()) { var psi = proc.StartInfo; psi.FileName = "protoc"; psi.Arguments = $"--csharp_out={Path.GetDirectoryName(protocBinPath)} {path}"; psi.RedirectStandardError = psi.RedirectStandardOutput = true; psi.UseShellExecute = false; psi.WorkingDirectory = schemaPath; proc.Start(); var stdout = proc.StandardOutput.ReadToEndAsync(); var stderr = proc.StandardError.ReadToEndAsync(); if (!proc.WaitForExit(5000)) { try { proc.Kill(); } catch { } } exitCode = proc.ExitCode; string err = "", @out = ""; if (stdout.Wait(1000)) { @out = stdout.Result; } if (stderr.Wait(1000)) { err = stderr.Result; } if (!string.IsNullOrWhiteSpace(@out)) { _output.WriteLine("stdout (C#): "); _output.WriteLine(@out); } if (!string.IsNullOrWhiteSpace(err)) { _output.WriteLine("stderr (C#): "); _output.WriteLine(err); } _output.WriteLine("exit code(C#): " + exitCode); } } set.Process(); var parserBinPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "parser.bin")); using (var file = File.Create(parserBinPath)) { set.Serialize(file, false); } var parserJson = set.Serialize((s, o) => JsonConvert.SerializeObject(s, Formatting.Indented, jsonSettings), false); var errors = set.GetErrors(); Exception genError = null; try { foreach (var file in CSharpCodeGenerator.Default.Generate(set)) { var newExtension = "parser" + Path.GetExtension(file.Name); var newFileName = Path.ChangeExtension(file.Name, newExtension); File.WriteAllText(Path.Combine(schemaPath, newFileName), file.Text); } } catch (Exception ex) { genError = ex; _output.WriteLine(ex.Message); _output.WriteLine(ex.StackTrace); } jsonPath = Path.Combine(schemaPath, Path.ChangeExtension(path, "parser.json")); File.WriteAllText(jsonPath, parserJson); if (errors.Any()) { _output.WriteLine("Parser errors:"); foreach (var err in errors) { _output.WriteLine(err.ToString()); } } _output.WriteLine("Protoc exited with code " + exitCode); var errorCount = errors.Count(x => x.IsError); if (exitCode == 0) { Assert.Equal(0, errorCount); } else { Assert.NotEqual(0, errorCount); } var parserBytes = File.ReadAllBytes(parserBinPath); using (var ms = new MemoryStream(parserBytes)) { var selfLoad = Serializer.Deserialize <FileDescriptorSet>(ms); var selfLoadJson = JsonConvert.SerializeObject(selfLoad, Formatting.Indented, jsonSettings); // should still be the same! Assert.Equal(parserJson, selfLoadJson); } var parserHex = GetPrettyHex(parserBytes); File.WriteAllText(Path.ChangeExtension(parserBinPath, "parser.hex"), parserHex); if (exitCode == 0) { var protocHex = GetPrettyHex(File.ReadAllBytes(protocBinPath)); File.WriteAllText(Path.ChangeExtension(protocBinPath, "protoc.hex"), protocHex); switch (path) { case "google/protobuf/unittest_custom_options.proto": // this is a special case; the two encoders choose slightly different // layouts for the same data; both are valid; I'm happy that this is OK // - this was why the "decode" tool (on the website) was written! break; default: // compare results Assert.Equal(protocJson, parserJson); Assert.Equal(protocHex, parserHex); break; } } Assert.Null(genError); }
private static async Task <int> Main(string[] args) { try { string outPath = null; // -o{FILE}, --descriptor_set_out={FILE} bool version = false; // --version bool help = false; // -h, --help var importPaths = new List <string>(); // -I{PATH}, --proto_path={PATH} var inputFiles = new List <string>(); // {PROTO_FILES} (everything not `-`) bool exec = false; string package = null; // --package=foo string grpcMode = null, grpcUrl = null, grpcService = null; CodeGenerator codegen = null; Dictionary <string, string> options = null; for (int i = 0; i < args.Length; i++) { var arg = args[i]; string lhs = arg, rhs = ""; int index = arg.IndexOf('='); if (index > 0) { lhs = arg.Substring(0, index); rhs = arg.Substring(index + 1); } else if (arg.StartsWith("-o")) { lhs = "--descriptor_set_out"; rhs = arg.Substring(2); } else if (arg.StartsWith("-I")) { lhs = "--proto_path"; rhs = arg.Substring(2); } if (lhs.StartsWith("+")) { if (options == null) { options = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); } options[lhs.Substring(1)] = rhs; continue; } switch (lhs) { case "": break; case "--version": version = true; break; case "--package": package = rhs; break; case "-h": case "--help": help = true; break; case "--csharp_out": outPath = rhs; codegen = CSharpCodeGenerator.Default; exec = true; break; case "--vb_out": outPath = rhs; #pragma warning disable CS0618 codegen = VBCodeGenerator.Default; #pragma warning restore CS0618 exec = true; break; case "--descriptor_set_out": outPath = rhs; codegen = null; exec = true; break; case "--proto_path": importPaths.Add(rhs); break; case "--pwd": Console.WriteLine($"Current Directory: {Directory.GetCurrentDirectory()}"); #if NETCOREAPP2_1 || NETSTANDARD2_0 Console.WriteLine($"Program: {typeof(Program).Assembly.Location}"); Console.WriteLine($"CodeGenerator: {typeof(CodeGenerator).Assembly.Location}"); #endif break; case "--grpc": if (++i < args.Length) { grpcMode = args[i]; if (++i < args.Length) { grpcUrl = args[i]; if (string.Equals(grpcMode, "get", StringComparison.OrdinalIgnoreCase) && ++i < args.Length) { grpcService = args[i]; } } } break; default: if (lhs.StartsWith("-") || !string.IsNullOrWhiteSpace(rhs)) { help = true; break; } else { inputFiles.Add(lhs); } break; } } if (help) { ShowHelp(); return(0); } else if (version) { var ver = GetVersion(typeof(Program)); Console.WriteLine($"protogen {ver}"); var tmp = GetVersion <ProtoReader>(); if (tmp != ver) { Console.WriteLine($"protobuf-net {tmp}"); } tmp = GetVersion <FileDescriptorSet>(); if (tmp != ver) { Console.WriteLine($"protobuf-net.Reflection {tmp}"); } return(0); } else if (grpcMode is object) { #if GRPC_TOOLS return(await GrpcTools.ExecuteAsync(grpcMode, grpcUrl, grpcService, codegen, outPath, options)); #else Console.Error.Write("gRPC tools are not available on this platform"); await Task.Yield(); // this is just to make the compiler happy, and doesn't really matter return(1); #endif } else if (inputFiles.Count == 0) { Console.Error.WriteLine("Missing input file."); return(-1); } else if (!exec) { Console.Error.WriteLine("Missing output directives."); return(-1); } else { int exitCode = 0; var set = new FileDescriptorSet { DefaultPackage = package }; if (importPaths.Count == 0) { set.AddImportPath(Directory.GetCurrentDirectory()); } else { foreach (var dir in importPaths) { if (Directory.Exists(dir)) { set.AddImportPath(dir); } else { Console.Error.WriteLine($"Directory not found: {dir}"); exitCode = 1; } } } // add the library area for auto-imports (library inbuilts) set.AddImportPath(Path.GetDirectoryName(typeof(Program).Assembly.Location)); if (inputFiles.Count == 1 && importPaths.Count == 1) { SearchOption?searchOption = null; if (inputFiles[0] == "**/*.proto" || inputFiles[0] == "**\\*.proto") { searchOption = SearchOption.AllDirectories; set.AllowNameOnlyImport = true; } else if (inputFiles[0] == "*.proto") { searchOption = SearchOption.TopDirectoryOnly; } if (searchOption != null) { inputFiles.Clear(); var searchRoot = importPaths[0]; foreach (var path in Directory.EnumerateFiles(importPaths[0], "*.proto", searchOption.Value)) { inputFiles.Add(MakeRelativePath(searchRoot, path)); } } } foreach (var input in inputFiles) { if (!set.Add(input, true)) { Console.Error.WriteLine($"File not found: {input}"); exitCode = 1; } } if (exitCode != 0) { return(exitCode); } set.Process(); var errors = set.GetErrors(); foreach (var err in errors) { if (err.IsError) { exitCode++; } Console.Error.WriteLine(err.ToString()); } if (exitCode != 0) { return(exitCode); } if (codegen == null) { using (var fds = File.Create(outPath)) { Serializer.Serialize(fds, set); } return(0); } var files = codegen.Generate(set, options: options); WriteFiles(files, outPath); return(0); } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); return(-1); } }
public void Generate() { CodeGenResult = null; string schema = Monaco.GetCode("protocontainer"); if (string.IsNullOrWhiteSpace(schema)) { return; } Dictionary <string, string> options = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); options["langver"] = LangVer; if (OneOfEnum) { options["oneof"] = "enum"; } if (ListSet) { options["listset"] = "yes"; } NameNormalizer nameNormalizer = null; switch (Names) { case "auto": nameNormalizer = NameNormalizer.Default; break; case "original": nameNormalizer = NameNormalizer.Null; break; } var result = new GenerateResult(); try { using (var reader = new StringReader(schema)) { var set = new FileDescriptorSet { //ImportValidator = path => ValidateImport(path), }; //set.AddImportPath(Path.Combine(_host.WebRootPath, "protoc")); set.Add("my.proto", true, reader); set.Process(); var errors = set.GetErrors(); if (errors.Length > 0) { result.ParserExceptions = errors; } CodeGenerator codegen; switch (Tooling) { case "protogen:VB": #pragma warning disable 0618 codegen = VBCodeGenerator.Default; #pragma warning restore 0618 break; case "protogen:C#": default: codegen = CSharpCodeGenerator.Default; break; } result.Files = codegen.Generate(set, nameNormalizer, options).ToArray(); } } catch (Exception ex) { Console.WriteLine(ex); result.Exception = ex.Message; } CodeGenResult = result; Monaco.SetCode("csharpcontainer", CodeGenResult?.Files?.FirstOrDefault()?.Text ?? ""); JSInProcess.InvokeVoid("processResults", CodeGenResult); }
internal static async Task <int> ExecuteAsync(string modeString, string uri, string serviceName, CodeGenerator codegen, string outPath, Dictionary <string, string> options) { if (!Enum.TryParse <GrpcMode>(modeString, true, out var mode)) { Console.Error.WriteLine($"Unknown gRPC mode: '{modeString}'"); return(1); } if (string.IsNullOrWhiteSpace(outPath) && mode == GrpcMode.Get) { Console.Error.WriteLine($"Missing output directive; please specify --csharp_out etc"); return(1); } switch (mode) { case GrpcMode.List: Console.WriteLine($"Requesting gRPC service directory from '{uri}'..."); break; case GrpcMode.Get: Console.WriteLine($"Requesting gRPC '{serviceName}' service from '{uri}'..."); break; default: Console.Error.WriteLine($"Unexpected mode: {mode}"); return(1); } int errorCount = 0; GrpcClientFactory.AllowUnencryptedHttp2 = true; using var channel = GrpcChannel.ForAddress(uri); var service = channel.CreateGrpcService <IServerReflection>(); FileDescriptorSet set = null; int services = 0; try { await foreach (var reply in service.ServerReflectionInfoAsync(GetRequest())) { switch (reply.MessageResponseCase) { case ServerReflectionResponse.MessageResponseOneofCase.ListServicesResponse: foreach (var availableService in reply.ListServicesResponse.Services) { services++; Console.WriteLine($"- {availableService.Name}"); } break; case ServerReflectionResponse.MessageResponseOneofCase.FileDescriptorResponse: { var file = reply.FileDescriptorResponse; if (file is null) { continue; } foreach (byte[] payload in file.FileDescriptorProtoes) { var proto = Serializer.Deserialize <FileDescriptorProto>(new Span <byte>(payload)); proto.IncludeInOutput = true; // have to assume all foreach (var dependency in proto.Dependencies) { proto.AddImport(dependency, true, default); } (set ??= new FileDescriptorSet()).Files.Add(proto); } } break; case ServerReflectionResponse.MessageResponseOneofCase.ErrorResponse: errorCount++; var code = (StatusCode)reply.ErrorResponse.ErrorCode; Console.Error.WriteLine($"{code}: {reply.ErrorResponse.ErrorMessage}"); break; } } switch (mode) { case GrpcMode.List: Console.WriteLine($"gRPC services discovered: {services}"); break; case GrpcMode.Get: Console.WriteLine($"gRPC descriptors fetched: {set?.Files?.Count ?? 0}"); if (set is object) { set.Process(); foreach (var error in set.GetErrors()) { errorCount++; Console.WriteLine($"{(error.IsError ? "error" : "warning")} {error.ErrorNumber}: {error.Message}"); } Program.WriteFiles(codegen.Generate(set, options: options), outPath); } break; } } catch (RpcException fault) { errorCount++; Console.Error.WriteLine($"{fault.StatusCode}: {fault.Status.Detail}"); } return(errorCount); IAsyncEnumerable <ServerReflectionRequest> GetRequest() => mode switch { GrpcMode.List => ListServices(), GrpcMode.Get => GetFileContainingSymbol(serviceName), _ => Nothing(), };
static int Main(string[] args) { try { string outPath = null; // -o{FILE}, --descriptor_set_out={FILE} bool version = false; // --version bool help = false; // -h, --help var importPaths = new List <string>(); // -I{PATH}, --proto_path={PATH} var inputFiles = new List <string>(); // {PROTO_FILES} (everything not `-`) bool exec = false; string package = null; // --package=foo CodeGenerator codegen = null; Dictionary <string, string> options = null; foreach (string arg in args) { string lhs = arg, rhs = ""; int index = arg.IndexOf('='); if (index > 0) { lhs = arg.Substring(0, index); rhs = arg.Substring(index + 1); } else if (arg.StartsWith("-o")) { lhs = "--descriptor_set_out"; rhs = arg.Substring(2); } else if (arg.StartsWith("-I")) { lhs = "--proto_path"; rhs = arg.Substring(2); } if (lhs.StartsWith("+")) { if (options == null) { options = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); } options[lhs.Substring(1)] = rhs; continue; } switch (lhs) { case "": break; case "--version": version = true; break; case "--package": package = rhs; break; case "-h": case "--help": help = true; break; case "--csharp_out": outPath = rhs; codegen = CSharpCodeGenerator.Default; exec = true; break; case "--vb_out": outPath = rhs; #pragma warning disable CS0618 codegen = VBCodeGenerator.Default; #pragma warning restore CS0618 exec = true; break; case "--descriptor_set_out": outPath = rhs; codegen = null; exec = true; break; case "--proto_path": importPaths.Add(rhs); break; default: if (lhs.StartsWith("-") || !string.IsNullOrWhiteSpace(rhs)) { help = true; break; } else { inputFiles.Add(lhs); } break; } } if (help) { ShowHelp(); return(0); } else if (version) { Console.WriteLine($"protogen {GetVersion<Program>()}"); Console.WriteLine($"protobuf-net {GetVersion<ProtoReader>()}"); Console.WriteLine($"protobuf-net.Reflection {GetVersion<FileDescriptorSet>()}"); return(0); } else if (inputFiles.Count == 0) { Console.Error.WriteLine("Missing input file."); return(-1); } else if (!exec) { Console.Error.WriteLine("Missing output directives."); return(-1); } else { int exitCode = 0; var set = new FileDescriptorSet { DefaultPackage = package }; if (importPaths.Count == 0) { set.AddImportPath(Directory.GetCurrentDirectory()); } else { foreach (var dir in importPaths) { if (Directory.Exists(dir)) { set.AddImportPath(dir); } else { Console.Error.WriteLine($"Directory not found: {dir}"); exitCode = 1; } } } if (inputFiles.Count == 1 && importPaths.Count == 1) { SearchOption?searchOption = null; if (inputFiles[0] == "**/*.proto" || inputFiles[0] == "**\\*.proto") { searchOption = SearchOption.AllDirectories; set.AllowNameOnlyImport = true; } else if (inputFiles[0] == "*.proto") { searchOption = SearchOption.TopDirectoryOnly; } if (searchOption != null) { inputFiles.Clear(); var searchRoot = importPaths[0]; foreach (var path in Directory.EnumerateFiles(importPaths[0], "*.proto", searchOption.Value)) { inputFiles.Add(MakeRelativePath(searchRoot, path)); } } } foreach (var input in inputFiles) { if (!set.Add(input, true)) { Console.Error.WriteLine($"File not found: {input}"); exitCode = 1; } } if (exitCode != 0) { return(exitCode); } set.Process(); var errors = set.GetErrors(); foreach (var err in errors) { if (err.IsError) { exitCode++; } Console.Error.WriteLine(err.ToString()); } if (exitCode != 0) { return(exitCode); } if (codegen == null) { using (var fds = File.Create(outPath)) { Serializer.Serialize(fds, set); } } var files = codegen.Generate(set, options: options); foreach (var file in files) { var path = Path.Combine(outPath, file.Name); var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) { Console.Error.WriteLine($"Output directory does not exist, creating... {dir}"); Directory.CreateDirectory(dir); } File.WriteAllText(path, file.Text); Console.WriteLine($"generated: {path}"); } return(0); } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); return(-1); } }
static int Main(string[] args) { try { string outPath = null; // -o{FILE}, --descriptor_set_out={FILE} bool version = false; // --version bool help = false; // -h, --help var importPaths = new List <string>(); // -I{PATH}, --proto_path={PATH} var inputFiles = new List <string>(); // {PROTO_FILES} (everything not `-`) bool exec = false; CodeGenerator codegen = null; foreach (string arg in args) { string lhs = arg, rhs = ""; int index = arg.IndexOf('='); if (index > 0) { lhs = arg.Substring(0, index); rhs = arg.Substring(index + 1); } else if (arg.StartsWith("-o")) { lhs = "--descriptor_set_out"; rhs = arg.Substring(2); } else if (arg.StartsWith("-I")) { lhs = "--proto_path"; rhs = arg.Substring(2); } switch (lhs) { case "": break; case "--version": version = true; break; case "-h": case "--help": help = true; break; case "--csharp_out": outPath = rhs; codegen = CSharpCodeGenerator.Default; exec = true; break; case "--descriptor_set_out": outPath = rhs; codegen = null; exec = true; break; case "--proto_path": importPaths.Add(rhs); break; default: if (lhs.StartsWith("-") || !string.IsNullOrWhiteSpace(rhs)) { help = true; break; } else { inputFiles.Add(lhs); } break; } } if (help) { ShowHelp(); return(0); } else if (version) { Console.WriteLine($"protogen {GetVersion<Program>()}"); Console.WriteLine($"protobuf-net {GetVersion<ProtoReader>()}"); Console.WriteLine($"protobuf-net.Reflection {GetVersion<FileDescriptorSet>()}"); return(0); } else if (inputFiles.Count == 0) { Console.Error.WriteLine("Missing input file."); return(-1); } else if (!exec) { Console.Error.WriteLine("Missing output directives."); return(-1); } else { int exitCode = 0; var set = new FileDescriptorSet(); if (importPaths.Count == 0) { set.AddImportPath(Directory.GetCurrentDirectory()); } else { foreach (var dir in importPaths) { if (Directory.Exists(dir)) { set.AddImportPath(dir); } else { Console.Error.WriteLine($"Directory not found: {dir}"); exitCode = 1; } } } foreach (var input in inputFiles) { if (!set.Add(input, true)) { Console.Error.WriteLine($"File not found: {input}"); exitCode = 1; } } if (exitCode != 0) { return(exitCode); } set.Process(); var errors = set.GetErrors(); foreach (var err in errors) { if (err.IsError) { exitCode++; } Console.Error.WriteLine(err.ToString()); } if (exitCode != 0) { return(exitCode); } if (codegen == null) { using (var fds = File.Create(outPath)) { Serializer.Serialize(fds, set); } } else { var files = codegen.Generate(set); foreach (var file in files) { var path = Path.Combine(outPath, file.Name); File.WriteAllText(path, file.Text); Console.WriteLine($"generated: {path}"); } } return(0); } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); return(-1); } }
private int Export() { textBox3.Text = ""; System.Text.StringBuilder tnewmsg = new StringBuilder(); int exitCode = 0; mSPath = textBox1.Text; mDPaht = textBox2.Text; if (string.IsNullOrEmpty(mSPath) || string.IsNullOrEmpty(mDPaht)) { return(1); } string tpathfile = Directory.GetCurrentDirectory() + mPathsFile; StringBuilder tstrb = new StringBuilder(); tstrb.AppendLine(mSPath); tstrb.AppendLine(mDPaht); File.WriteAllText(tpathfile, tstrb.ToString()); tnewmsg.AppendLine(System.DateTime.Now.ToString() + ":开始导出."); textBox3.Text = tnewmsg.ToString(); ILCodeGen codegen = ILCodeGen.Default; var set = new FileDescriptorSet(); set.AddImportPath(mSPath); string[] tpaths = Directory.GetDirectories(mSPath); foreach (string tp in tpaths) { set.AddImportPath(tp); } DirectoryInfo tdirfolder = new DirectoryInfo(mSPath); FileInfo[] tfileinfos = tdirfolder.GetFiles("*.proto", System.IO.SearchOption.AllDirectories); foreach (var input in tfileinfos) { if (!set.Add(input.Name, true)) { Console.Error.WriteLine($"File not found: {input}"); exitCode = 1; } } set.Process(); var errors = set.GetErrors(); foreach (var err in errors) { if (err.IsError) { exitCode++; } tnewmsg.AppendLine(err.ToString()); Console.Error.WriteLine(err.ToString()); } textBox3.Text = tnewmsg.ToString(); if (exitCode != 0) { return(exitCode); } var files = codegen.Generate(set); foreach (var file in files) { var path = Path.Combine(mDPaht, file.Name); File.WriteAllText(path, file.Text); } tnewmsg.AppendLine(System.DateTime.Now.ToString() + ":导出结束."); textBox3.Text = tnewmsg.ToString(); return(0); }
static ErrorCode GenerateCode(StreamWriter writer, string basePath, string inputPath, string outputPath, bool current) { string inputFolder = GetFolderName(inputPath); string inputRelativePath = MakeRelativePath(basePath, inputPath); #region Get the list of .proto files. var fileDescriptorSet = new FileDescriptorSet { AllowNameOnlyImport = true, }; fileDescriptorSet.AddImportPath(inputPath); var inputFiles = new List <string>(); foreach (var path in Directory.EnumerateFiles(inputPath, "*.proto", SearchOption.AllDirectories)) { inputFiles.Add(MakeRelativePath(inputPath, path)); } bool error = false; foreach (var proto in inputFiles) { if (!fileDescriptorSet.Add(proto, true)) { error = true; ConsoleOutput.OutputError($"Error Loading: {proto}"); } } if (error) { return(ErrorCode.InvalidProto); } fileDescriptorSet.Process(); var errors = fileDescriptorSet.GetErrors(); if (errors.Length > 0) { foreach (var err in errors) { ConsoleOutput.OutputError(err.ToString()); } return(ErrorCode.FileDescriptorSetProcessFailure); } #endregion Get the list of .proto files. #region Generate the files. Dictionary <string, string> options = new Dictionary <string, string>(); if (!current) { string version = inputFolder; options.Add("PROTO_VERSION", version); outputPath = Path.Combine(outputPath, version); } string outputRelativePath = MakeRelativePath(basePath, outputPath); writer.WriteLine($"<!-- {outputRelativePath} -->"); writer.WriteLine(" <ItemGroup>"); foreach (var file in GM_CSharpCodeGenerator.Default.Generate(fileDescriptorSet, null, options)) { var filePath = Path.Combine(outputPath, file.Name); var fileFolder = Path.GetDirectoryName(filePath); if (!Directory.Exists(fileFolder)) { ConsoleOutput.OutputWarning($"Output directory does not exist, creating... {fileFolder}"); Directory.CreateDirectory(fileFolder); } File.WriteAllText(filePath, file.Text); writer.WriteLine($" <Compile Include=\"{Path.Combine(outputRelativePath, file.Name)}\">"); writer.WriteLine($" <Visible>true</Visible>"); writer.WriteLine($" </Compile>"); ConsoleOutput.OutputSuccess($"generated: {filePath}"); } writer.WriteLine(" </ItemGroup>"); writer.WriteLine(" <ItemGroup>"); foreach (var file in fileDescriptorSet.Files) { writer.WriteLine($" <None Include=\"{Path.Combine(inputRelativePath, file.Name)}\">"); writer.WriteLine($" <Visible>true</Visible>"); writer.WriteLine($" </None>"); } writer.WriteLine(" </ItemGroup>"); writer.WriteLine(); ConsoleOutput.OutputSuccess($"generated: {ProjFile}"); #endregion Generate the files. return(ErrorCode.Success); }
public GenerateResult Generate(string schema = null, string tooling = null, string names = null) { if (string.IsNullOrWhiteSpace(schema)) { return(null); } Dictionary <string, string> options = null; foreach (var field in Request.Form) { switch (field.Key) { case nameof(schema): case nameof(tooling): case nameof(names): break; // handled separately default: string s = field.Value; if (!string.IsNullOrWhiteSpace(s)) { if (options == null) { options = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); } options[field.Key] = s; } break; } } NameNormalizer nameNormalizer = null; switch (names) { case "auto": nameNormalizer = NameNormalizer.Default; break; case "original": nameNormalizer = NameNormalizer.Null; break; } var result = new GenerateResult(); try { using (var reader = new StringReader(schema)) { var set = new FileDescriptorSet { ImportValidator = path => ValidateImport(path), }; set.AddImportPath(Path.Combine(_host.WebRootPath, "protoc")); set.Add("my.proto", true, reader); set.Process(); var errors = set.GetErrors(); if (!ProtocTooling.IsDefined(tooling)) { if (errors.Length > 0) { result.ParserExceptions = errors; } CodeGenerator codegen; switch (tooling) { case "protogen:VB": #pragma warning disable 0618 codegen = VBCodeGenerator.Default; #pragma warning restore 0618 break; case "protogen:C#": default: codegen = CSharpCodeGenerator.Default; break; } result.Files = codegen.Generate(set, nameNormalizer, options).ToArray(); } else { // we're going to offer protoc! hold me... if (errors.Length != 0 && schema.Contains("import")) { // code output disabled because of import } else { result.Files = RunProtoc(_host, schema, tooling, out errors); if (errors.Length > 0) { result.ParserExceptions = errors; } } } } } catch (Exception ex) { result.Exception = ex; } return(result); }
static ErrorCode GenerateCode(string inputBaseFolder, string projectBaseFolder, string codeOutputRelativeFolder) { #region Validate Parameters if (!Directory.Exists(inputBaseFolder)) { ConsoleOutput.OutputError($"inputBaseFolder not found: \"{inputBaseFolder}\""); return(ErrorCode.InputBaseFolderDoesNotExist); } if (!Directory.Exists(projectBaseFolder)) { ConsoleOutput.OutputWarning($"projectBaseFolder not found, creating \"{projectBaseFolder}\"..."); Directory.CreateDirectory(projectBaseFolder); if (!Directory.Exists(projectBaseFolder)) { ConsoleOutput.OutputError($"Could not create projectBaseFolder: \"{projectBaseFolder}\""); return(ErrorCode.ProjectBaseFolderCouldNotBeCreated); } else { ConsoleOutput.OutputSuccess("Success"); } } string codeOutputBaseFolder = Path.Combine(projectBaseFolder, codeOutputRelativeFolder); if (!Directory.Exists(codeOutputBaseFolder)) { ConsoleOutput.OutputWarning($"codeOutputRelativeFolder not found, creating \"{codeOutputBaseFolder}\"..."); Directory.CreateDirectory(codeOutputBaseFolder); if (!Directory.Exists(codeOutputBaseFolder)) { ConsoleOutput.OutputError($"Could not create codeOutputRelativeFolder: \"{codeOutputBaseFolder}\""); return(ErrorCode.CodeOutputFolderCouldNotBeCreated); } else { ConsoleOutput.OutputSuccess("Success"); } } #endregion Validate Parameters try { ErrorCode result = ErrorCode.Success; var fileDescriptorSet = new FileDescriptorSet { AllowNameOnlyImport = true }; fileDescriptorSet.AddImportPath(inputBaseFolder); var inputFiles = new List <string>(); foreach (var path in Directory.EnumerateFiles(inputBaseFolder, "*.proto", SearchOption.AllDirectories)) { inputFiles.Add(MakeRelativePath(inputBaseFolder, path)); } bool error = false; foreach (var proto in inputFiles) { if (!fileDescriptorSet.Add(proto, true)) { error = true; ConsoleOutput.OutputError($"Error Loading: {proto}"); } } if (error) { return(ErrorCode.InvalidProto); } fileDescriptorSet.Process(); var errors = fileDescriptorSet.GetErrors(); if (errors.Length > 0) { StringBuilder stringBuilder = new StringBuilder(); foreach (var err in errors) { stringBuilder.AppendLine(err.ToString()); } ConsoleOutput.OutputError(stringBuilder.ToString()); return(ErrorCode.FileDescriptorSetProcessFailure); } #region Generate the files. Dictionary <string, string> options = new Dictionary <string, string>(); using (StreamWriter writer = new StreamWriter(Path.Combine(projectBaseFolder, ProjFile))) { writer.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">"); writer.WriteLine(" <!-- ======================================================================= -->"); writer.WriteLine(" <!-- =============== This file is generated by GM_protogen. ================ -->"); writer.WriteLine(" <!-- ======================================================================= -->"); writer.WriteLine(); writer.WriteLine(" <!-- Generated .cs files -->"); writer.WriteLine(" <ItemGroup>"); foreach (var file in GM_CSharpCodeGenerator.Default.Generate(fileDescriptorSet, null, options)) { var filePath = Path.Combine(codeOutputBaseFolder, file.Name); var fileFolder = Path.GetDirectoryName(filePath); if (!Directory.Exists(fileFolder)) { ConsoleOutput.OutputWarning($"Output directory does not exist, creating... {fileFolder}"); Directory.CreateDirectory(fileFolder); } File.WriteAllText(filePath, file.Text); writer.WriteLine($" <Compile Include=\"{Path.Combine(codeOutputRelativeFolder, file.Name)}\">"); writer.WriteLine($" <Visible>true</Visible>"); writer.WriteLine($" </Compile>"); ConsoleOutput.OutputSuccess($"generated: {filePath}"); } writer.WriteLine(" </ItemGroup>"); writer.WriteLine(); writer.WriteLine("</Project>"); } ConsoleOutput.OutputSuccess($"generated: {ProjFile}"); #endregion Generate the files. return(result); } catch (Exception ex) { ConsoleOutput.OutputException(ex); return(ErrorCode.Exception); } }