public void DescriptorProtoVB() { var schemaPath = Path.Combine(Directory.GetCurrentDirectory(), SchemaPath); var path = "descriptor.proto"; var set = new FileDescriptorSet(); set.AddImportPath(schemaPath); set.Add(path, includeInOutput: true); set.Process(); #pragma warning disable CS0618 var sourceFiles = VBCodeGenerator.Default.Generate(set).Select(x => x.Text).ToArray(); #pragma warning restore CS0618 Assert.Single(sourceFiles); _output.WriteLine(sourceFiles[0]); var vb = new VBCodeProvider(new Dictionary <string, string> { { "CompilerVersion", "v3.5" } }); var p = new CompilerParameters { GenerateInMemory = true }; p.ReferencedAssemblies.Add(typeof(ProtoContractAttribute).Assembly.Location); // add protobuf-net reference p.ReferencedAssemblies.Add("System.dll"); // for [DefaultValue] p.ReferencedAssemblies.Add("System.Core.dll"); // for extension methods var results = vb.CompileAssemblyFromSource(p, sourceFiles); Assert.Empty(results.Errors); }
/// <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); }
/// <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())); }
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); }
public void LargeDefaultValueIsCorrect() { var schemaPath = Path.Combine(Directory.GetCurrentDirectory(), SchemaPath); const string path = "bigIntegerDefaultValue.proto"; var set = new FileDescriptorSet(); set.AddImportPath(schemaPath); set.Add(path, includeInOutput: true); set.Process(); var langver = set.Files[0].Options.GetOptions()?.CSharpLanguageVersion; Assert.Equal("3", langver); var sourceFiles = CSharpCodeGenerator.Default.Generate(set).Select(x => x.Text).ToArray(); Assert.Single(sourceFiles); _output.WriteLine(sourceFiles[0]); var csharp = new CSharpCodeProvider(new Dictionary <string, string> { { "CompilerVersion", "v3.5" } }); var p = new CompilerParameters { GenerateInMemory = true }; p.ReferencedAssemblies.Add(typeof(ProtoContractAttribute).Assembly.Location); // add protobuf-net reference p.ReferencedAssemblies.Add("System.dll"); // for [DefaultValue] p.ReferencedAssemblies.Add("System.Core.dll"); // for extension methods CompilerResults results; try { results = csharp.CompileAssemblyFromSource(p, sourceFiles); Assert.Empty(results.Errors); } catch (PlatformNotSupportedException) { return; } var assembly = results.CompiledAssembly; var messageType = assembly.GetType("TestMessage"); var properties = messageType.GetProperties(); Assert.Equal(2, properties.Length); foreach (var property in properties) { var defaultValueAttribute = (DefaultValueAttribute)Attribute.GetCustomAttribute(property, typeof(DefaultValueAttribute)); Assert.NotNull(defaultValueAttribute); Assert.Equal(18446744073709551615UL, defaultValueAttribute.Value); } }
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); }
internal static FileDescriptorSet Create(IEnumerable <Type> serviceTypes, BinderConfiguration?binderConfiguration = null) { var fileDescriptorSet = new FileDescriptorSet(); binderConfiguration ??= BinderConfiguration.Default; foreach (var serviceType in serviceTypes) { Populate(fileDescriptorSet, serviceType, binderConfiguration); } fileDescriptorSet.Process(); return(fileDescriptorSet); }
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 EverythingProtoLangver3() { Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); var schemaPath = Path.Combine(Directory.GetCurrentDirectory(), SchemaPath); const string path = "everything.proto"; var set = new FileDescriptorSet(); set.AddImportPath(schemaPath); set.Add(path, includeInOutput: true); set.Process(); var langver = set.Files[0].Options.GetOptions()?.CSharpLanguageVersion; Assert.Equal("3", langver); var sourceFiles = CSharpCodeGenerator.Default.Generate(set).Select(x => x.Text).ToArray(); Assert.Single(sourceFiles); _output.WriteLine(sourceFiles[0]); using var csharp = new CSharpCodeProvider(new Dictionary <string, string> { { "CompilerVersion", "v3.5" } }); var p = new CompilerParameters { GenerateInMemory = true }; p.ReferencedAssemblies.Add(typeof(ProtoContractAttribute).Assembly.Location); // add protobuf-net reference p.ReferencedAssemblies.Add("System.dll"); // for [DefaultValue] p.ReferencedAssemblies.Add("System.Core.dll"); // for extension methods try { var results = csharp.CompileAssemblyFromSource(p, sourceFiles); var count = results.Errors.Count; Assert.Equal(3, count); foreach (CompilerError error in results.Errors) { Assert.Equal("CS0619", error.ErrorNumber); var txt = error.ErrorText; bool expected = txt.StartsWith("'ProtoBuf.ProtoMemberAttribute.AsReference' is obsolete") || txt.StartsWith("'ProtoBuf.ProtoMemberAttribute.DynamicType' is obsolete"); Assert.True(expected); } } catch (PlatformNotSupportedException) { } }
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 FileDescriptorSet ParseFiles(Options arguments) { var set = new FileDescriptorSet { DefaultPackage = arguments.Namespace }; set.AddImportPath(Path.GetDirectoryName(arguments.ProtobufPath)); var fileName = Path.GetFileName(arguments.ProtobufPath); if (!set.Add(fileName, includeInOutput: true)) { Console.Error.WriteLine($"Could not find file '{fileName}'."); return(null); } set.Process(); return(set); }
/// <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>(); try { results.AddRange(Generate(set)); } catch (Exception ex) { var errorCode = ex is ParserException pe ? pe.ErrorCode : ErrorCode.Undefined; set.Errors.Add(new Error(default, ex.Message, true, errorCode));
static FileDescriptorSet ReparseFiles(Options arguments, FileDescriptorSet firstPass) { var set = new FileDescriptorSet { DefaultPackage = firstPass.DefaultPackage }; set.AddImportPath(Path.GetDirectoryName(arguments.ProtobufPath)); foreach (var file in firstPass.Files) { if (string.IsNullOrEmpty(file.Syntax)) { file.Syntax = "proto2"; } set.Files.Add(file); } set.Process(); return(set); }
static void Main(string[] args) { try { if (args.Length < 1) { Console.WriteLine("You need to specify a path to the proto file to use"); } else { var set = new FileDescriptorSet(); var r = File.OpenText($@"{args[0]}"); var defaultOutputName = Path.GetFileName(args[0]); if (args.Length > 1) { defaultOutputName = args[1]; } set.Add(defaultOutputName, true, r); set.Process(); var gen = new GrainGen(); var res = gen.Generate(set).ToList(); foreach (var items in res) { File.WriteAllText(items.Name, items.Text); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
public void EverythingProtoLangver3() { var schemaPath = Path.Combine(Directory.GetCurrentDirectory(), SchemaPath); const string path = "everything.proto"; var set = new FileDescriptorSet(); set.AddImportPath(schemaPath); set.Add(path, includeInOutput: true); set.Process(); var langver = set.Files[0].Options.GetOptions()?.CSharpLanguageVersion; Assert.Equal("3", langver); var sourceFiles = CSharpCodeGenerator.Default.Generate(set).Select(x => x.Text).ToArray(); Assert.Single(sourceFiles); _output.WriteLine(sourceFiles[0]); var csharp = new CSharpCodeProvider(new Dictionary <string, string> { { "CompilerVersion", "v3.5" } }); var p = new CompilerParameters { GenerateInMemory = true }; p.ReferencedAssemblies.Add(typeof(ProtoContractAttribute).Assembly.Location); // add protobuf-net reference p.ReferencedAssemblies.Add("System.dll"); // for [DefaultValue] p.ReferencedAssemblies.Add("System.Core.dll"); // for extension methods try { var results = csharp.CompileAssemblyFromSource(p, sourceFiles); Assert.Empty(results.Errors); } catch (PlatformNotSupportedException) { } }
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}"); } }
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 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); } }
public void Process() => _fileDescriptorSet.Process();
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); }
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); } }
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); }
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); }
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); } }