-
Notifications
You must be signed in to change notification settings - Fork 1.7k
AVRO-2883: Fix namespace mapping #1610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6326ee3
1187cf8
c434957
e3c2804
ec47628
916c63f
a131791
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |
| using System.Linq; | ||
| using System.Reflection; | ||
| using System.Text; | ||
| using System.Text.RegularExpressions; | ||
| using Microsoft.CSharp; | ||
|
|
||
| namespace Avro | ||
|
|
@@ -63,6 +64,7 @@ public class CodeGen | |
| /// <value> | ||
| /// The namespace mapping. | ||
| /// </value> | ||
| [Obsolete("NamespaceMapping is not used, use AddProtocol(string ...) or AddSchema(string ...) instead!")] | ||
| public IDictionary<string, string> NamespaceMapping { get; private set; } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this potentially API breaking to remove this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a good call out. I reshuffled the code and added back the NamespaceMapping property and marked it obsolete. |
||
|
|
||
| /// <summary> | ||
|
|
@@ -80,7 +82,6 @@ public CodeGen() | |
| { | ||
| Schemas = new List<Schema>(); | ||
| Protocols = new List<Protocol>(); | ||
| NamespaceMapping = new Dictionary<string, string>(); | ||
| NamespaceLookup = new Dictionary<string, CodeNamespace>(StringComparer.Ordinal); | ||
| } | ||
|
|
||
|
|
@@ -103,6 +104,19 @@ public virtual void AddProtocol(Protocol protocol) | |
| Protocols.Add(protocol); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Parses and adds a protocol object to generate code for. | ||
| /// </summary> | ||
| /// <param name="protocolText">The protocol.</param> | ||
| /// <param name="namespaceMapping">namespace mapping key value pairs.</param> | ||
| public virtual void AddProtocol(string protocolText, IEnumerable<KeyValuePair<string, string>> namespaceMapping = null) | ||
| { | ||
| // Map namespaces | ||
| protocolText = ReplaceMappedNamespacesInSchema(protocolText, namespaceMapping); | ||
| Protocol protocol = Protocol.Parse(protocolText); | ||
| Protocols.Add(protocol); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Adds a schema object to generate code for. | ||
| /// </summary> | ||
|
|
@@ -112,6 +126,19 @@ public virtual void AddSchema(Schema schema) | |
| Schemas.Add(schema); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Parses and adds a schema object to generate code for. | ||
| /// </summary> | ||
| /// <param name="schemaText">schema object.</param> | ||
| /// <param name="namespaceMapping">namespace mapping key value pairs.</param> | ||
| public virtual void AddSchema(string schemaText, IEnumerable<KeyValuePair<string, string>> namespaceMapping = null) | ||
| { | ||
| // Map namespaces | ||
| schemaText = ReplaceMappedNamespacesInSchema(schemaText, namespaceMapping); | ||
| Schema schema = Schema.Parse(schemaText); | ||
| Schemas.Add(schema); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Adds a namespace object for the given name into the dictionary if it doesn't exist yet. | ||
| /// </summary> | ||
|
|
@@ -129,9 +156,7 @@ protected virtual CodeNamespace AddNamespace(string name) | |
|
|
||
| if (!NamespaceLookup.TryGetValue(name, out CodeNamespace ns)) | ||
| { | ||
| ns = NamespaceMapping.TryGetValue(name, out string csharpNamespace) | ||
| ? new CodeNamespace(csharpNamespace) | ||
| : new CodeNamespace(CodeGenUtil.Instance.Mangle(name)); | ||
| ns = new CodeNamespace(CodeGenUtil.Instance.Mangle(name)); | ||
|
|
||
| foreach (CodeNamespaceImport nci in CodeGenUtil.Instance.NamespaceImports) | ||
| { | ||
|
|
@@ -1153,5 +1178,48 @@ public virtual void WriteTypes(string outputdir) | |
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Replace namespace(s) in schema or protocol definition. | ||
| /// </summary> | ||
| /// <param name="input">input schema or protocol definition.</param> | ||
| /// <param name="namespaceMapping">namespace mappings object.</param> | ||
| private static string ReplaceMappedNamespacesInSchema(string input, IEnumerable<KeyValuePair<string, string>> namespaceMapping) | ||
| { | ||
| if (namespaceMapping == null || input == null) | ||
| return input; | ||
|
|
||
| // Replace namespace in "namespace" definitions: | ||
| // "namespace": "originalnamespace" -> "namespace": "mappednamespace" | ||
| // "namespace": "originalnamespace.whatever" -> "namespace": "mappednamespace.whatever" | ||
| // Note: It keeps the original whitespaces | ||
| return Regex.Replace(input, @"""namespace""(\s*):(\s*)""([^""]*)""", m => | ||
| { | ||
| // m.Groups[1]: whitespaces before ':' | ||
| // m.Groups[2]: whitespaces after ':' | ||
| // m.Groups[3]: the namespace | ||
|
|
||
| string ns = m.Groups[3].Value; | ||
|
|
||
| foreach (var mapping in namespaceMapping) | ||
| { | ||
| // Full match | ||
| if (mapping.Key == ns) | ||
| { | ||
| ns = mapping.Value; | ||
| break; | ||
| } | ||
| else | ||
| // Partial match | ||
| if (ns.StartsWith($"{mapping.Key}.")) | ||
| { | ||
| ns = $"{mapping.Value}.{ns.Substring(mapping.Key.Length + 1)}"; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return $@"""namespace""{m.Groups[1].Value}:{m.Groups[2].Value}""{ns}"""; | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,7 +63,7 @@ public void TestReservedKeywords() | |
| [TestCase("a.b.int", "a.b.@int")] | ||
| [TestCase("int.long.while", "@int.@long.@while")] // Reserved keywords | ||
| [TestCase("a.value.partial", "a.value.partial")] // Contextual keywords | ||
| [TestCase("a.value.b.int.c.while.longpartial", "[email protected][email protected]")] // Rseserved and contextual keywords | ||
| [TestCase("a.value.b.int.c.while.longpartial", "[email protected][email protected]")] // Reserved and contextual keywords | ||
| public void TestMangleUnMangle(string input, string mangled) | ||
| { | ||
| // Mangle | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not C# developer but this change does not look related to the issue with the namespaces by avrogen.
Please explain.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It is not related. I just got a watning that those packages are not used. All the reflection related code is in the main library. I guess there used to be code in avrogen which used relection, however it is not present. I can move it to a seperate ticket easily if needed. I considered this change just like removing unused
using WhateverPackage;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw when I do sneaky stuff like this, usually create a specific commit for it and explain somewaht in the commit mnessage. 6326ee3