From cf995373690dee2ef50c9de308670fa46473af2b Mon Sep 17 00:00:00 2001 From: caran Date: Thu, 30 May 2024 13:27:44 +0200 Subject: [PATCH] More XML --- YangParser/SemanticModel/Builtins/Binary.cs | 39 ++++++++++++++++++- YangParser/SemanticModel/Builtins/Bits.cs | 14 +++++++ .../Builtins/BuiltinTypeReference.cs | 2 +- .../SemanticModel/Builtins/Enumeration.cs | 16 ++++++++ .../Builtins/IdentityReference.cs | 2 +- YangParser/SemanticModel/Builtins/Union.cs | 2 +- YangParser/SemanticModel/Container.cs | 2 +- YangParser/SemanticModel/Leaf.cs | 20 ++++++++-- YangParser/SemanticModel/LeafList.cs | 2 +- YangParser/SemanticModel/List.cs | 23 ++++++++++- YangParser/SemanticModel/Module.cs | 8 +++- 11 files changed, 118 insertions(+), 12 deletions(-) diff --git a/YangParser/SemanticModel/Builtins/Binary.cs b/YangParser/SemanticModel/Builtins/Binary.cs index f261d11..49271bb 100644 --- a/YangParser/SemanticModel/Builtins/Binary.cs +++ b/YangParser/SemanticModel/Builtins/Binary.cs @@ -1,3 +1,40 @@ +using System.Collections.Generic; + namespace YangParser.SemanticModel.Builtins; -public class Binary() : BuiltinType("binary", _ => ("byte[]", null)); \ No newline at end of file +public class Binary() : BuiltinType("binary", statement => +{ + var hasLength = statement.TryGetChild(out var length); + List staticFields = new(); + var typeName = BuiltinTypeReference.TypeName(statement); + List constructorStatements = new(); + if (hasLength) + { + constructorStatements.Add(length!.GetConstructorValidation()); + } + + return (typeName, $$""" + {{statement.DescriptionString}}{{statement.AttributeString}} + public class {{typeName}} + { + {{Statement.Indent(string.Join("\n", staticFields))}} + public byte[] WrittenValue { get; } + public static implicit operator byte[]?({{typeName}}? input) => input?.WrittenValue; + public static implicit operator {{typeName}}(byte[] input) => new {{typeName}}(input); + public {{typeName}}(byte[] input) + { + {{Statement.Indent(Statement.Indent(string.Join("\n", constructorStatements)))}} + WrittenValue = input; + } + public override string ToString() + { + return Convert.ToBase64String(WrittenValue); + } + public {{typeName}} Parse(string base64) + { + return new {{typeName}}(Convert.FromBase64String(base64)); + } + + } + """); +}); \ No newline at end of file diff --git a/YangParser/SemanticModel/Builtins/Bits.cs b/YangParser/SemanticModel/Builtins/Bits.cs index 3e037f5..a1c2fff 100644 --- a/YangParser/SemanticModel/Builtins/Bits.cs +++ b/YangParser/SemanticModel/Builtins/Bits.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; namespace YangParser.SemanticModel.Builtins; @@ -12,7 +13,20 @@ public class Bits() : BuiltinType("bits", statement => child.ToCode(); } + var cases = new List(); + foreach (var e in bits) + { + cases.Add($"if ((value & {name}.{Statement.MakeName(e.Argument)}) == {name}.{Statement.MakeName(e.Argument)}) bits.Add(\"{e.Argument}\");"); + } + var definition = $$""" + public static string GetEncodedValue({{name}} value) + { + List bits = new List(); + {{Statement.Indent(string.Join("\n", cases))}} + return string.Join(" ", bits); + } + public static string GetEncodedValue({{name}}? value) => GetEncodedValue(value!.Value!); {{statement.DescriptionString}}{{statement.AttributeString}} public enum {{name}} { diff --git a/YangParser/SemanticModel/Builtins/BuiltinTypeReference.cs b/YangParser/SemanticModel/Builtins/BuiltinTypeReference.cs index 3c86493..9692576 100644 --- a/YangParser/SemanticModel/Builtins/BuiltinTypeReference.cs +++ b/YangParser/SemanticModel/Builtins/BuiltinTypeReference.cs @@ -68,7 +68,7 @@ public class {{typeName}} } public override string ToString() { - return WrittenValue.ToString(); + return WrittenValue.ToString()!; } } """; diff --git a/YangParser/SemanticModel/Builtins/Enumeration.cs b/YangParser/SemanticModel/Builtins/Enumeration.cs index 6c50c9c..896c11f 100644 --- a/YangParser/SemanticModel/Builtins/Enumeration.cs +++ b/YangParser/SemanticModel/Builtins/Enumeration.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; namespace YangParser.SemanticModel.Builtins; @@ -13,7 +14,22 @@ public class Enumeration() : BuiltinType("enumeration", (statement) => child.ToCode(); } + var cases = new List(); + foreach (var e in enums) + { + cases.Add($"case {name}.{Statement.MakeName(e.Argument)}: return \"{e.Argument}\";"); + } + var definition = $$""" + public static string GetEncodedValue({{name}} value) + { + switch(value) + { + {{Statement.Indent(Statement.Indent(string.Join("\n", cases)))}} + default: return value.ToString(); + } + } + public static string GetEncodedValue({{name}}? value) => GetEncodedValue(value!.Value!); {{statement.DescriptionString}}{{statement.AttributeString}} public enum {{name}} { diff --git a/YangParser/SemanticModel/Builtins/IdentityReference.cs b/YangParser/SemanticModel/Builtins/IdentityReference.cs index 6b5559e..4a42c74 100644 --- a/YangParser/SemanticModel/Builtins/IdentityReference.cs +++ b/YangParser/SemanticModel/Builtins/IdentityReference.cs @@ -14,7 +14,7 @@ public class {{name}} public string Identity { get; } public static string[] Bases = [{{string.Join(", ", inherits)}}]; public {{name}}(string input) => Identity = input; - public static implicit operator string({{name}} input) => input.Identity; + public static implicit operator string?({{name}}? input) => input?.Identity; public static implicit operator {{name}}(string input) => new(input); } """; diff --git a/YangParser/SemanticModel/Builtins/Union.cs b/YangParser/SemanticModel/Builtins/Union.cs index 32cc083..f1640d7 100644 --- a/YangParser/SemanticModel/Builtins/Union.cs +++ b/YangParser/SemanticModel/Builtins/Union.cs @@ -29,7 +29,7 @@ public class {{name}} { {{Statement.Indent(string.Join("\n", types.Select(typeName => $"public {name}({typeName} input){{ {varName(typeName)} = input; }}")))}} {{Statement.Indent(string.Join("\n", types.Select(typeName => $"public {typeName}? {varName(typeName)} {{ get; }}")))}} - {{Statement.Indent(string.Join("\n", types.Select(typeName => $"public static implicit operator {typeName}({name} input) => input.{varName(typeName)} ?? throw new InvalidOperationException(\"Union was not of effective type '{typeName}'\");")))}} + {{Statement.Indent(string.Join("\n", types.Select(typeName => $"public static implicit operator {typeName}?({name}? input) => input is null ? null : input.{varName(typeName)} ?? throw new InvalidOperationException(\"Union was not of effective type '{typeName}'\");")))}} {{Statement.Indent(string.Join("\n", types.Select(typeName => $"public static implicit operator {name}({typeName} input) => new {name}(input);")))}} {{Statement.Indent(string.Join("\n", declarations))}} } diff --git a/YangParser/SemanticModel/Container.cs b/YangParser/SemanticModel/Container.cs index 1d27982..435e242 100644 --- a/YangParser/SemanticModel/Container.cs +++ b/YangParser/SemanticModel/Container.cs @@ -76,5 +76,5 @@ public class {{MakeName(name)}}Container """; } - public string TargetName { get; private set; } + public string TargetName { get; private set; } = string.Empty; } \ No newline at end of file diff --git a/YangParser/SemanticModel/Leaf.cs b/YangParser/SemanticModel/Leaf.cs index 327e88b..3dd3f20 100644 --- a/YangParser/SemanticModel/Leaf.cs +++ b/YangParser/SemanticModel/Leaf.cs @@ -76,19 +76,31 @@ public override string ToCode() """; } - public string TargetName { get; private set; } + public string TargetName { get; private set; } = string.Empty; public string WriteCall { get { var pre = string.IsNullOrWhiteSpace(Prefix) ? "null" : $"\"{Prefix}\""; + if (Type.Argument is "enumeration" or "bits") + { + return $$""" + if({{TargetName}} != default) + { + await writer.WriteStartElementAsync({{pre}},"{{Argument}}",null); + await writer.WriteStringAsync(GetEncodedValue({{TargetName}}!)); + await writer.WriteEndElementAsync(); + } + """; + } + return $$""" if({{TargetName}} != default) { - await writer.WriteStartElementAsync({{pre}},"{{Argument}}",null); - await writer.WriteStringAsync({{TargetName}}!.ToString()); - await writer.WriteEndElementAsync(); + await writer.WriteStartElementAsync({{pre}},"{{Argument}}",null); + await writer.WriteStringAsync({{TargetName}}!.ToString()); + await writer.WriteEndElementAsync(); } """; } diff --git a/YangParser/SemanticModel/LeafList.cs b/YangParser/SemanticModel/LeafList.cs index 735de3c..6805cd4 100644 --- a/YangParser/SemanticModel/LeafList.cs +++ b/YangParser/SemanticModel/LeafList.cs @@ -68,7 +68,7 @@ public override string ToCode() """; } - public string TargetName { get; private set; } + public string TargetName { get; private set; } = string.Empty; public string WriteCall { diff --git a/YangParser/SemanticModel/List.cs b/YangParser/SemanticModel/List.cs index d962e66..658c930 100644 --- a/YangParser/SemanticModel/List.cs +++ b/YangParser/SemanticModel/List.cs @@ -6,7 +6,7 @@ namespace YangParser.SemanticModel; -public class List : Statement, IClassSource +public class List : Statement, IClassSource, IXMLValue { private YangStatement m_source; @@ -53,6 +53,7 @@ public List(YangStatement statement) : base(statement) public override string ToCode() { var nodes = Children.Select(child => child.ToCode()).ToArray(); + TargetName = MakeName(Argument); string property = $"\n{DescriptionString}\npublic{KeywordString}List<{MakeName(Argument)}Entry> {MakeName(Argument)} {{ get; }} = new();"; return $$""" @@ -61,7 +62,27 @@ public override string ToCode() public class {{MakeName(Argument)}}Entry { {{string.Join("\n\t", nodes.Select(Indent))}} + {{Indent(XmlFunction())}} } """; } + + public string TargetName { get; private set; } + + public string WriteCall + { + get + { + var pre = string.IsNullOrWhiteSpace(Prefix) ? "null" : $"\"{Prefix}\""; + return $$""" + if({{TargetName}} != null) + { + foreach(var element in {{TargetName}}) + { + await element!.WriteXML(writer); + } + } + """; + } + } } \ No newline at end of file diff --git a/YangParser/SemanticModel/Module.cs b/YangParser/SemanticModel/Module.cs index a08f409..7ddcd4b 100644 --- a/YangParser/SemanticModel/Module.cs +++ b/YangParser/SemanticModel/Module.cs @@ -60,9 +60,16 @@ public Module(YangStatement statement) : base(statement) { Extensions.Add(extension); } + + if (child is Feature feature) + { + Features.Add(feature); + } } } + public List Features { get; } = []; + public Dictionary ImportedModules { get; } = []; public Dictionary Usings { get; } public string Namespace { get; private set; } @@ -119,7 +126,6 @@ namespace {{ns}}; {{DescriptionString}}{{AttributeString}} public class YangNode { - {{string.Join("\n\t", Usings.Select(p => $"//Importing {p.Value} as {p.Key}"))}} {{string.Join("\n\t", nodes)}} {{string.Join("\n\t", extraDefinitions)}} }