diff --git a/YangParser/SemanticModel/Action.cs b/YangParser/SemanticModel/Action.cs
index 13e2a5e..397fab2 100644
--- a/YangParser/SemanticModel/Action.cs
+++ b/YangParser/SemanticModel/Action.cs
@@ -5,7 +5,7 @@
namespace YangParser.SemanticModel;
-public class Action : Statement
+public class Action : Statement, IXMLValue
{
public Action(YangStatement statement) : base(statement)
{
@@ -35,29 +35,58 @@ public Action(YangStatement statement) : base(statement)
public override string ToCode()
{
+ //TODO: REWORK
StringBuilder builder = new();
builder.AppendLine(DescriptionString);
builder.AppendLine(AttributeString);
- var returnType = Outgoing is null ? "void" : MakeName(Argument) + "Output";
+ var outputType = MakeName(Argument) + "Output";
+ var returnType = Outgoing is null ? "Task" : "Task<" + outputType + ">";
var inputType = Ingoing is null ? string.Empty : ", " + MakeName(Argument) + "Input input";
builder.AppendLine(
- $"public static {returnType} {MakeName(Argument)}(IChannel channel, int messageID{inputType})");
- builder.AppendLine("{");
- var ns = Parent is Module module ? $"xmlns:{module.XmlNamespace?.Prefix}=\\\"" + module.XmlNamespace?.Namespace + "\\\"" : string.Empty;
- builder.AppendLine(inputType != string.Empty
- ? $$"""
- var xml = $"<{{Argument}} {{ns}}>{input.ToXML()}{{Argument}}>";
- """
- : $$"""
- var xml = $"<{{Argument}} {{ns}}/>";
- """);
-
- builder.AppendLine(returnType != "void"
+ $"public async {returnType} {MakeName(Argument)}(IChannel channel, int messageID{inputType})");
+ builder.AppendLine("""
+ {
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ settings.OmitXmlDeclaration = true;
+ settings.NewLineOnAttributes = true;
+ StringBuilder stringBuilder = new StringBuilder();
+ using XmlWriter writer = XmlWriter.Create(stringBuilder, settings);
+ await writer.WriteStartElementAsync(null,"rpc","urn:ietf:params:xml:ns:netconf:base:1.0");
+ await writer.WriteAttributeStringAsync(null,"message-id",null,messageID.ToString());
+ await writer.WriteStartElementAsync(null,"action","urn:ietf:params:xml:ns:yang:1");
+ """);
+ if (Ingoing is not null)
+ {
+ builder.AppendLine($"\tthis.{MakeName(Argument)}InputValue = input;");
+ }
+ else
+ {
+ builder.AppendLine($"\tthis.{MakeName(Argument)}Active = true;");
+ }
+
+ builder.AppendLine("""
+ await WriteXML(writer);
+ await writer.WriteEndElementAsync();
+ await writer.WriteEndElementAsync();
+ var xml = stringBuilder.ToString();
+ """);
+ builder.AppendLine(returnType != "Task"
? "\tvar response = channel.Send(xml);"
: "\tchannel.Send(xml);");
- if (returnType != "void")
+ if (Ingoing is not null)
+ {
+ builder.AppendLine($"\tthis.{MakeName(Argument)}InputValue = null;");
+ }
+ else
+ {
+
+ builder.AppendLine($"\tthis.{MakeName(Argument)}Active = false;");
+ }
+
+ if (returnType != "Task")
{
- builder.AppendLine($"\treturn {returnType}.Parse(response);");
+ builder.AppendLine($"\treturn {outputType}.Parse(response);");
}
builder.AppendLine("}");
@@ -69,6 +98,11 @@ public override string ToCode()
if (Ingoing is not null)
{
builder.AppendLine(Ingoing.ToCode());
+ builder.AppendLine($"private {MakeName(Argument)}Input? {MakeName(Argument)}InputValue {{ get; set; }}");
+ }
+ else
+ {
+ builder.AppendLine($"private bool {MakeName(Argument)}Active {{ get; set; }}");
}
return builder.ToString();
@@ -88,4 +122,32 @@ protected override void ValidateParent()
parent = parent.Parent;
}
}
+
+ public string TargetName => MakeName(Argument);
+
+ public string WriteCall
+ {
+ get
+ {
+ if (Ingoing is not null)
+ {
+ return $$"""
+ if({{MakeName(Argument)}}InputValue is not null)
+ {
+ await writer.WriteStartElementAsync(null,"{{Source.Argument}}",null);
+ await {{MakeName(Argument)}}InputValue.WriteXML(writer);
+ await writer.WriteEndElementAsync();
+ }
+ """;
+ }
+
+ return $$"""
+ if({{MakeName(Argument)}}Active)
+ {
+ await writer.WriteStartElementAsync(null,"{Source.Argument}",null);
+ await writer.WriteEndElementAsync();
+ }
+ """;
+ }
+ }
}
\ No newline at end of file
diff --git a/YangParser/SemanticModel/AnyData.cs b/YangParser/SemanticModel/AnyData.cs
index ecd10fc..6238e76 100644
--- a/YangParser/SemanticModel/AnyData.cs
+++ b/YangParser/SemanticModel/AnyData.cs
@@ -2,7 +2,7 @@
namespace YangParser.SemanticModel;
-public class AnyData : Statement
+public class AnyData : Statement, IXMLValue
{
public AnyData(YangStatement statement) : base(statement)
{
@@ -26,6 +26,24 @@ public AnyData(YangStatement statement) : base(statement)
public override string ToCode()
{
- return "public string? Data { get; }";
+ return $"public string? {TargetName} {{ get; set; }}";
+ }
+
+ public string TargetName => MakeName(Argument);
+
+ public string WriteCall
+ {
+ get
+ {
+ var pre = string.IsNullOrWhiteSpace(Prefix) ? "null" : $"\"{Prefix}\"";
+ return $$"""
+ if({{TargetName}} != null)
+ {
+ await writer.WriteStartElementAsync({{pre}},"{{Argument}}",null);
+ await writer.WriteStringAsync({{TargetName}});
+ await writer.WriteEndElementAsync();
+ }
+ """;
+ }
}
}
\ No newline at end of file
diff --git a/YangParser/SemanticModel/AnyXml.cs b/YangParser/SemanticModel/AnyXml.cs
index de41c16..a072b41 100644
--- a/YangParser/SemanticModel/AnyXml.cs
+++ b/YangParser/SemanticModel/AnyXml.cs
@@ -28,6 +28,24 @@ public AnyXml(YangStatement statement) : base(statement)
public override string ToCode()
{
- return "public string? XML { get; }";
+ return $"public string? {TargetName} {{ get; set; }}";
+ }
+
+ public string TargetName => MakeName(Argument);
+
+ public string WriteCall
+ {
+ get
+ {
+ var pre = string.IsNullOrWhiteSpace(Prefix) ? "null" : $"\"{Prefix}\"";
+ return $$"""
+ if({{TargetName}} != null)
+ {
+ await writer.WriteStartElementAsync({{pre}},"{{Argument}}",null);
+ await writer.WriteStringAsync({{TargetName}});
+ await writer.WriteEndElementAsync();
+ }
+ """;
+ }
}
}
\ No newline at end of file
diff --git a/YangParser/SemanticModel/Builtins/IdentityReference.cs b/YangParser/SemanticModel/Builtins/IdentityReference.cs
index 4a42c74..751a9b3 100644
--- a/YangParser/SemanticModel/Builtins/IdentityReference.cs
+++ b/YangParser/SemanticModel/Builtins/IdentityReference.cs
@@ -8,15 +8,16 @@ public class IdentityReference() : BuiltinType("identityref", statement =>
var inherits = statement.Children.OfType().Select(x => '"' + x.Argument + '"').ToArray();
var name = BuiltinTypeReference.TypeName(statement);
var definition = $$"""
- {{statement.DescriptionString}}{{statement.AttributeString}}
- 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 {{name}}(string input) => new(input);
- }
- """;
+ {{statement.DescriptionString}}{{statement.AttributeString}}
+ 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 {{name}}(string input) => new(input);
+ public override string ToString() => Identity;
+ }
+ """;
return (name, definition);
});
\ No newline at end of file
diff --git a/YangParser/SemanticModel/Case.cs b/YangParser/SemanticModel/Case.cs
index 14f3458..e2b99c8 100644
--- a/YangParser/SemanticModel/Case.cs
+++ b/YangParser/SemanticModel/Case.cs
@@ -70,7 +70,7 @@ namespace YangParser.SemanticModel;
/// | when | 7.19.5 | 0..1 |
/// +--------------+---------+-------------+
///
-public class Case : Statement, IClassSource
+public class Case : Statement, IClassSource, IXMLSource
{
public List Comments { get; } = new();
@@ -102,18 +102,20 @@ public Case(YangStatement statement) : base(statement)
public override string ToCode()
{
var nodes = Children.Select(c => c.ToCode()).ToArray();
-
return $$"""
- public {{MakeName(Parent!.Argument)}}Choice({{MakeName(Argument)}}Case input)
+ public {{MakeName(Parent!.Argument)}}Choice({{TargetName}}Case input)
{
- {{MakeName(Argument)}} = input;
+ {{TargetName}} = input;
}
- public {{MakeName(Argument)}}Case? {{MakeName(Argument)}};
+ public {{TargetName}}Case? {{TargetName}};
{{DescriptionString}}{{AttributeString}}
- public class {{MakeName(Argument)}}Case
+ public class {{TargetName}}Case
{
{{Indent(string.Join("\n", nodes))}}
+ {{Indent(XmlFunctionWithInvisibleSelf())}}
}
""";
}
+
+ public string TargetName => MakeName(Argument);
}
\ No newline at end of file
diff --git a/YangParser/SemanticModel/Choice.cs b/YangParser/SemanticModel/Choice.cs
index 4bfd710..6d7dd8c 100644
--- a/YangParser/SemanticModel/Choice.cs
+++ b/YangParser/SemanticModel/Choice.cs
@@ -5,7 +5,7 @@
namespace YangParser.SemanticModel;
-public class Choice : Statement, IClassSource
+public class Choice : Statement, IClassSource, IXMLSource
{
private readonly YangStatement m_source;
@@ -43,16 +43,17 @@ public Choice(YangStatement statement) : base(statement)
public override string ToCode()
{
var nodes = Children.Where(t => t is not DefaultValue).Select(child => child.ToCode()).ToArray();
- string property = Parent is Module
- ? string.Empty
- : $"public{KeywordString}{MakeName(Argument)}Choice? {MakeName(Argument)} {{ get; set; }}";
+ string property = $"public{KeywordString}{MakeName(Argument)}Choice? {MakeName(Argument)} {{ get; set; }}";
return $$"""
{{property}}
{{DescriptionString}}{{AttributeString}}
public class {{MakeName(Argument)}}Choice
{
{{string.Join("\n\t", nodes.Select(Indent))}}
+ {{Indent(XmlFunctionWithInvisibleSelf())}}
}
""";
}
+
+ public string TargetName => MakeName(Argument);
}
\ No newline at end of file
diff --git a/YangParser/SemanticModel/Input.cs b/YangParser/SemanticModel/Input.cs
index a65e1dc..293518d 100644
--- a/YangParser/SemanticModel/Input.cs
+++ b/YangParser/SemanticModel/Input.cs
@@ -34,10 +34,11 @@ public Input(YangStatement statement) : base(statement)
public override string ToCode()
{
return $$"""
- public class {{MakeName(Parent!.Argument)}}Input : IXMLSource
+ public class {{MakeName(Parent!.Argument)}}Input
{
{{string.Join("\n\t", Children.Select(child => Indent(child.ToCode())))}}
- public string ToXML() => string.Empty; //TODO
+ {{Indent(XmlFunction())}}
+
}
""";
}
diff --git a/YangParser/SemanticModel/List.cs b/YangParser/SemanticModel/List.cs
index 658c930..edcb634 100644
--- a/YangParser/SemanticModel/List.cs
+++ b/YangParser/SemanticModel/List.cs
@@ -53,9 +53,8 @@ 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();";
+ $"\n{DescriptionString}\npublic{KeywordString}List<{MakeName(Argument)}Entry> {TargetName} {{ get; }} = new();";
return $$"""
{{property}}
{{AttributeString}}
@@ -67,7 +66,7 @@ public class {{MakeName(Argument)}}Entry
""";
}
- public string TargetName { get; private set; }
+ public string TargetName => MakeName(Argument);
public string WriteCall
{
diff --git a/YangParser/SemanticModel/Module.cs b/YangParser/SemanticModel/Module.cs
index 7ddcd4b..f493f25 100644
--- a/YangParser/SemanticModel/Module.cs
+++ b/YangParser/SemanticModel/Module.cs
@@ -116,6 +116,7 @@ public override string ToCode()
var raw = $$"""
using System;
using System.Xml;
+ using System.Text;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
diff --git a/YangParser/SemanticModel/Rpc.cs b/YangParser/SemanticModel/Rpc.cs
index 1238671..3e9eee1 100644
--- a/YangParser/SemanticModel/Rpc.cs
+++ b/YangParser/SemanticModel/Rpc.cs
@@ -49,26 +49,41 @@ public override string ToCode()
StringBuilder builder = new();
builder.AppendLine(DescriptionString);
builder.AppendLine(AttributeString);
- var returnType = Outgoing is null ? "void" : MakeName(Argument) + "Output";
+ var outputType = MakeName(Argument) + "Output";
+ var returnType = Outgoing is null ? "Task" : "Task<" + outputType + ">";
var inputType = Ingoing is null ? string.Empty : ", " + MakeName(Argument) + "Input input";
builder.AppendLine(
- $"public static {returnType} {MakeName(Argument)}(IChannel channel, int messageID{inputType})");
- builder.AppendLine("{");
- var ns = Parent is Module module ? $"xmlns:{module.XmlNamespace?.Prefix}=\\\"" + module.XmlNamespace?.Namespace + "\\\"" : string.Empty;
- builder.AppendLine(inputType != string.Empty
- ? $$"""
- var xml = $"<{{Argument}} {{ns}}>{input.ToXML()}{{Argument}}>";
- """
- : $$"""
- var xml = $"<{{Argument}} {{ns}}/>";
- """);
+ $"public static async {returnType} {MakeName(Argument)}(IChannel channel, int messageID{inputType})");
+ builder.AppendLine($$"""
+ {
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ settings.OmitXmlDeclaration = true;
+ settings.NewLineOnAttributes = true;
+ StringBuilder stringBuilder = new StringBuilder();
+ using XmlWriter writer = XmlWriter.Create(stringBuilder, settings);
+ await writer.WriteStartElementAsync(null,"rpc","urn:ietf:params:xml:ns:netconf:base:1.0");
+ await writer.WriteAttributeStringAsync(null,"message-id",null,messageID.ToString());
+ await writer.WriteStartElementAsync("{{XmlNamespace?.Prefix}}","{{Argument}}","{{XmlNamespace?.Namespace}}");
- builder.AppendLine(returnType != "void"
+ """);
+ var ns = $"xmlns:{XmlNamespace?.Prefix}=\\\"" + XmlNamespace?.Namespace + "\\\"";
+ if (inputType != string.Empty)
+ {
+ builder.AppendLine("\tawait input.WriteXML(writer);");
+ }
+
+ builder.AppendLine($$"""
+ await writer.WriteEndElementAsync();
+ await writer.WriteEndElementAsync();
+ var xml = stringBuilder.ToString();
+ """);
+ builder.AppendLine(returnType != "Task"
? "\tvar response = channel.Send(xml);"
: "\tchannel.Send(xml);");
- if (returnType != "void")
+ if (returnType != "Task")
{
- builder.AppendLine($"\treturn {returnType}.Parse(response);");
+ builder.AppendLine($"\treturn {outputType}.Parse(response);");
}
builder.AppendLine("}");
diff --git a/YangParser/SemanticModel/Statement.cs b/YangParser/SemanticModel/Statement.cs
index 7018c68..5811207 100644
--- a/YangParser/SemanticModel/Statement.cs
+++ b/YangParser/SemanticModel/Statement.cs
@@ -31,6 +31,34 @@ public async Task WriteXML(XmlWriter writer)
""";
}
+ protected string XmlFunctionWithInvisibleSelf()
+ {
+ var ns = XmlNamespace?.Namespace;
+ ns = ns is null ? "null" : $"\"{ns}\"";
+ var pre = string.IsNullOrWhiteSpace(Prefix) ? "null" : $"\"{Prefix}\"";
+ var writeCalls = Children.OfType()
+ .Select(t => $"if({t.TargetName} is not null) await {t.TargetName}.WriteXML(writer);").ToArray();
+ var elementCalls = Children.OfType()
+ .Select(t => t.WriteCall).ToArray();
+ if (elementCalls.Length == 0 && writeCalls.Length == 0)
+ {
+ return """
+ public async Task WriteXML(XmlWriter writer)
+ {
+ await writer.FlushAsync();
+ }
+ """;
+ }
+
+ return $$"""
+ public async Task WriteXML(XmlWriter writer)
+ {
+ {{Indent(string.Join("\n", elementCalls))}}
+ {{Indent(string.Join("\n", writeCalls))}}
+ }
+ """;
+ }
+
protected Statement(YangStatement statement, bool validate = true)
{
Argument = statement.Argument?.ToString() ?? string.Empty;