You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by dk...@apache.org on 2018/12/05 14:54:06 UTC
[avro] branch master updated: AVRO-2156: Map Avro namespace to C#
namespaces during code generation
This is an automated email from the ASF dual-hosted git repository.
dkulp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new 602a2c5 AVRO-2156: Map Avro namespace to C# namespaces during code generation
602a2c5 is described below
commit 602a2c5b5258d5e1f0f60f71506b16801cbdf156
Author: Brian Lachniet <bl...@gmail.com>
AuthorDate: Sat Mar 10 18:34:49 2018 -0500
AVRO-2156: Map Avro namespace to C# namespaces during code generation
---
lang/csharp/src/apache/codegen/AvroGen.cs | 111 ++++++++++++++++++++--
lang/csharp/src/apache/main/CodeGen/CodeGen.cs | 12 ++-
lang/csharp/src/apache/test/CodGen/CodeGenTest.cs | 37 ++++++++
3 files changed, 150 insertions(+), 10 deletions(-)
diff --git a/lang/csharp/src/apache/codegen/AvroGen.cs b/lang/csharp/src/apache/codegen/AvroGen.cs
index 033b840..465857f 100644
--- a/lang/csharp/src/apache/codegen/AvroGen.cs
+++ b/lang/csharp/src/apache/codegen/AvroGen.cs
@@ -25,25 +25,111 @@ namespace Avro
{
static void Main(string[] args)
{
- if (args.Length != 3)
+ // Print usage if no arguments provided or help requested
+ if (args.Length == 0 || args[0] == "-h" || args[0] == "--help")
{
Usage();
return;
}
- if (args[0] == "-p")
- GenProtocol(args[1], args[2]);
- else if (args[0] == "-s")
- GenSchema(args[1], args[2]);
- else
+
+ // Parse command line arguments
+ bool? isProtocol = null;
+ string inputFile = null;
+ string outputDir = null;
+ var namespaceMapping = new Dictionary<string, string>();
+ for (int i = 0; i < args.Length; ++i)
+ {
+ if (args[i] == "-p")
+ {
+ if (i + 1 >= args.Length)
+ {
+ Console.WriteLine("Missing path to protocol file");
+ Usage();
+ return;
+ }
+
+ isProtocol = true;
+ inputFile = args[++i];
+ }
+ else if (args[i] == "-s")
+ {
+ if (i + 1 >= args.Length)
+ {
+ Console.WriteLine("Missing path to schema file");
+ Usage();
+ return;
+ }
+
+ isProtocol = false;
+ inputFile = args[++i];
+ }
+ else if (args[i] == "--namespace")
+ {
+ if (i + 1 >= args.Length)
+ {
+ Console.WriteLine("Missing namespace mapping");
+ Usage();
+ return;
+ }
+
+ var parts = args[++i].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (parts.Length != 2)
+ {
+ Console.WriteLine("Malformed namespace mapping. Required format is \"avro.namespace:csharp.namespace\"");
+ Usage();
+ return;
+ }
+
+ namespaceMapping[parts[0]] = parts[1];
+ }
+ else if (outputDir == null)
+ {
+ outputDir = args[i];
+ }
+ else
+ {
+ Console.WriteLine("Unexpected command line argument: {0}", args[i]);
+ Usage();
+ }
+ }
+
+ // Ensure we got all the command line arguments we need
+ bool isValid = true;
+ if (!isProtocol.HasValue || inputFile == null)
+ {
+ Console.WriteLine("Must provide either '-p <protocolfile>' or '-s <schemafile>'");
+ isValid = false;
+ }
+ else if (outputDir == null)
+ {
+ Console.WriteLine("Must provide 'outputdir'");
+ isValid = false;
+ }
+
+ if (!isValid)
Usage();
+ else if (isProtocol.Value)
+ GenProtocol(inputFile, outputDir, namespaceMapping);
+ else
+ GenSchema(inputFile, outputDir, namespaceMapping);
}
static void Usage()
{
- Console.WriteLine("Usage:\navrogen -p <protocolfile> <outputdir>\navrogen -s <schemafile> <outputdir>");
+ Console.WriteLine("{0}\n\n" +
+ "Usage:\n" +
+ " avrogen -p <protocolfile> <outputdir> [--namespace <my.avro.ns:my.csharp.ns>]\n" +
+ " avrogen -s <schemafile> <outputdir> [--namespace <my.avro.ns:my.csharp.ns>]\n\n" +
+ "Options:\n" +
+ " -h --help Show this screen.\n" +
+ " --namespace Map an Avro schema/protocol namespace to a C# namespace.\n" +
+ " The format is \"my.avro.namespace:my.csharp.namespace\".\n" +
+ " May be specified multiple times to map multiple namespaces.\n",
+ AppDomain.CurrentDomain.FriendlyName);
return;
}
- static void GenProtocol(string infile, string outdir)
+ static void GenProtocol(string infile, string outdir,
+ IEnumerable<KeyValuePair<string, string>> namespaceMapping)
{
try
{
@@ -53,6 +139,9 @@ namespace Avro
CodeGen codegen = new CodeGen();
codegen.AddProtocol(protocol);
+ foreach (var entry in namespaceMapping)
+ codegen.NamespaceMapping[entry.Key] = entry.Value;
+
codegen.GenerateCode();
codegen.WriteTypes(outdir);
}
@@ -61,7 +150,8 @@ namespace Avro
Console.WriteLine("Exception occurred. " + ex.Message);
}
}
- static void GenSchema(string infile, string outdir)
+ static void GenSchema(string infile, string outdir,
+ IEnumerable<KeyValuePair<string, string>> namespaceMapping)
{
try
{
@@ -71,6 +161,9 @@ namespace Avro
CodeGen codegen = new CodeGen();
codegen.AddSchema(schema);
+ foreach (var entry in namespaceMapping)
+ codegen.NamespaceMapping[entry.Key] = entry.Value;
+
codegen.GenerateCode();
codegen.WriteTypes(outdir);
}
diff --git a/lang/csharp/src/apache/main/CodeGen/CodeGen.cs b/lang/csharp/src/apache/main/CodeGen/CodeGen.cs
index 2bcebab..c576200 100644
--- a/lang/csharp/src/apache/main/CodeGen/CodeGen.cs
+++ b/lang/csharp/src/apache/main/CodeGen/CodeGen.cs
@@ -45,6 +45,11 @@ namespace Avro
public IList<Protocol> Protocols { get; private set; }
/// <summary>
+ /// Mapping of Avro namespaces to C# namespaces
+ /// </summary>
+ public IDictionary<string, string> NamespaceMapping { get; private set; }
+
+ /// <summary>
/// List of generated namespaces
/// </summary>
protected Dictionary<string, CodeNamespace> namespaceLookup = new Dictionary<string, CodeNamespace>(StringComparer.Ordinal);
@@ -56,6 +61,7 @@ namespace Avro
{
this.Schemas = new List<Schema>();
this.Protocols = new List<Protocol>();
+ this.NamespaceMapping = new Dictionary<string, string>();
}
/// <summary>
@@ -90,7 +96,11 @@ namespace Avro
if (!namespaceLookup.TryGetValue(name, out ns))
{
- ns = new CodeNamespace(CodeGenUtil.Instance.Mangle(name));
+ string csharpNamespace;
+ ns = NamespaceMapping.TryGetValue(name, out csharpNamespace)
+ ? new CodeNamespace(csharpNamespace)
+ : new CodeNamespace(CodeGenUtil.Instance.Mangle(name));
+
foreach (CodeNamespaceImport nci in CodeGenUtil.Instance.NamespaceImports)
ns.Imports.Add(nci);
diff --git a/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs b/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs
index c5428b3..f1141db 100644
--- a/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs
+++ b/lang/csharp/src/apache/test/CodGen/CodeGenTest.cs
@@ -98,6 +98,43 @@ namespace Avro.Test
}
}
+ [TestCase(@"{
+""type"": ""fixed"",
+""namespace"": ""com.base"",
+""name"": ""MD5"",
+""size"": 16
+}", null, null, "com.base")]
+ [TestCase(@"{
+""type"": ""fixed"",
+""namespace"": ""com.base"",
+""name"": ""MD5"",
+""size"": 16
+}", "com.base", "SchemaTest", "SchemaTest")]
+ [TestCase(@"{
+""type"": ""fixed"",
+""namespace"": ""com.base"",
+""name"": ""MD5"",
+""size"": 16
+}", "miss", "SchemaTest", "com.base")]
+ public void TestCodeGenNamespaceMapping(string str, string avroNamespace, string csharpNamespace,
+ string expectedNamespace)
+ {
+ Schema schema = Schema.Parse(str);
+
+ var codegen = new CodeGen();
+ codegen.AddSchema(schema);
+
+ if (avroNamespace != null && csharpNamespace != null)
+ {
+ codegen.NamespaceMapping[avroNamespace] = csharpNamespace;
+ }
+
+ var results = GenerateAssembly(codegen);
+ foreach(var type in results.CompiledAssembly.GetTypes())
+ {
+ Assert.AreEqual(expectedNamespace, type.Namespace);
+ }
+ }
private static CompilerResults GenerateSchema(Schema schema)
{